How a descriptor is checked
A descriptor is only useful if it is right: a wrong label or a wrong decimal shows a person something false at the moment they decide. Three checks catch most mistakes before a reviewer ever sees the file.
1. The linter
Section titled “1. The linter”python-erc7730, the linter the registry runs, checks a descriptor against the ERC-7730 schema and against the contract’s verified ABI on Sourcify: every displayed path must exist in the function it describes. It also warns about strings that a hardware wallet’s screen would cut short.
The registry pins the linter’s version in its .github/requirements.txt and needs Python 3.12; the pinned package does not install on 3.13 or later. From a clone of the registry:
python3.12 -m venv .venvsource .venv/bin/activatepip install -r .github/requirements.txterc7730 lint registry/<project>/calldata-<ContractName>.jsonOr, with uv:
uvx --python 3.12 --from "$(cat .github/requirements.txt)" erc7730 lint registry/<project>/calldata-<ContractName>.jsonFix every error. A warning such as Missing display format means a function has no entry yet, which is fine only if users never sign it.
2. Tests from real transactions
Section titled “2. Tests from real transactions”Each descriptor gets a test file, testsv2/calldata-<ContractName>.tests.json, with at least one test for every function in display.formats. A test has three parts:
rawTx: the full serialized unsigned transaction, not only its calldata. Real transactions make the best tests.dataProvider: the token metadata, and optionally address and ENS names, that the display needs, so the test runs without a network.expected: what a wallet should show.
The registry’s CI renders every test with clear-signing implementations and compares the result with expected.
3. The display on a device
Section titled “3. The display on a device”The linter and the tests check the data. A person checks the screen: Ledger’s ERC-7730 tester loads a descriptor onto a device or the Speculos emulator, so you can step through each call with representative values and read what a signer would read.
How we check the descriptors we write
Section titled “How we check the descriptors we write”-
The registry’s pinned linter, with no errors.
-
A test for every function, built from a real transaction on the chain the contract is deployed to.
-
The display read through, call by call, in a tester.
-
Each change shown to you before it goes to the registry.
Next: The registry and attestations.
Sources
Section titled “Sources”Checked on 30 October 2026: ethereum.org’s Clear Signing guide and Ledger’s Validate & Submit page.