ERC-7730 clear-signing descriptors: load a descriptor, bind it to a signing request, and render human-readable display fields.
ERC-7730 standardizes a JSON descriptor that binds calldata, EIP-712 typed messages, and ERC-4337 UserOperations to display rules, so a wallet can show what a transaction does instead of opaque hex. This module is the entry point over three internal pieces:
Onchain.ERC7730.Descriptor— parse + structurally validate the JSON.Onchain.ERC7730.Binding— resolve which display format applies and decode the bound data (chain id + address + selector, or EIP-712 domain + type).Onchain.ERC7730.Formatter— apply per-field format rules.
Usage
{:ok, descriptor} = Onchain.ERC7730.load(json_string)
{:ok, fields} =
Onchain.ERC7730.format(
descriptor,
{:calldata, token_address, 1, calldata_hex},
tokens: %{"0x...usdc" => %{decimals: 6, symbol: "USDC"}}
)
# fields => [%{label: "To", value: "0x...", formatted_value: "0x...", raw: <<...>>}, ...]Scope (Task 74, first pass)
- In: caller-provided descriptors; contract/calldata, EIP-712, and
UserOp binding; the common formatters (
raw,amount,tokenAmount,addressName,date,duration,unit,enum). - Out: fetching curated descriptors from the Ledger registry / IPFS / CDN;
includes/ external$refresolution; on-chain proxy/addressMatcherresolution;calldata(embedded sub-call) andnftNameformatters (they fall back to raw rendering).
Token decimals/symbol for tokenAmount resolve from opts[:tokens], the
descriptor's metadata.token, or a live opts[:rpc_url] lookup — see
Onchain.ERC7730.Formatter.
API Functions
| Function | Arity | Description | Param Kinds |
|---|---|---|---|
format! | 3 | Bind a descriptor to a signing request and render its display fields. Raises on error. | descriptor: value, request: exchange_data, opts: value |
format | 3 | Bind a descriptor to a signing request and render its display fields. | descriptor: value, request: exchange_data, opts: value |
load | 1 | Load and validate an ERC-7730 descriptor from a JSON string, file path, or decoded map. | source: exchange_data |
Summary
Functions
Bind a descriptor to a signing request and render its display fields.
Bind a descriptor to a signing request and render its display fields. Raises on error.
Load and validate an ERC-7730 descriptor from a JSON string, file path, or decoded map.
Functions
@spec format( Onchain.ERC7730.Descriptor.t(), Onchain.ERC7730.Binding.request(), keyword() ) :: {:ok, [Onchain.ERC7730.Formatter.result()]} | {:error, {atom(), term()}}
Bind a descriptor to a signing request and render its display fields.
Parameters
descriptor- Parsed %Onchain.ERC7730.Descriptor{} from load/1 (value)request- {:calldata, address, chain_id, hex_data} | {:eip712, payload} | {:user_op, address, chain_id, user_op} (exchange_data)opts- Rendering opts: :tokens, :rpc_url, :native_symbol, :native_decimals, :names, :value, :from (default:[], value)
Returns
Ordered list of rendered visible fields, or a binding/format error tuple ({:ok, [%{label, value, formatted_value, raw}]} | {:error, {tag, reason}})
# descripex:contract
%{
params: %{
request: %{
description: "{:calldata, address, chain_id, hex_data} | {:eip712, payload} | {:user_op, address, chain_id, user_op}",
kind: :exchange_data
},
opts: %{
default: [],
description: "Rendering opts: :tokens, :rpc_url, :native_symbol, :native_decimals, :names, :value, :from",
kind: :value
},
descriptor: %{
description: "Parsed %Onchain.ERC7730.Descriptor{} from load/1",
kind: :value
}
},
returns: %{
type: "{:ok, [%{label, value, formatted_value, raw}]} | {:error, {tag, reason}}",
description: "Ordered list of rendered visible fields, or a binding/format error tuple"
}
}
@spec format!( Onchain.ERC7730.Descriptor.t(), Onchain.ERC7730.Binding.request(), keyword() ) :: [ Onchain.ERC7730.Formatter.result() ]
Bind a descriptor to a signing request and render its display fields. Raises on error.
Parameters
descriptor- Parsed %Onchain.ERC7730.Descriptor{} from load/1 (value)request- Same request shapes as format/2 (exchange_data)opts- Same rendering opts as format/2 (default:[], value)
Returns
Ordered list of rendered visible fields ([%{label, value, formatted_value, raw}])
# descripex:contract
%{
params: %{
request: %{
description: "Same request shapes as format/2",
kind: :exchange_data
},
opts: %{
default: [],
description: "Same rendering opts as format/2",
kind: :value
},
descriptor: %{
description: "Parsed %Onchain.ERC7730.Descriptor{} from load/1",
kind: :value
}
},
returns: %{
type: "[%{label, value, formatted_value, raw}]",
description: "Ordered list of rendered visible fields"
}
}
@spec load(String.t() | map()) :: {:ok, Onchain.ERC7730.Descriptor.t()} | {:error, {atom(), term()}}
Load and validate an ERC-7730 descriptor from a JSON string, file path, or decoded map.
Parameters
source- A JSON string, a filesystem path to a .json descriptor, or an already-decoded JSON map (exchange_data)
Returns
Parsed descriptor, or an error: {:invalidjson, }, {:file_error, posix}, or a structural tag from Descriptor.parse/1 ({:ok, Descriptor.t()} | {:error, {tag, reason}})
# descripex:contract
%{
params: %{
source: %{
description: "A JSON string, a filesystem path to a .json descriptor, or an already-decoded JSON map",
kind: :exchange_data
}
},
returns: %{
type: "{:ok, Descriptor.t()} | {:error, {tag, reason}}",
description: "Parsed descriptor, or an error: {:invalid_json, _}, {:file_error, posix}, or a structural tag from Descriptor.parse/1"
}
}