Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 82 additions & 81 deletions ERCS/erc-7730.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ References to values in the container (here an EVM Tx container)

#### Value Interpolation

The `interpolatedIntent` field supports embedding formatted field values directly within intent strings using interpolation syntax. This allows constructing dynamic, context-aware descriptions of transactions and messages.
The `interpolatedIntent` field supports embedding formatted field values directly within intent strings using interpolation syntax. This allows constructing dynamic, context-aware descriptions of transactions and messages as an alternative to using individual `intent` and `fields`.

The `interpolatedIntent` makes transaction intents significantly shorter and easier to read by presenting all relevant information in a single, natural language sentence rather than as separate labeled fields. This is particularly valuable for:
- Reducing the cognitive load on users reviewing transactions
Expand All @@ -219,6 +219,8 @@ Values are interpolated using curly braces containing a path reference: `{path}`
- Container values (e.g., `{@.value}`, `{@.from}`)
- Metadata constants (e.g., `{$.metadata.constants.nativeAssetAddress}`)

Interpolated intents MUST only refer to paths that are noted as `required`.

**Formatting Behavior**

When a wallet processes an `interpolatedIntent`:
Expand All @@ -242,7 +244,8 @@ To include literal curly braces in the intent text, escape them by doubling: `{{
"fields": [
{"path": "_to", "format": "addressName"},
{"path": "_value", "format": "tokenAmount", "params": {"tokenPath": "@.to"}}
]
],
"required": [ "_to", "_value" ]
}
```
Displays as: **"Send 100 USDT to cyberdrk.eth"**
Expand All @@ -255,7 +258,8 @@ Displays as: **"Send 100 USDT to cyberdrk.eth"**
"fields": [
{"path": "amountIn", "format": "tokenAmount", "params": {"tokenPath": "tokenIn"}},
{"path": "amountOutMinimum", "format": "tokenAmount", "params": {"tokenPath": "tokenOut"}}
]
],
"required": [ "amountIn", "amountOutMinimum" ]
}
```
Displays as: **"Swap 1000 USDC for at least 0.25 WETH"**
Expand All @@ -267,7 +271,8 @@ Displays as: **"Swap 1000 USDC for at least 0.25 WETH"**
"interpolatedIntent": "Wrap {@.value} ETH for WETH",
"fields": [
{"path": "@.value", "format": "amount"}
]
],
"required": [ "@.value" ]
}
```
Displays as: **"Wrap 0.5 ETH for WETH"**
Expand All @@ -280,75 +285,6 @@ Displays as: **"Wrap 0.5 ETH for WETH"**
```
Displays as: **"Execute {function} with 100 tokens"**

**Batch Transactions (EIP-5792)**

When displaying batch transactions as defined in [EIP-5792](./eip-5792.md), wallets SHOULD concatenate the `interpolatedIntent` strings of individual operations using " and " as a separator to create a single, human-readable description of the entire batch.

This approach provides users with a clear, natural language summary of complex multi-step operations without requiring them to mentally piece together separate transaction descriptions.

*Permit + Swap example:*
```json
[
{
"function": "permit",
"interpolatedIntent": "Approve {spender} to spend {value} USDC"
},
{
"function": "swapExactTokensForTokens",
"interpolatedIntent": "Swap {amountIn} for at least {amountOutMin}"
}
]
```
Combined display: **"Approve Uniswap Router to spend 1000 USDC and Swap 1000 USDC for at least 0.25 WETH"**

*Approve + Swap example:*
```json
[
{
"function": "approve",
"interpolatedIntent": "Approve {_spender} to spend {_value}"
},
{
"function": "exactInputSingle",
"interpolatedIntent": "Swap {amountIn} for at least {amountOutMinimum}"
}
]
```
Combined display: **"Approve Uniswap V3 Router to spend 5000 DAI and Swap 5000 DAI for at least 1.2 ETH"**

*Approve + Swap + Mint NFT example:*
```json
[
{
"function": "approve",
"interpolatedIntent": "Approve {_spender} to spend {_value}"
},
{
"function": "swapExactTokensForETH",
"interpolatedIntent": "Swap {amountIn} for at least {amountOutMin} ETH"
},
{
"function": "mint",
"interpolatedIntent": "Mint {quantity} NFT(s) from {collection}"
}
]
```
Combined display: **"Approve DEX Router to spend 2000 USDC and Swap 2000 USDC for at least 0.5 ETH and Mint 2 NFT(s) from NftProject"**

**Implementation Guidance for Batch Transactions**

Wallets implementing batch transaction display SHOULD:
1. Process each transaction in the batch to generate its `interpolatedIntent`
2. Join the resulting intent strings with " and " (note the spaces)
3. Display the combined string as a single transaction summary
4. Provide a way for users to view individual transaction details if needed
5. Fall back to displaying individual `intent` fields if any `interpolatedIntent` processing fails

Wallets MAY:
- Apply additional formatting (e.g., capitalizing the first letter, adding a period at the end)
- Truncate very long combined intents and provide expansion UI
- Group related operations visually while still showing the combined intent

#### Organizing files

Smart contracts and EIP-712 messages are often re-using common interfaces or types that share similar display formatting. This specification supports a basic inclusion mechanism that enables sharing files describing specific interfaces or types.
Expand Down Expand Up @@ -830,15 +766,9 @@ This snippet defines an intent for a withdrawal function on a contract, with an

A string containing an intent description with embedded field values using [interpolation syntax](#value-interpolation).

The `interpolatedIntent` provides a more dynamic, contextual description than the static `intent` field by embedding actual transaction/message values directly in the intent string. This is particularly useful for:
- Displaying concise, single-line transaction summaries
- Improving UX on devices with limited screen space
- Reducing cognitive load by presenting values in natural language context
Wallets MUST display either `interpolatedIntent` strings or screens generated from `intent` and individual `fields`.

When both `intent` and `interpolatedIntent` are present:
- Wallets SHOULD prefer displaying `interpolatedIntent` when interpolation is successfully processed
- Wallets MUST fall back to `intent` if interpolation fails for any reason
- Wallets MAY display both fields, with `interpolatedIntent` as the primary description
Wallets MAY display both fields, with `interpolatedIntent` as the primary description.

Interpolated paths MUST reference fields that have corresponding format specifications in the `fields` array. The formatting applied during interpolation MUST match the formatting that would be applied if the field were displayed separately.

Expand Down Expand Up @@ -1370,6 +1300,77 @@ All display strings in ERC-7730 files—including intents, labels, field names,

Future versions of this specification may consider standardized internationalization support once the base standard achieves wider adoption and the ecosystem can better assess the need for multilingual support.

### Batch Transactions (EIP-5792)

When displaying batch transactions as defined in [EIP-5792](./eip-5792.md), wallets SHOULD either:
* Concatenate the `interpolatedIntent` strings of individual operations using " and " as a separator to create a single, human-readable description of the entire batch.
* Concatenate screens generated using `intent` and required `fields`, clearly separating individual transactions

The `interpolatedIntent` approach provides users with a clear, natural language summary of complex multi-step operations without requiring them to mentally piece together separate transaction descriptions. The `intent` approach provide a more controllable wallet UI for space limited wallets.

*Permit + Swap example:*
```json
[
{
"function": "permit",
"interpolatedIntent": "Approve {spender} to spend {value} USDC"
},
{
"function": "swapExactTokensForTokens",
"interpolatedIntent": "Swap {amountIn} for at least {amountOutMin}"
}
]
```
Combined display: **"Approve Uniswap Router to spend 1000 USDC and Swap 1000 USDC for at least 0.25 WETH"**

*Approve + Swap example:*
```json
[
{
"function": "approve",
"interpolatedIntent": "Approve {_spender} to spend {_value}"
},
{
"function": "exactInputSingle",
"interpolatedIntent": "Swap {amountIn} for at least {amountOutMinimum}"
}
]
```
Combined display: **"Approve Uniswap V3 Router to spend 5000 DAI and Swap 5000 DAI for at least 1.2 ETH"**

*Approve + Swap + Mint NFT example:*
```json
[
{
"function": "approve",
"interpolatedIntent": "Approve {_spender} to spend {_value}"
},
{
"function": "swapExactTokensForETH",
"interpolatedIntent": "Swap {amountIn} for at least {amountOutMin} ETH"
},
{
"function": "mint",
"interpolatedIntent": "Mint {quantity} NFT(s) from {collection}"
}
]
```
Combined display: **"Approve DEX Router to spend 2000 USDC and Swap 2000 USDC for at least 0.5 ETH and Mint 2 NFT(s) from NftProject"**

**Implementation Guidance for Batch Transactions using interpolatedIntents**

Wallets implementing batch transaction display SHOULD:
1. Process each transaction in the batch to generate its `interpolatedIntent`
2. Join the resulting intent strings with " and " (note the spaces)
3. Display the combined string as a single transaction summary
4. Provide a way for users to view individual transaction details if needed
5. Fall back to displaying individual `intent` fields if any `interpolatedIntent` processing fails

Wallets MAY:
- Apply additional formatting (e.g., capitalizing the first letter, adding a period at the end)
- Truncate very long combined intents and provide expansion UI
- Group related operations visually while still showing the combined intent

### Why is the ABI still necessary?

The full signature of a function call does not contain information about the types of complex parameters that might be used in the function call, only their names, while the ABI does carry this information. This is why the ABI is the reference and the function signature MUST match it. The full form of the function call is allowed in order to simplify writing and reading the ERC-7730 file.
Expand Down
10 changes: 5 additions & 5 deletions assets/erc-7730/erc7730-v1.schema.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"description": "ERC7730 Clear Signing Specification Schema. Specification located at https://github.com/LedgerHQ/clear-signing-erc7730-registry/tree/master/specs",

Expand Down Expand Up @@ -53,7 +53,7 @@
"$ref": "#/$context/EIP712"
}
],
"unresolvedProperties": false
"unevaluatedProperties": false
},

"contract": {
Expand Down Expand Up @@ -473,7 +473,7 @@
}
]
},
"unresolvedProperties": false
"unevaluatedProperties": false
},
"nestedFields": {
"title": "A single set of field formats, allowing recursivity in the schema",
Expand Down Expand Up @@ -625,7 +625,7 @@
}
}
],
"unresolvedProperties": false
"unevaluatedProperties": false
},
"names": {
"anyOf": [
Expand Down Expand Up @@ -1035,7 +1035,7 @@
"description": "fully qualified type name in solidity source code"
},
"components": {
"type": "array",
"type": [ "array", "null" ],
"items": {
"$ref": "#/$definitions/abi-parameter"
}
Expand Down
2 changes: 1 addition & 1 deletion assets/erc-7730/example-main.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
{
"path": "_to",
"label": "To",
"format": "addressOrName"
"format": "addressName"
},
{
"path": "_value",
Expand Down
Loading