chainId 143 and your contract address, then add it to the public registry.
What is clear signing?
ERC-7730 is a JSON format for describing how a wallet should render contract calldata and EIP-712 messages. The descriptor lives outside your contract. It maps functions, message types, and fields to labels and formatters a wallet can show before a user signs. The lookup key ischainId plus contract address, so Monad contracts do not need a Monad-specific version of the standard.
Without a descriptor, a wallet may only have raw calldata:
Why it matters for Monad
Users should not have to trust the site that assembled a transaction. A spoofed frontend can ask for one action while submitting another, and raw calldata gives most users nothing useful to inspect. Clear signing moves the important details into the wallet prompt: the action, recipient, amount, token, deadline, or any other field that matters for the call. Adding a descriptor does not require a contract change. You publish a JSON file, validate it, and submit it to the registry used by wallets that support ERC-7730.Monad mainnetchainIdis143(testnet10143). See Network Information.
Quickstart
Installuv first. The uvx command runs the erc7730 tool without a separate global install.
- Generate a starting descriptor from your ABI:
- Edit the intents and field labels so they read like English (see Editing the descriptor).
- Validate the descriptor:
- Preview how a wallet renders your fields at clear-signing.sourcify.dev.
- Open a PR to the ERC-7730 registry. CI validates it against the schema, a maintainer reviews, and once merged, supporting wallets can use it.
The Monad gotcha: embed your ABI inline
Theerc7730 linter and registry CI try to fetch a reference ABI from Etherscan’s multichain API. Monad is not served by that API, so you may see a warning like this:
context.contract.abi. The generate command above already does this, which makes the descriptor self-contained and lets the fields validate locally. Do not remove the inline abi; with it present, the warning is expected and can be ignored.
Editing the descriptor
generate gives you a skeleton with one entry per function. Most of the hand-editing is in two places:
intent: a short action label, such asApprove USDCorWrap MON. Keep it to 30 characters or fewer; some hardware wallet screens truncate longer strings.fields: the parameters you want users to review, each with alabelandformat.
format | Renders | Notes |
|---|---|---|
tokenAmount | 1,000 USDC | Applies decimals and ticker. Set a threshold with a message like Unlimited for max approvals. |
amount | Native MON with ticker | Reads the transaction value. |
addressName | A known name, otherwise a checksummed address | Use types (eoa, contract, token) and sources (local, ens). |
raw | A number, string, or address as-is | |
date | A readable date from a unix timestamp | Set encoding. |
#. for decoded calldata or message fields, $. for this descriptor’s own metadata, and @. for the transaction container, such as @.value.
Monad examples
These Monad descriptors are useful references when writing your own:- Permit2, the EIP-712 approval contract used across many dApps, at, added to the canonical Uniswap descriptor in registry PR #2611.
- The Monad staking precompile (delegate, undelegate, claim rewards) at, in registry PR #2589.
- Wrapped MON (wrap, unwrap, and ERC-20 calls) at.
How a wallet uses the descriptor
At a high level, a supporting wallet does this:- A user starts a transaction or signs an EIP-712 message.
- The wallet computes the 4-byte selector (or the EIP-712 type hash).
- It looks up the descriptor by
chainIdand address. - It checks that the descriptor’s
contextbinding matches the actual target. - It decodes the parameters with the ABI and resolves token and name metadata.
- It applies each field formatter and shows the
intentwith the formatted fields.

