Skip to content

EIP-681 — ethereum: transaction-request URIs (summary)

A condensed reference for the part of EIP-681 cuere implements in ethereum_uri and erc20_transfer_uri. It is a summary, not the spec — read the original for anything load-bearing.

Grammar

request           = "ethereum" ":" [ "pay-" ] target_address
                    [ "@" chain_id ] [ "/" function_name ] [ "?" parameters ]
target_address    = ethereum_address          ; "0x" + 40 hex digits, or an ENS name
chain_id          = 1*DIGIT                    ; EIP-155 network id, e.g. 1 = mainnet
function_name     = STRING                     ; e.g. "transfer"
parameters        = parameter *( "&" parameter )
parameter         = key "=" value
key               = "value" | "gas" | "gasLimit" | "gasPrice" | TYPE
value             = number | ethereum_address | STRING
number            = [ "-" | "+" ] *DIGIT [ "." 1*DIGIT ]
                    [ ( "e" | "E" ) [ 1*DIGIT ] [ "+" UNIT ] ]

Two shapes matter here:

  • Native payment — no function name; the value parameter is the amount of ether to send, in wei (1 ETH = 10¹⁸ wei): ethereum:0xADDR?value=….
  • Contract call — a function_name plus typed arguments. The canonical ERC-20 case is transfer(address,uint256): ethereum:0xTOKEN/transfer?address=0xRECIPIENT&uint256=AMOUNT. The argument keys are the Solidity types (address, uint256); AMOUNT is in the token's own base units (its decimals).

chain_id (when present) sits between the address and the /function path, so a chain-scoped transfer is ethereum:0xTOKEN@1/transfer?…. The optional pay- prefix marks an explicit payment; cuere omits it, emitting the bare ethereum:0x… form that wallets accept most broadly.

EIP-681's number grammar allows scientific notation with a unit suffix (e.g. value=2.014e18). cuere instead emits a plain integer number of wei, which every wallet parses unambiguously.

EIP-55 — address checksums are case-significant

An Ethereum address is 20 bytes shown as 0x + 40 hex digits. EIP-55 mixes the case of the a–f hex letters to encode a keccak-256 checksum, so 0xfb6916095ca1df60bb79Ce92ce3ea74c37c5d359 and its all-lowercase form are the same address but only the former carries the checksum. Consequences for cuere:

  • An ethereum: URI is byte-mode and case-significant: it must be stored and rendered verbatim, never upper/lower-cased.
  • optimize_uri therefore refuses the ethereum: scheme outright — uppercasing it to reach QR-alphanumeric mode (as it does for bech32 bitcoin:/lightning:; see bip-21.md) would corrupt the checksum. Never pass an ethereum: URI through optimize_uri.

What cuere does

  • ethereum_uri(address, *, value=None, chain_id=None, gas_limit=None, gas_price=None) builds the native-payment form.
  • erc20_transfer_uri(token, *, to, amount, chain_id=None, gas_limit=None, gas_price=None) builds the transfer(address,uint256) form.

Shared rules:

  • Addresses (address, token, to) are validated structurally as 0x + 40 hex digits with case preserved. This is not an EIP-55 checksum verification — that needs keccak-256, a crypto dependency cuere intentionally does not bundle (the same stance bitcoin_uri takes on base58check).
  • value, gas_price, and the ERC-20 amount are uint256 words (accept int / base-10 str / integral Decimal); they must be whole and in the full uint256 range 0 … 2²⁵⁶−10 is accepted, since it is the EVM word's natural default and EIP-681 imposes no positivity (unlike a BIP-21 amount, which must be positive). value/gas_price are in wei; amount is in the token's base units (cuere does not know a token's decimals, so it applies no scaling). gas_limit and chain_id are likewise non-negative integers. bool is rejected even though it is an int subtype.
  • Gas is emitted as the gasLimit / gasPrice keys; cuere does not emit the gas abbreviation that EIP-681 treats as a synonym for gasLimit.
  • The result is a plain str that composes with render / show.

Out of scope (candidate follow-ups): the pay- prefix, ENS-name targets, arbitrary function_name calls beyond ERC-20 transfer, the gas synonym, and scientific-notation value output.