Skip to content
Open
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
93 changes: 91 additions & 2 deletions ERCS/erc-7730.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
eip: 7730
title: Structured Data Clear Signing Format
description: JSON format describing how to clear-sign smart contract calls and typed messages.
author: Laurent Castillo (@lcastillo-ledger), Derek Rein (@arein), Pierre Aoun (@paoun-ledger), Arik Galansky (@arikg)
author: Laurent Castillo (@lcastillo-ledger), Derek Rein (@arein), Pierre Aoun (@paoun-ledger), Arik Galansky (@arikg), Bartosz Rozwarski (@llbartekll)
discussions-to: https://ethereum-magicians.org/t/eip-7730-proposal-for-a-clear-signing-standard-format-for-wallets/20403
status: Draft
type: Standards Track
Expand Down Expand Up @@ -1281,7 +1281,7 @@ Formats usable for bytes
| *Parameters* | --- |
| `calleePath` or `callee` | A path reference or a constant value specifying the address of the contract being called. |
| `selectorPath` or `selector`| Optional. If omitted, the first 4 bytes of the calldata are used as the selector. |
| `chainIdPath` or `chainId` | Optional. Specifies the chain ID if it differs from the current contracts chain. |
| `chainIdPath` or `chainId` | Optional. Specifies the chain ID if it differs from the current contract's chain. |
| `amountPath` or `amount` | Optional. Specifies the native currency amount associated with the calldata, if applicable. If provided, the ERC-7730 descriptor for this embedded calldata MAY reference this value using the `@.value` container path. |
| `spenderPath` or `spender` | Optional. Specifies the spender address associated with the calldata, if applicable. If provided, the ERC-7730 descriptor for this embedded calldata MAY reference this value using the `@.from` container path. |
| *Examples* | |
Expand Down Expand Up @@ -1340,6 +1340,95 @@ Sources values are wallet manufacturer specific. Some example values could be:

Wallets MAY extend the specification with wallet specific layout instructions by defining a schema bound to the `display.formats.screens` field.

### ERC-7730: Optional Integrity Field for Descriptor Tamper-Evidence

#### Abstract

This amendment introduces an optional top-level `integrity` object that wallets and tooling can use to detect tampering with ERC-7730 descriptors during storage or transport. The mechanism is transport-agnostic, operates offline, and does not influence descriptor interpretation.

#### Motivation

Descriptors are frequently distributed from arbitrary locations such as GitHub repositories, content delivery networks, and dapp-hosted domains, which makes byte-level tampering difficult to notice. This amendment focuses solely on byte-integrity so that consumers can surface warnings when the document payload changes; provenance, governance, and trust decisions remain outside its scope.

#### Specification

##### Scope

* The `integrity` object is optional. Absence is not an error.
* Implementations MAY validate `integrity` if present; verification outcome affects wallet and tool user experiences only and MUST NOT alter descriptor semantics.

##### Hash Input (canonicalization)

* Let D be the JSON document with the top-level `integrity` key removed.
* Canonicalize D using the RFC 8785 JSON Canonicalization Scheme (JCS) with UTF-8 encoding, lexicographic member ordering, and I-JSON constraints.
* Compute `digest = keccak256(JCS(D))`, where `keccak256` is the Ethereum Keccak-256 function (distinct from FIPS SHA3-256).

##### Signed Message (exact bytes)

Implementations MUST construct the exact ASCII (UTF-8) message with line feed newlines, no byte order mark, and no trailing spaces:

```
ERC-7730 descriptor
hash=<0x{64 lowercase hex}>
```

The following Augmented Backus-Naur form (ABNF) removes ambiguity:

```abnf
message = "ERC-7730 descriptor" LF
"hash=" "0x" 64HEXDIGIT LF

LF = %x0A
HEXDIGIT = %x30-39 / %x61-66 ; 0-9 or a-f (lowercase)
64HEXDIGIT = 64*HEXDIGIT
```

##### Signature schemes and verification rules

* `sigType: "eip191"`, `signerType: "eoa"`:
The signer MUST sign the message defined above using [EIP-191](./eip-191.md) personal signing. Verifiers MUST:
1. apply EIP-191 prefixing (`hashMessage(message)`),
2. recover an address equal to the account encoded by `integrity.signer`, and
3. enforce low-s ECDSA and normalize `v in {27,28}`.

* `signerType: "erc1271"`:
The `integrity.signer` field encodes the account as a CAIP-10 identifier (for example, `eip155:1:0x...`). Verifiers MUST:
1. parse the CAIP-10 value to obtain the chain namespace, network reference, and account,
2. compute `keccak256(message)`, and
3. call [EIP-1271](./eip-1271.md) `isValidSignature(bytes32,bytes)` on that account at the chain specified by the CAIP-10 identifier, requiring the magic value `0x1626ba7e`.
If chain access is unavailable, implementations SHOULD surface "verification unavailable" and continue according to product policy.

##### Signer identity format (CAIP-10)

The `signer` field MUST be a CAIP-10 account string (e.g., `eip155:1:0xAbc...`), uniquely binding both the chain reference and the account without requiring separate `chainId` properties.

##### `integrity` object (JSON schema fragment)

```json
"integrity": {
"sigType": "eip191",
"signerType": "eoa", // or "erc1271"
"signer": "eip155:1:0xCSA_SIGNER", // CAIP-10 account identifier
"hash": "0x<keccak256(JCS(document_without_integrity))>",
"signature": "0x<r||s||v>" // ECDSA over EIP-191 message
}
```

##### Verifier behavior

* If `integrity` is present and verification fails (hash mismatch, bad signature, or invalid 1271 response), implementations MUST surface an integrity failure. Whether to block is product policy.
* If `integrity` is present and verification cannot be performed (for example, offline EIP-1271 lookups), implementations SHOULD surface "verification unavailable."
* If `integrity` is absent, implementations MUST NOT treat this as an error.
* Implementations MUST NOT change how they interpret descriptor content based on the verification outcome.

#### Rationale

JSON canonicalization via RFC 8785 ensures stable bytes across languages and tooling, while Keccak-256 matches existing Ethereum hashing primitives. The explicit message template and ABNF eliminate newline or casing ambiguities. Separating `sigType` from `signerType` avoids assumptions about available chain connectivity and supports future combinations. Encoding the signer as CAIP-10 binds chain and account in one field, removing auxiliary identifiers. Time-based invalidation features are intentionally excluded to keep the surface minimal, and provenance or governance concerns stay intentionally out of scope.

#### Security Considerations

This mechanism only detects tampering of descriptor bytes and does not assert safety or endorsement. Implementations SHOULD reject non-I-JSON inputs (duplicate keys or non-UTF-8 encodings) before canonicalization, MUST enforce low-s ECDSA handling, and MUST ensure the Ethereum Keccak-256 function, not the FIPS SHA3-256 variant, is used throughout verification.

## Rationale

### Human readability
Expand Down
Loading