mechanisms/evm
import "github.com/x402-foundation/x402/go/v2/mechanisms/evm"
Constants
Source: mechanisms/evm/constants.go:9
const (
// Scheme identifiers
SchemeExact = "exact"
SchemeUpto = "upto"
SchemeBatched = "batch-settlement"
// Default token decimals for USDC
DefaultDecimals = 6
// EIP-3009 function names
FunctionTransferWithAuthorization = "transferWithAuthorization"
FunctionReceiveWithAuthorization = "receiveWithAuthorization"
FunctionAuthorizationState = "authorizationState"
FunctionTryAggregate = "tryAggregate"
// Permit2 function names
FunctionSettle = "settle"
FunctionSettleWithPermit = "settleWithPermit"
// Transaction status
TxStatusSuccess = 1
TxStatusFailed = 0
// Default validity period (1 hour)
DefaultValidityPeriod = 3600 // seconds
// ERC-6492 magic value (last 32 bytes of wrapped signature)
// This is bytes32(uint256(keccak256("erc6492.invalid.signature")) - 1)
ERC6492MagicValue = "0x6492649264926492649264926492649264926492649264926492649264926492"
// EIP-1271 magic value (returned by isValidSignature on success)
EIP1271MagicValue = "0x1626ba7e"
// Shared error constants (used by verify_universal.go and other shared utilities)
ErrUndeployedSmartWallet = "invalid_exact_evm_payload_undeployed_smart_wallet"
// Permit2 constants
// PERMIT2Address is the canonical Uniswap Permit2 contract address.
// Same address on all EVM chains via CREATE2 deployment.
PERMIT2Address = "0x000000000022D473030F116dDEE9F6B43aC78BA3"
// MULTICALL3Address is the canonical Multicall3 deployment address.
// Same address on all EVM chains via CREATE2 deployment.
MULTICALL3Address = "0xcA11bde05977b3631167028862bE2a173976CA11"
// X402ExactPermit2ProxyAddress is the x402 exact payment proxy.
// Vanity address: 0x4020...0001 for easy recognition.
X402ExactPermit2ProxyAddress = "0x402085c248EeA27D92E8b30b2C58ed07f9E20001"
// X402UptoPermit2ProxyAddress is the x402 upto payment proxy.
// Vanity address: 0x4020...0002 for easy recognition.
X402UptoPermit2ProxyAddress = "0x4020A4f3b7b90ccA423B9fabCc0CE57C6C240002"
// Permit2DeadlineBuffer is the time buffer (in seconds) added when checking
// deadline expiration to account for block propagation time.
Permit2DeadlineBuffer = 6
// ERC20ApproveGasLimit is the gas limit for a standard ERC-20 approve() transaction.
ERC20ApproveGasLimit = 70000
// DefaultMaxFeePerGas is the fallback max fee per gas (1 gwei) for gas cost estimation.
DefaultMaxFeePerGas = 1_000_000_000
)Shared Permit2 error constants used by both the exact and upto facilitators. Both schemes write these strings to JSON responses and facilitate cross-SDK parity, so the values must never change without a coordinated update across all SDKs.
Source: mechanisms/evm/permit2_errors.go:16
const (
// Verification errors
ErrPermit2InvalidSpender = "invalid_permit2_spender"
ErrPermit2RecipientMismatch = "invalid_permit2_recipient_mismatch"
ErrPermit2DeadlineExpired = "permit2_deadline_expired"
ErrPermit2NotYetValid = "permit2_not_yet_valid"
ErrPermit2AmountMismatch = "permit2_amount_mismatch"
ErrPermit2TokenMismatch = "permit2_token_mismatch"
ErrPermit2InvalidSignature = "invalid_permit2_signature"
ErrPermit2AllowanceRequired = "permit2_allowance_required"
// Settle errors (from contract reverts)
ErrPermit2InvalidAmount = "permit2_invalid_amount"
ErrPermit2InvalidDestination = "permit2_invalid_destination"
ErrPermit2InvalidOwner = "permit2_invalid_owner"
ErrPermit2PaymentTooEarly = "permit2_payment_too_early"
ErrPermit2InvalidNonce = "permit2_invalid_nonce"
ErrPermit2612AmountMismatch = "permit2_2612_amount_mismatch"
// Simulation errors
ErrPermit2SimulationFailed = "permit2_simulation_failed"
ErrPermit2InsufficientBalance = "permit2_insufficient_balance"
ErrPermit2ProxyNotDeployed = "permit2_proxy_not_deployed"
// ERC-20 approval gas-sponsoring errors
ErrErc20ApprovalInsufficientEth = "erc20_approval_insufficient_eth_for_gas"
ErrErc20ApprovalBroadcastFailed = "erc20_approval_broadcast_failed"
)BuilderCodeKey is the extension key for the ERC-8021 builder-code extension. It is replicated here (rather than imported from the buildercode extension package) so the base evm mechanism stays a dependency-free leaf - the buildercode package defines its own matching public constant and imports evm, mirroring the TS shared/extensions BUILDER_CODE_KEY pattern.
Source: mechanisms/evm/datasuffix.go:13
const BuilderCodeKey = "builder-code"Shared EVM error constants used across all EVM payment types. Values must never change without a coordinated update across all SDKs.
Source: mechanisms/evm/permit2_errors.go:8
const (
// ErrAssetNotDeployedContract is returned when the payment asset address has no bytecode.
// EOAs return empty data on any eth_call without reverting, causing silent no-op settlements.
ErrAssetNotDeployedContract = "asset_not_deployed_contract"
)Source: mechanisms/evm/types.go:42
const (
// AssetTransferMethodEIP3009 uses EIP-3009 transferWithAuthorization
AssetTransferMethodEIP3009 AssetTransferMethod = "eip3009"
// AssetTransferMethodPermit2 uses Permit2 + x402Permit2Proxy
AssetTransferMethodPermit2 AssetTransferMethod = "permit2"
)Variables
Source: mechanisms/evm/constants.go:73
var (
// Network chain IDs
ChainIDBase = big.NewInt(8453)
ChainIDBaseSepolia = big.NewInt(84532)
ChainIDMegaETH = big.NewInt(4326)
ChainIDMonad = big.NewInt(143)
ChainIDMezo = big.NewInt(31612)
ChainIDMezoTestnet = big.NewInt(31611)
ChainIDStable = big.NewInt(988)
ChainIDStableTestnet = big.NewInt(2201)
ChainIDPolygon = big.NewInt(137)
ChainIDArbOne = big.NewInt(42161)
ChainIDArbSepolia = big.NewInt(421614)
ChainIDRadius = big.NewInt(723487)
ChainIDRadiusTestnet = big.NewInt(72344)
ChainIDADI = big.NewInt(36900)
ChainIDHPP = big.NewInt(190415)
ChainIDHPPSepolia = big.NewInt(181228)
ChainIDXDC = big.NewInt(50)
ChainIDXDCApothem = big.NewInt(51)
ChainIDIgra = big.NewInt(38833)
ChainIDFlare = big.NewInt(14)
ChainIDCelo = big.NewInt(42220)
ChainIDCeloSepolia = big.NewInt(11142220)
// Network configurations
// See DEFAULT_ASSETS.md for guidelines on adding new chains
//
// Default Asset Selection Policy:
// - Each chain has the right to determine its own default stablecoin
// - If the chain has officially endorsed a stablecoin, that asset should be used
// - If no official stance exists, the chain team should make the selection
//
// Both EIP-3009 (transferWithAuthorization) and Permit2 asset transfer methods are supported.
// EIP-3009 is the default. Set AssetTransferMethod to AssetTransferMethodPermit2 for tokens
// that don't support EIP-3009. See DEFAULT_ASSETS.md for details.
NetworkConfigs = map[string]NetworkConfig{
"eip155:8453": {
ChainID: ChainIDBase,
DefaultAsset: AssetInfo{
Address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
Name: "USD Coin",
Version: "2",
Decimals: DefaultDecimals,
},
},
"eip155:84532": {
ChainID: ChainIDBaseSepolia,
DefaultAsset: AssetInfo{
Address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
Name: "USDC",
Version: "2",
Decimals: DefaultDecimals,
},
},
"eip155:4326": {
ChainID: ChainIDMegaETH,
DefaultAsset: AssetInfo{
Address: "0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7",
Name: "MegaUSD",
Version: "1",
Decimals: 18,
AssetTransferMethod: AssetTransferMethodPermit2,
SupportsEip2612: true,
},
},
"eip155:143": {
ChainID: ChainIDMonad,
DefaultAsset: AssetInfo{
Address: "0x754704Bc059F8C67012fEd69BC8A327a5aafb603",
Name: "USD Coin",
Version: "2",
Decimals: DefaultDecimals,
},
},
"eip155:31612": {
ChainID: ChainIDMezo,
DefaultAsset: AssetInfo{
Address: "0xdD468A1DDc392dcdbEf6db6e34E89AA338F9F186",
Name: "Mezo USD",
Version: "1",
Decimals: 18,
AssetTransferMethod: AssetTransferMethodPermit2,
SupportsEip2612: true,
},
},
"eip155:31611": {
ChainID: ChainIDMezoTestnet,
DefaultAsset: AssetInfo{
Address: "0x118917a40FAF1CD7a13dB0Ef56C86De7973Ac503",
Name: "Mezo USD",
Version: "1",
Decimals: 18,
AssetTransferMethod: AssetTransferMethodPermit2,
SupportsEip2612: true,
},
},
"eip155:988": {
ChainID: ChainIDStable,
DefaultAsset: AssetInfo{
Address: "0x779Ded0c9e1022225f8E0630b35a9b54bE713736",
Name: "USDT0",
Version: "1",
Decimals: DefaultDecimals,
},
},
"eip155:2201": {
ChainID: ChainIDStableTestnet,
DefaultAsset: AssetInfo{
Address: "0x78Cf24370174180738C5B8E352B6D14c83a6c9A9",
Name: "USDT0",
Version: "1",
Decimals: DefaultDecimals,
},
},
"eip155:137": {
ChainID: ChainIDPolygon,
DefaultAsset: AssetInfo{
Address: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
Name: "USD Coin",
Version: "2",
Decimals: DefaultDecimals,
},
},
"eip155:42161": {
ChainID: ChainIDArbOne,
DefaultAsset: AssetInfo{
Address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
Name: "USD Coin",
Version: "2",
Decimals: DefaultDecimals,
},
},
"eip155:421614": {
ChainID: ChainIDArbSepolia,
DefaultAsset: AssetInfo{
Address: "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d",
Name: "USD Coin",
Version: "2",
Decimals: DefaultDecimals,
},
},
"eip155:723487": {
ChainID: ChainIDRadius,
DefaultAsset: AssetInfo{
Address: "0x33ad9e4BD16B69B5BFdED37D8B5D9fF9aba014Fb",
Name: "Stable Coin",
Version: "1",
Decimals: DefaultDecimals,
AssetTransferMethod: AssetTransferMethodPermit2,
SupportsEip2612: true,
},
},
"eip155:72344": {
ChainID: ChainIDRadiusTestnet,
DefaultAsset: AssetInfo{
Address: "0x33ad9e4BD16B69B5BFdED37D8B5D9fF9aba014Fb",
Name: "Stable Coin",
Version: "1",
Decimals: DefaultDecimals,
AssetTransferMethod: AssetTransferMethodPermit2,
SupportsEip2612: true,
},
},
"eip155:36900": {
ChainID: ChainIDADI,
DefaultAsset: AssetInfo{
Address: "0x9cb8142aEBBcdc60AF7c97Af897A67A8f3CA71C2",
Name: "USDC.e",
Version: "2",
Decimals: DefaultDecimals,
},
},
"eip155:190415": {
ChainID: ChainIDHPP,
DefaultAsset: AssetInfo{
Address: "0x401eCb1D350407f13ba348573E5630B83638E30D",
Name: "Bridged USDC",
Version: "2",
Decimals: DefaultDecimals,
},
},
"eip155:181228": {
ChainID: ChainIDHPPSepolia,
DefaultAsset: AssetInfo{
Address: "0x401eCb1D350407f13ba348573E5630B83638E30D",
Name: "Bridged USDC",
Version: "2",
Decimals: DefaultDecimals,
},
},
"eip155:50": {
ChainID: ChainIDXDC,
DefaultAsset: AssetInfo{
Address: "0xfA2958CB79b0491CC627c1557F441eF849Ca8eb1",
Name: "USDC",
Version: "2",
Decimals: DefaultDecimals,
},
},
"eip155:51": {
ChainID: ChainIDXDCApothem,
DefaultAsset: AssetInfo{
Address: "0xb5AB69F7bBada22B28e79C8FFAECe55eF1c771D4",
Name: "USDC",
Version: "2",
Decimals: DefaultDecimals,
},
},
"eip155:38833": {
ChainID: ChainIDIgra,
DefaultAsset: AssetInfo{
Address: "0xA5b8BF902b2844dA17d4506cc827F7F1681735E7",
Name: "USDC",
Version: "1",
Decimals: DefaultDecimals,
AssetTransferMethod: AssetTransferMethodPermit2,
},
},
"eip155:14": {
ChainID: ChainIDFlare,
DefaultAsset: AssetInfo{
Address: "0xe7cd86e13AC4309349F30B3435a9d337750fC82D",
Name: "USD₮0",
Version: "1",
Decimals: DefaultDecimals,
},
},
"eip155:42220": {
ChainID: ChainIDCelo,
DefaultAsset: AssetInfo{
Address: "0xcebA9300f2b948710d2653dD7B07f33A8B32118C",
Name: "USDC",
Version: "2",
Decimals: DefaultDecimals,
},
},
"eip155:11142220": {
ChainID: ChainIDCeloSepolia,
DefaultAsset: AssetInfo{
Address: "0x01C5C0122039549AD1493B8220cABEdD739BC44E",
Name: "USDC",
Version: "2",
Decimals: DefaultDecimals,
},
},
}
// EIP-3009 ABI for transferWithAuthorization with v,r,s (EOA signatures)
TransferWithAuthorizationVRSABI = []byte(`[
{
"inputs": [
{"name": "from", "type": "address"},
{"name": "to", "type": "address"},
{"name": "value", "type": "uint256"},
{"name": "validAfter", "type": "uint256"},
{"name": "validBefore", "type": "uint256"},
{"name": "nonce", "type": "bytes32"},
{"name": "v", "type": "uint8"},
{"name": "r", "type": "bytes32"},
{"name": "s", "type": "bytes32"}
],
"name": "transferWithAuthorization",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]`)
// EIP-3009 ABI for transferWithAuthorization with bytes signature (smart wallets)
TransferWithAuthorizationBytesABI = []byte(`[
{
"inputs": [
{"name": "from", "type": "address"},
{"name": "to", "type": "address"},
{"name": "value", "type": "uint256"},
{"name": "validAfter", "type": "uint256"},
{"name": "validBefore", "type": "uint256"},
{"name": "nonce", "type": "bytes32"},
{"name": "signature", "type": "bytes"}
],
"name": "transferWithAuthorization",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]`)
// Legacy: Combined ABI (deprecated, use specific ABIs above)
TransferWithAuthorizationABI = TransferWithAuthorizationVRSABI
// ERC20TransferEventABI for parsing Transfer event logs
ERC20TransferEventABI = []byte(`[
{
"anonymous": false,
"inputs": [
{"indexed": true, "name": "from", "type": "address"},
{"indexed": true, "name": "to", "type": "address"},
{"indexed": false, "name": "value", "type": "uint256"}
],
"name": "Transfer",
"type": "event"
}
]`)
// ABI for authorizationState check
AuthorizationStateABI = []byte(`[
{
"inputs": [
{"name": "authorizer", "type": "address"},
{"name": "nonce", "type": "bytes32"}
],
"name": "authorizationState",
"outputs": [{"name": "", "type": "bool"}],
"stateMutability": "view",
"type": "function"
}
]`)
// Multicall3TryAggregateABI batches arbitrary eth_call requests.
Multicall3TryAggregateABI = []byte(`[
{
"inputs": [
{"name": "requireSuccess", "type": "bool"},
{
"name": "calls",
"type": "tuple[]",
"components": [
{"name": "target", "type": "address"},
{"name": "callData", "type": "bytes"}
]
}
],
"name": "tryAggregate",
"outputs": [
{
"name": "returnData",
"type": "tuple[]",
"components": [
{"name": "success", "type": "bool"},
{"name": "returnData", "type": "bytes"}
]
}
],
"stateMutability": "payable",
"type": "function"
}
]`)
// ERC20AllowanceABI for checking Permit2 approval
ERC20AllowanceABI = []byte(`[
{
"inputs": [
{"name": "owner", "type": "address"},
{"name": "spender", "type": "address"}
],
"name": "allowance",
"outputs": [{"name": "", "type": "uint256"}],
"stateMutability": "view",
"type": "function"
}
]`)
// ERC20ApproveABI for approving Permit2
ERC20ApproveABI = []byte(`[
{
"inputs": [
{"name": "spender", "type": "address"},
{"name": "amount", "type": "uint256"}
],
"name": "approve",
"outputs": [{"name": "", "type": "bool"}],
"stateMutability": "nonpayable",
"type": "function"
}
]`)
// ERC20BalanceOfABI for checking token balance
ERC20BalanceOfABI = []byte(`[
{
"inputs": [
{"name": "account", "type": "address"}
],
"name": "balanceOf",
"outputs": [{"name": "", "type": "uint256"}],
"stateMutability": "view",
"type": "function"
}
]`)
// ERC20NameABI for checking EIP-712 domain name diagnostics.
ERC20NameABI = []byte(`[
{
"inputs": [],
"name": "name",
"outputs": [{"name": "", "type": "string"}],
"stateMutability": "view",
"type": "function"
}
]`)
// ERC20VersionABI for checking EIP-712 domain version diagnostics.
ERC20VersionABI = []byte(`[
{
"inputs": [],
"name": "version",
"outputs": [{"name": "", "type": "string"}],
"stateMutability": "view",
"type": "function"
}
]`)
// X402ExactPermit2ProxySettleABI for calling settle on x402ExactPermit2Proxy
X402ExactPermit2ProxySettleABI = []byte(`[
{
"type": "function",
"name": "settle",
"inputs": [
{
"name": "permit",
"type": "tuple",
"components": [
{
"name": "permitted",
"type": "tuple",
"components": [
{"name": "token", "type": "address"},
{"name": "amount", "type": "uint256"}
]
},
{"name": "nonce", "type": "uint256"},
{"name": "deadline", "type": "uint256"}
]
},
{"name": "owner", "type": "address"},
{
"name": "witness",
"type": "tuple",
"components": [
{"name": "to", "type": "address"},
{"name": "validAfter", "type": "uint256"}
]
},
{"name": "signature", "type": "bytes"}
],
"outputs": [],
"stateMutability": "nonpayable"
}
]`)
// X402ExactPermit2ProxyPermit2ABI for verifying proxy deployment
X402ExactPermit2ProxyPermit2ABI = []byte(`[
{
"inputs": [],
"name": "PERMIT2",
"outputs": [{"name": "", "type": "address"}],
"stateMutability": "view",
"type": "function"
}
]`)
// Multicall3GetEthBalanceABI for querying native ETH balance via Multicall3.
Multicall3GetEthBalanceABI = []byte(`[
{
"inputs": [
{"name": "addr", "type": "address"}
],
"name": "getEthBalance",
"outputs": [{"name": "balance", "type": "uint256"}],
"stateMutability": "view",
"type": "function"
}
]`)
// X402UptoPermit2ProxySettleABI for calling settle on x402UptoPermit2Proxy.
// Differs from exact: takes an additional `amount` param and witness includes `facilitator`.
X402UptoPermit2ProxySettleABI = []byte(`[
{
"type": "function",
"name": "settle",
"inputs": [
{
"name": "permit",
"type": "tuple",
"components": [
{
"name": "permitted",
"type": "tuple",
"components": [
{"name": "token", "type": "address"},
{"name": "amount", "type": "uint256"}
]
},
{"name": "nonce", "type": "uint256"},
{"name": "deadline", "type": "uint256"}
]
},
{"name": "amount", "type": "uint256"},
{"name": "owner", "type": "address"},
{
"name": "witness",
"type": "tuple",
"components": [
{"name": "to", "type": "address"},
{"name": "facilitator", "type": "address"},
{"name": "validAfter", "type": "uint256"}
]
},
{"name": "signature", "type": "bytes"}
],
"outputs": [],
"stateMutability": "nonpayable"
}
]`)
// X402UptoPermit2ProxySettleWithPermitABI for calling settleWithPermit on x402UptoPermit2Proxy (EIP-2612 extension).
X402UptoPermit2ProxySettleWithPermitABI = []byte(`[
{
"type": "function",
"name": "settleWithPermit",
"inputs": [
{
"name": "permit2612",
"type": "tuple",
"components": [
{"name": "value", "type": "uint256"},
{"name": "deadline", "type": "uint256"},
{"name": "r", "type": "bytes32"},
{"name": "s", "type": "bytes32"},
{"name": "v", "type": "uint8"}
]
},
{
"name": "permit",
"type": "tuple",
"components": [
{
"name": "permitted",
"type": "tuple",
"components": [
{"name": "token", "type": "address"},
{"name": "amount", "type": "uint256"}
]
},
{"name": "nonce", "type": "uint256"},
{"name": "deadline", "type": "uint256"}
]
},
{"name": "amount", "type": "uint256"},
{"name": "owner", "type": "address"},
{
"name": "witness",
"type": "tuple",
"components": [
{"name": "to", "type": "address"},
{"name": "facilitator", "type": "address"},
{"name": "validAfter", "type": "uint256"}
]
},
{"name": "signature", "type": "bytes"}
],
"outputs": [],
"stateMutability": "nonpayable"
}
]`)
// X402UptoPermit2ProxyPermit2ABI for verifying upto proxy deployment
X402UptoPermit2ProxyPermit2ABI = []byte(`[
{
"inputs": [],
"name": "PERMIT2",
"outputs": [{"name": "", "type": "address"}],
"stateMutability": "view",
"type": "function"
}
]`)
// EIP2612NoncesABI for querying EIP-2612 nonces
EIP2612NoncesABI = []byte(`[
{
"inputs": [
{"name": "owner", "type": "address"}
],
"name": "nonces",
"outputs": [{"name": "", "type": "uint256"}],
"stateMutability": "view",
"type": "function"
}
]`)
// X402ExactPermit2ProxySettleWithPermitABI for calling settleWithPermit (EIP-2612 extension)
X402ExactPermit2ProxySettleWithPermitABI = []byte(`[
{
"type": "function",
"name": "settleWithPermit",
"inputs": [
{
"name": "permit2612",
"type": "tuple",
"components": [
{"name": "value", "type": "uint256"},
{"name": "deadline", "type": "uint256"},
{"name": "r", "type": "bytes32"},
{"name": "s", "type": "bytes32"},
{"name": "v", "type": "uint8"}
]
},
{
"name": "permit",
"type": "tuple",
"components": [
{
"name": "permitted",
"type": "tuple",
"components": [
{"name": "token", "type": "address"},
{"name": "amount", "type": "uint256"}
]
},
{"name": "nonce", "type": "uint256"},
{"name": "deadline", "type": "uint256"}
]
},
{"name": "owner", "type": "address"},
{
"name": "witness",
"type": "tuple",
"components": [
{"name": "to", "type": "address"},
{"name": "validAfter", "type": "uint256"}
]
},
{"name": "signature", "type": "bytes"}
],
"outputs": [],
"stateMutability": "nonpayable"
}
]`)
// EIP712DomainTypes defines the standard EIP-712 domain type for Permit2.
// Permit2 uses name + chainId + verifyingContract (no version field).
EIP712DomainTypes = []TypedDataField{
{Name: "name", Type: "string"},
{Name: "chainId", Type: "uint256"},
{Name: "verifyingContract", Type: "address"},
}
// Permit2WitnessTypes defines the EIP-712 types for Permit2 with witness.
// Field order MUST match the on-chain Permit2 contract and TypeScript implementation.
Permit2WitnessTypes = map[string][]TypedDataField{
"PermitWitnessTransferFrom": {
{Name: "permitted", Type: "TokenPermissions"},
{Name: "spender", Type: "address"},
{Name: "nonce", Type: "uint256"},
{Name: "deadline", Type: "uint256"},
{Name: "witness", Type: "Witness"},
},
"TokenPermissions": {
{Name: "token", Type: "address"},
{Name: "amount", Type: "uint256"},
},
"Witness": {
{Name: "to", Type: "address"},
{Name: "validAfter", Type: "uint256"},
},
}
)EIP2612PermitTypes defines the EIP-712 types for EIP-2612 permit signing.
Source: mechanisms/evm/constants.go:774
var EIP2612PermitTypes = map[string][]TypedDataField{
"Permit": {
{Name: "owner", Type: "address"},
{Name: "spender", Type: "address"},
{Name: "value", Type: "uint256"},
{Name: "nonce", Type: "uint256"},
{Name: "deadline", Type: "uint256"},
},
}EIP712DomainTypesWithVersion is the standard EIP-712 domain type with version field. Used by EIP-2612 tokens (unlike Permit2 which omits version).
Source: mechanisms/evm/constants.go:786
var EIP712DomainTypesWithVersion = []TypedDataField{
{Name: "name", Type: "string"},
{Name: "version", Type: "string"},
{Name: "chainId", Type: "uint256"},
{Name: "verifyingContract", Type: "address"},
}UptoPermit2WitnessTypes defines the EIP-712 types for the upto Permit2 witness.
The upto witness includes a facilitator field absent from the exact witness.
Only the address matching witness.facilitator can call settle() on-chain.
Field order MUST match the on-chain x402UptoPermit2Proxy contract and TypeScript implementation.
Source: mechanisms/evm/constants.go:805
var UptoPermit2WitnessTypes = map[string][]TypedDataField{
"PermitWitnessTransferFrom": {
{Name: "permitted", Type: "TokenPermissions"},
{Name: "spender", Type: "address"},
{Name: "nonce", Type: "uint256"},
{Name: "deadline", Type: "uint256"},
{Name: "witness", Type: "Witness"},
},
"TokenPermissions": {
{Name: "token", Type: "address"},
{Name: "amount", Type: "uint256"},
},
"Witness": {
{Name: "to", Type: "address"},
{Name: "facilitator", Type: "address"},
{Name: "validAfter", Type: "uint256"},
},
}Functions
func AppendDataSuffix(calldata, suffix []byte) []byte
Source: mechanisms/evm/datasuffix.go:54
AppendDataSuffix appends an ERC-8021 data suffix to ABI-encoded calldata, returning the calldata unchanged when suffix is empty. Signers call this after packing the call so the suffix lands on-chain. Mirrors TS appendDataSuffix.
func BuildPermit2WitnessMap(to string, validAfter *big.Int) map[string]interface{}
Source: mechanisms/evm/eip712.go:254
BuildPermit2WitnessMap returns the witness map used in EIP-712 message construction. Centralizing this ensures eip712.go and exact/client/permit2.go stay in sync when the witness struct changes.
func BuildUptoPermit2WitnessMap(to string, facilitator string, validAfter *big.Int) map[string]interface{}
Source: mechanisms/evm/eip712.go:193
BuildUptoPermit2WitnessMap returns the witness map for upto EIP-712 message construction. Includes the facilitator field absent from the exact witness.
func BytesToHex(data []byte) string
Source: mechanisms/evm/utils.go:229
BytesToHex converts bytes to a hex string with 0x prefix
func CreateNonce() (string, error)
Source: mechanisms/evm/utils.go:27
CreateNonce generates a random 32-byte nonce for EIP-3009
func CreatePermit2Nonce() (string, error)
Source: mechanisms/evm/utils.go:38
CreatePermit2Nonce generates a random 256-bit nonce for Permit2. Permit2 uses uint256 nonces (not bytes32 like EIP-3009).
func CreateValidityWindow(duration time.Duration) (validAfter, validBefore *big.Int)
Source: mechanisms/evm/utils.go:214
CreateValidityWindow creates valid after/before timestamps
func FormatAmount(amount *big.Int, decimals int) string
Source: mechanisms/evm/utils.go:121
FormatAmount converts an amount in wei to a decimal string
func GetAssetInfo(network string, assetSymbolOrAddress string) (*AssetInfo, error)
Source: mechanisms/evm/utils.go:177
GetAssetInfo returns information about an asset on a network. If assetSymbolOrAddress is a valid address, returns info for that specific token. If assetSymbolOrAddress is empty or a symbol, attempts to use the network's default asset.
Args:
- network: The network identifier
- assetSymbolOrAddress: Either an asset address (0x...) or empty for default
Returns:
- AssetInfo for the requested asset
- Error if default asset is requested but not configured for this network
func GetEIP2612EIP712Types() map[string][]TypedDataField
Source: mechanisms/evm/constants.go:794
GetEIP2612EIP712Types returns the complete EIP-712 types map for EIP-2612 signing.
func GetERC7702DelegateAddress(code []byte) (common.Address, bool)
Source: mechanisms/evm/erc7702.go:25
GetERC7702DelegateAddress extracts the 20-byte delegate address from a 7702 designation. Returns a checksummed EIP-55 common.Address. The Python and TypeScript equivalents return lowercase hex strings - normalise before comparing cross-SDK outputs. Returns (common.Address{}, false) if code is not a valid delegation.
func GetEvmChainId(network string) (*big.Int, error)
Source: mechanisms/evm/utils.go:14
GetEvmChainId returns the chain ID for a given CAIP-2 network identifier (eip155:CHAIN_ID).
func GetNetworkConfig(network string) (*NetworkConfig, error)
Source: mechanisms/evm/utils.go:148
GetNetworkConfig returns the configuration for a CAIP-2 network identifier (eip155:CHAIN_ID). For networks with configured defaults, returns the full config. For other valid EIP-155 networks, returns a config with just the chain ID (no default asset).
func GetPermit2EIP712Types() map[string][]TypedDataField
Source: mechanisms/evm/constants.go:764
GetPermit2EIP712Types returns the complete EIP-712 types map for Permit2 signing. This combines the EIP712Domain with the Permit2-specific types. Use this function instead of defining types locally to ensure consistency.
func GetUptoPermit2EIP712Types() map[string][]TypedDataField
Source: mechanisms/evm/constants.go:826
GetUptoPermit2EIP712Types returns the complete EIP-712 types map for upto Permit2 signing. This combines the EIP712Domain with the upto-specific Permit2 types (including facilitator in witness).
func HasEIP6492Deployment(sigData *ERC6492SignatureData) bool
Source: mechanisms/evm/erc6492_deploy.go:16
HasEIP6492Deployment reports whether sigData carries ERC-6492 factory deployment information (a non-zero factory address and non-empty factory calldata).
Shared across facilitator schemes (exact, batch-settlement) so the counterfactual deployment routing is identical everywhere.
func HashEIP3009Authorization( authorization ExactEIP3009Authorization, chainID *big.Int, verifyingContract string, tokenName string, tokenVersion string, ) ([]byte, error)
Source: mechanisms/evm/eip712.go:123
HashEIP3009Authorization hashes a TransferWithAuthorization message for EIP-3009
This is a convenience function that wraps HashTypedData with the specific types and structure used by EIP-3009's transferWithAuthorization.
Args:
authorization: The EIP-3009 authorization data
chainID: The chain ID for the EIP-712 domain
verifyingContract: The token contract address
tokenName: The token name (e.g., "USD Coin")
tokenVersion: The token version (e.g., "2")Returns:
32-byte hash suitable for signing or verification
error if hashing failsfunc HashEIP712TypedData( domain TypedDataDomain, types map[string][]TypedDataField, primaryType string, message map[string]interface{}, ) ([32]byte, error)
Source: mechanisms/evm/verify_strict.go:53
HashEIP712TypedData computes the canonical EIP-712 digest: keccak256("\x19\x01" || domainSeparator || hashStruct(message))
func HashPermit2Authorization( authorization Permit2Authorization, chainID *big.Int, ) ([]byte, error)
Source: mechanisms/evm/eip712.go:275
HashPermit2Authorization hashes a PermitWitnessTransferFrom message for Permit2.
This function creates the EIP-712 hash for Permit2's PermitWitnessTransferFrom with the x402 witness structure.
Args:
authorization: The Permit2 authorization data
chainID: The chain ID for the EIP-712 domainReturns:
32-byte hash suitable for signing or verification
error if hashing failsfunc HashTypedData( domain TypedDataDomain, types map[string][]TypedDataField, primaryType string, message map[string]interface{}, ) ([]byte, error)
Source: mechanisms/evm/eip712.go:29
HashTypedData hashes EIP-712 typed data according to the specification
This function creates the EIP-712 hash that should be signed or verified. The hash is computed as: keccak256("\x19\x01" + domainSeparator + structHash)
Args:
domain: The EIP-712 domain separator parameters
types: The type definitions for the structured data
primaryType: The name of the primary type being hashed
message: The message data to hashReturns:
32-byte hash suitable for signing or verification
error if hashing failsfunc HashUptoPermit2Authorization( authorization UptoPermit2Authorization, chainID *big.Int, ) ([]byte, error)
Source: mechanisms/evm/eip712.go:203
HashUptoPermit2Authorization hashes a PermitWitnessTransferFrom message for the upto Permit2 scheme. Uses upto-specific witness types that include the facilitator address.
func HexToBytes(hexStr string) ([]byte, error)
Source: mechanisms/evm/utils.go:222
HexToBytes converts a hex string to bytes
func IsContractRevert(err error) bool
Source: mechanisms/evm/erc6492_deploy.go:28
IsContractRevert reports whether err looks like an on-chain contract revert (as opposed to a transport/RPC failure). Used to avoid misreporting an RPC blip during a post-deploy simulation as a deterministic "signature unsupported" rejection. Matches the revert-substring heuristic the EIP-3009 revert-reason parsers already rely on.
func IsEIP3009Payload(data map[string]interface{}) bool
Source: mechanisms/evm/types.go:183
IsEIP3009Payload checks if a payload map is an EIP-3009 payload.
func IsERC6492Signature(sig []byte) bool
Source: mechanisms/evm/erc6492.go:29
IsERC6492Signature checks if a signature has the ERC-6492 magic suffix
ERC-6492 signatures are wrapped signatures for counterfactual smart contract accounts. They end with a specific 32-byte magic value to distinguish them from regular signatures.
Args:
sig: The signature bytes to checkReturns:
true if the signature ends with the ERC-6492 magic valuefunc IsERC7702Delegation(code []byte) bool
Source: mechanisms/evm/erc7702.go:14
IsERC7702Delegation reports whether code is a valid ERC-7702 delegation designation: exactly 23 bytes (3-byte prefix + 20-byte delegate address).
NOTE: this is a diagnostic helper - the verification path does not branch on 7702 detection. It routes by code.length (via VerifySignatureStrict) and the delegate decides via isValidSignature, which mirrors on-chain SignatureChecker semantics.
func IsFactoryAllowed(factory [20]byte, allowedFactories []string) bool
Source: mechanisms/evm/erc6492_deploy.go:37
IsFactoryAllowed reports whether factory is present in allowedFactories (case-insensitive). An empty allowlist denies all factories, preventing unconstrained arbitrary call injection.
func IsPermit2Payload(data map[string]interface{}) bool
Source: mechanisms/evm/types.go:177
IsPermit2Payload checks if a payload map is a Permit2 payload.
func IsUptoPermit2Payload(data map[string]interface{}) bool
Source: mechanisms/evm/types.go:496
IsUptoPermit2Payload checks if a payload map is an upto Permit2 payload. Validates structural presence of all required fields including witness.facilitator.
func IsValidAddress(address string) bool
Source: mechanisms/evm/utils.go:67
IsValidAddress checks if a string is a valid Ethereum address
func MaxUint256() *big.Int
Source: mechanisms/evm/utils.go:50
MaxUint256 returns the maximum value for uint256 (used for unlimited approval).
func Multicall( ctx context.Context, signer FacilitatorEvmSigner, calls []MulticallCall, ) ([]MulticallResult, error)
Source: mechanisms/evm/multicall.go:46
Multicall batches typed and raw eth_call requests via Multicall3.
func NormalizeAddress(address string) string
Source: mechanisms/evm/utils.go:58
NormalizeAddress ensures an Ethereum address is in the correct format
func ParseAmount(amount string, decimals int) (*big.Int, error)
Source: mechanisms/evm/utils.go:82
ParseAmount converts a decimal string amount to wei based on token decimals
func ParseERC6492Signature(sig []byte) (*ERC6492SignatureData, error)
Source: mechanisms/evm/erc6492.go:53
ParseERC6492Signature unwraps an ERC-6492 signature to extract its components
ERC-6492 Format:
abi.encode((address factory, bytes factoryCalldata, bytes signature)) + magicBytesIf the signature is not ERC-6492 format, it returns the original signature as the InnerSignature with empty Factory and FactoryCalldata.
Args:
sig: The signature bytes (may or may not be ERC-6492 wrapped)Returns:
ERC6492SignatureData containing the parsed components
error if the ERC-6492 format is invalidfunc PayloadFromMap(data map[string]interface{}) (*ExactEIP3009Payload, error)
Source: mechanisms/evm/types.go:335
PayloadFromMap creates an ExactEIP3009Payload from a map
func Permit2PayloadFromMap(data map[string]interface{}) (*ExactPermit2Payload, error)
Source: mechanisms/evm/types.go:103
Permit2PayloadFromMap creates an ExactPermit2Payload from a map. Returns an error if required fields are missing or malformed.
func ResolveDataSuffix(fctx *x402.FacilitatorContext, ctx DataSuffixContext) ([]byte, error)
Source: mechanisms/evm/datasuffix.go:33
ResolveDataSuffix fetches the builder-code facilitator extension from fctx and returns the data suffix it produces. Returns nil when fctx is nil, no matching extension is registered, or the extension produces no suffix.
func ResolveRPCURL(config *RPCConfig, network string) string
Source: mechanisms/evm/rpc.go:30
ResolveRPCURL returns the appropriate RPC URL for the given network.
func ResolveReadSigner( ctx context.Context, signer ClientEvmSigner, rpcURL string, ) (ClientEvmSignerWithReadContract, error)
Source: mechanisms/evm/rpc.go:215
ResolveReadSigner returns a ClientEvmSignerWithReadContract. If the signer already implements a functional ReadContract, it is returned as-is. Otherwise an RPC-backed wrapper is created using rpcURL; if rpcURL is empty, nil is returned without error.
func ResolveTxSigner( ctx context.Context, signer ClientEvmSigner, rpcURL string, ) (ClientEvmSignerWithTxSigning, error)
Source: mechanisms/evm/rpc.go:242
ResolveTxSigner returns a ClientEvmSignerWithTxSigning. Nonce and fee-estimation capabilities are taken from the signer when available, and fall back to the provided rpcURL. Returns nil without error when the signer cannot sign transactions or when RPC capabilities are needed but rpcURL is empty.
func SendFactoryDeployTransaction( ctx context.Context, signer FacilitatorEvmSigner, sigData *ERC6492SignatureData, ) error
Source: mechanisms/evm/erc6492_deploy.go:50
SendFactoryDeployTransaction submits the ERC-6492 factory deployment transaction and waits for the receipt, returning an error if the deployment transaction reverted. It is a no-op (nil) when sigData carries no deployment information.
func SplitEip2612Signature(signature string) (uint8, [32]byte, [32]byte, error)
Source: mechanisms/evm/eip2612.go:42
SplitEip2612Signature splits a 65-byte hex-encoded signature into v, r, s components.
func UptoPermit2PayloadFromMap(data map[string]interface{}) (*UptoPermit2Payload, error)
Source: mechanisms/evm/types.go:415
UptoPermit2PayloadFromMap creates an UptoPermit2Payload from a map. Returns an error if required fields are missing or malformed.
func ValidateAssetIsContract(ctx context.Context, signer FacilitatorEvmSigner, asset string) (string, error)
Source: mechanisms/evm/utils.go:236
ValidateAssetIsContract checks whether the payment asset is a deployed contract. Returns (ErrAssetNotDeployedContract, nil) for an EOA/empty address, ("", nil) for a deployed contract, or ("", err) if eth_getCode itself fails.
func ValidateEip2612PermitForPayment(info *eip2612gassponsor.Info, payer string, tokenAddress string) string
Source: mechanisms/evm/eip2612.go:14
ValidateEip2612PermitForPayment validates EIP-2612 extension data for a Permit2 payment. Returns an empty string if valid, or an error-reason string on failure.
func VerifyEIP1271Signature( ctx context.Context, signer FacilitatorEvmSigner, wallet string, hash [32]byte, signature []byte, ) (bool, error)
Source: mechanisms/evm/verify_1271.go:42
VerifyEIP1271Signature verifies a signature from a smart contract wallet using EIP-1271
EIP-1271 defines a standard way for contracts to verify signatures. This function calls the isValidSignature(bytes32,bytes) function on the smart contract wallet and checks if it returns the magic value 0x1626ba7e.
Args:
ctx: Context for cancellation and timeout control
signer: The facilitator signer that can perform contract calls
wallet: The smart contract wallet address (as hex string)
hash: The 32-byte message hash that was signed
signature: The signature bytes (format is wallet-specific)Returns:
true if the contract returns the EIP-1271 magic value
error if the contract call fails or returns an invalid responsefunc VerifyEOASignature( hash []byte, signature []byte, expectedAddress common.Address, ) (bool, error)
Source: mechanisms/evm/verify_eoa.go:26
VerifyEOASignature verifies an ECDSA signature from an externally owned account (EOA)
This function uses secp256k1 public key recovery to verify that the signature was created by the expected address. It handles the Ethereum-specific v value adjustment (27/28 → 0/1 for recovery).
Args:
hash: The 32-byte message hash that was signed
signature: The 65-byte ECDSA signature (r: 32 bytes, s: 32 bytes, v: 1 byte)
expectedAddress: The Ethereum address that should have signed the messageReturns:
true if the signature is valid and recovers to the expected address
error if the signature is malformed or recovery failsfunc VerifyEOATypedData( address string, domain TypedDataDomain, types map[string][]TypedDataField, primaryType string, message map[string]interface{}, signature []byte, ) (bool, error)
Source: mechanisms/evm/verify_strict.go:129
VerifyEOATypedData verifies an EIP-712 typed-data signature using pure ECDSA (no on-chain call). Use this for the payerAuthorizer path in batch-settlement where the on-chain contract also uses ECDSA.recoverCalldata - regardless of code presence at the address.
func VerifySignatureStrict( ctx context.Context, signer FacilitatorEvmSigner, address string, hash [32]byte, signature []byte, ) (bool, error)
Source: mechanisms/evm/verify_strict.go:23
VerifySignatureStrict verifies a raw 32-byte digest against an address using the same code-routing rule as on-chain SignatureChecker (Permit2, USDC v2.2, OpenZeppelin):
- address has no bytecode → ecrecover (EOA path)
- address has bytecode → IERC1271.isValidSignature (strict EIP-1271, no ECDSA fallback)
This prevents the pre-verify/on-chain divergence that arises when an ECDSA fallback accepts signatures that the on-chain verifier routes to EIP-1271 and rejects - most visibly for ERC-7702 delegated EOAs whose delegate does not accept raw owner ECDSA.
func VerifyTypedDataStrict( ctx context.Context, signer FacilitatorEvmSigner, address string, domain TypedDataDomain, types map[string][]TypedDataField, primaryType string, message map[string]interface{}, signature []byte, ) (bool, error)
Source: mechanisms/evm/verify_strict.go:109
VerifyTypedDataStrict verifies an EIP-712 typed-data signature using the strict code-routed primitive. Replaces signer.VerifyTypedData in facilitator code paths where the on-chain verifier routes by code.length (Permit2, USDC v2.2, OZ SignatureChecker).
func VerifyUniversalSignature( ctx context.Context, facilitatorSigner FacilitatorEvmSigner, signerAddress string, hash [32]byte, signature []byte, allowUndeployed bool, ) (bool, *ERC6492SignatureData, error)
Source: mechanisms/evm/verify_universal.go:40
VerifyUniversalSignature verifies signatures from EOA, EIP-1271, and ERC-6492 sources.
This function mirrors on-chain SignatureChecker semantics - routing is determined by code.length at the signer address, not by the byte-length of the signature. The old 65-byte EOA fast-path (that skipped GetCode) was removed because it caused pre-verify to accept signatures that on-chain verifiers routed to isValidSignature and rejected, most visibly for ERC-7702-delegated EOAs whose delegate rejects raw owner ECDSA.
The verification flow:
- Parse ERC-6492 wrapper if present to extract inner signature
- GetCode - always required; determines whether to use ECDSA or EIP-1271
- If undeployed + has deployment info + allowUndeployed: classify as counterfactual, do not treat as valid until a later onchain simulation succeeds
- If undeployed without deployment info: ECDSA fallback (covers plain EOAs)
- If deployed (any address with code, including ERC-7702): strict EIP-1271
Args:
ctx: Context for cancellation and timeout control
facilitatorSigner: The facilitator signer for blockchain interactions
signerAddress: The address that should have signed (hex string)
hash: The 32-byte message hash that was signed
signature: The signature bytes (may be wrapped in ERC-6492 format)
allowUndeployed: Whether to accept ERC-6492 signatures from undeployed walletsReturns:
valid: true if the signature is valid
sigData: Parsed ERC-6492 data (if applicable)
error: Any error that occurred during verificationTypes
type AssetInfo
Source: mechanisms/evm/types.go:300
AssetInfo contains information about an ERC20 token
type AssetInfo struct {
Address string
Name string
Version string
Decimals int
AssetTransferMethod AssetTransferMethod
SupportsEip2612 bool
}Fields
Address stringName stringVersion stringDecimals intAssetTransferMethod AssetTransferMethodSupportsEip2612 bool
type AssetTransferMethod
Source: mechanisms/evm/types.go:38
AssetTransferMethod defines how assets are transferred on EVM chains. The choice affects which on-chain mechanism is used for token transfers:
- eip3009: Uses transferWithAuthorization (USDC, etc.) - recommended for compatible tokens
- permit2: Uses Permit2 + x402Permit2Proxy - universal fallback for any ERC-20
type AssetTransferMethod stringtype BuilderCodeFacilitatorExtension
Source: mechanisms/evm/datasuffix.go:25
BuilderCodeFacilitatorExtension is implemented by the builder-code facilitator extension. BuildDataSuffix returns the encoded ERC-8021 suffix for the given settlement, or nil when there is nothing to attribute.
type BuilderCodeFacilitatorExtension interface {
x402.FacilitatorExtension
BuildDataSuffix(ctx DataSuffixContext) ([]byte, error)
}Methods
x402.FacilitatorExtensionBuildDataSuffix func(ctx DataSuffixContext) ([]byte, error)
type ClientEvmSigner
Source: mechanisms/evm/types.go:235
ClientEvmSigner defines the minimal interface for client-side EVM signing operations.
Base payment signing only requires address + typed-data signing. Optional extension flows can use additional capability interfaces like ClientEvmSignerWithReadContract and ClientEvmSignerWithTxSigning.
type ClientEvmSigner interface {
// Address returns the signer's Ethereum address
Address() string
// SignTypedData signs EIP-712 typed data
SignTypedData(ctx context.Context, domain TypedDataDomain, types map[string][]TypedDataField, primaryType string, message map[string]interface{}) ([]byte, error)
}Methods
Address func() stringAddress returns the signer's Ethereum address
SignTypedData func(ctx context.Context, domain TypedDataDomain, types map[string][]TypedDataField, primaryType string, message map[string]interface{}) ([]byte, error)SignTypedData signs EIP-712 typed data
type ClientEvmSignerWithEstimateFeesPerGas
Source: mechanisms/evm/types.go:214
ClientEvmSignerWithEstimateFeesPerGas extends ClientEvmSigner with fee estimation.
type ClientEvmSignerWithEstimateFeesPerGas interface {
ClientEvmSigner
// EstimateFeesPerGas returns the EIP-1559 maxFeePerGas and maxPriorityFeePerGas.
EstimateFeesPerGas(ctx context.Context) (maxFeePerGas, maxPriorityFeePerGas *big.Int, err error)
}Methods
ClientEvmSignerEstimateFeesPerGas func(ctx context.Context) (maxFeePerGas, maxPriorityFeePerGas *big.Int, err error)EstimateFeesPerGas returns the EIP-1559 maxFeePerGas and maxPriorityFeePerGas.
type ClientEvmSignerWithGetTransactionCount
Source: mechanisms/evm/types.go:206
ClientEvmSignerWithGetTransactionCount extends ClientEvmSigner with nonce lookup.
type ClientEvmSignerWithGetTransactionCount interface {
ClientEvmSigner
// GetTransactionCount returns the pending nonce for an address.
GetTransactionCount(ctx context.Context, address string) (uint64, error)
}Methods
ClientEvmSignerGetTransactionCount func(ctx context.Context, address string) (uint64, error)GetTransactionCount returns the pending nonce for an address.
type ClientEvmSignerWithReadContract
Source: mechanisms/evm/types.go:223
ClientEvmSignerWithReadContract extends ClientEvmSigner with on-chain read capability. Used by extension enrichment paths (EIP-2612 nonce lookup, allowance checks).
type ClientEvmSignerWithReadContract interface {
ClientEvmSigner
// ReadContract reads data from a smart contract.
ReadContract(ctx context.Context, address string, abi []byte, functionName string, args ...interface{}) (interface{}, error)
}Methods
ClientEvmSignerReadContract func(ctx context.Context, address string, abi []byte, functionName string, args ...interface{}) (interface{}, error)ReadContract reads data from a smart contract.
type ClientEvmSignerWithSignTransaction
Source: mechanisms/evm/types.go:198
ClientEvmSignerWithSignTransaction extends ClientEvmSigner with raw tx signing.
type ClientEvmSignerWithSignTransaction interface {
ClientEvmSigner
// SignTransaction signs an EIP-1559 transaction and returns the RLP-encoded bytes.
SignTransaction(ctx context.Context, tx *goethtypes.Transaction) ([]byte, error)
}Methods
ClientEvmSignerSignTransaction func(ctx context.Context, tx *goethtypes.Transaction) ([]byte, error)SignTransaction signs an EIP-1559 transaction and returns the RLP-encoded bytes.
type ClientEvmSignerWithTxSigning
Source: mechanisms/evm/types.go:191
ClientEvmSignerWithTxSigning extends ClientEvmSigner with raw transaction signing capabilities. Required for the ERC-20 approval gas sponsoring extension, where the client signs (but does not broadcast) an approve(Permit2, MaxUint256) transaction.
type ClientEvmSignerWithTxSigning interface {
ClientEvmSignerWithSignTransaction
ClientEvmSignerWithGetTransactionCount
ClientEvmSignerWithEstimateFeesPerGas
}Methods
ClientEvmSignerWithSignTransactionClientEvmSignerWithGetTransactionCountClientEvmSignerWithEstimateFeesPerGas
type DataSuffixContext
Source: mechanisms/evm/datasuffix.go:17
DataSuffixContext carries the settlement payload and requirements a facilitator extension inspects when building an ERC-8021 calldata suffix.
type DataSuffixContext struct {
Payload types.PaymentPayload
Requirements types.PaymentRequirements
}Fields
Payload types.PaymentPayloadRequirements types.PaymentRequirements
type ERC6492SignatureData
Source: mechanisms/evm/types.go:529
ERC6492SignatureData represents the parsed components of an ERC-6492 signature ERC-6492 allows signatures from undeployed smart contract accounts by wrapping the signature with deployment information (factory address and calldata)
type ERC6492SignatureData struct {
Factory [20]byte // CREATE2 factory address (zero address if not ERC-6492)
FactoryCalldata []byte // Calldata to deploy the wallet (empty if not ERC-6492)
InnerSignature []byte // The actual signature (EIP-1271 or EOA)
}Fields
Factory [20]byteCREATE2 factory address (zero address if not ERC-6492)
FactoryCalldata []byteCalldata to deploy the wallet (empty if not ERC-6492)
InnerSignature []byteThe actual signature (EIP-1271 or EOA)
type ExactEIP3009Authorization
Source: mechanisms/evm/types.go:12
ExactEIP3009Authorization represents the EIP-3009 TransferWithAuthorization data
type ExactEIP3009Authorization struct {
From string `json:"from"` // Ethereum address (hex)
To string `json:"to"` // Ethereum address (hex)
Value string `json:"value"` // Amount in wei as string
ValidAfter string `json:"validAfter"` // Unix timestamp as string
ValidBefore string `json:"validBefore"` // Unix timestamp as string
Nonce string `json:"nonce"` // 32-byte nonce as hex string
}Fields
From string`json:"from"`Ethereum address (hex)
To string`json:"to"`Ethereum address (hex)
Value string`json:"value"`Amount in wei as string
ValidAfter string`json:"validAfter"`Unix timestamp as string
ValidBefore string`json:"validBefore"`Unix timestamp as string
Nonce string`json:"nonce"`32-byte nonce as hex string
type ExactEIP3009Payload
Source: mechanisms/evm/types.go:22
ExactEIP3009Payload represents the exact payment payload for EVM networks
type ExactEIP3009Payload struct {
Signature string `json:"signature,omitempty"`
Authorization ExactEIP3009Authorization `json:"authorization"`
}Fields
Signature string`json:"signature,omitempty"`Authorization ExactEIP3009Authorization`json:"authorization"`
func ToMap() map[string]interface{}
Source: mechanisms/evm/types.go:317
PayloadToMap converts an ExactEIP3009Payload to a map for JSON marshaling
type ExactEvmPayloadV1
Source: mechanisms/evm/types.go:28
ExactEvmPayloadV1 is an alias for ExactEIP3009Payload (v1 compatibility)
type ExactEvmPayloadV1 = ExactEIP3009Payloadtype ExactEvmPayloadV2
Source: mechanisms/evm/types.go:32
ExactEvmPayloadV2 is an alias for ExactEIP3009Payload (v2 compatibility) Note: V2 also supports ExactPermit2Payload - use IsPermit2Payload() to check
type ExactEvmPayloadV2 = ExactEIP3009Payloadtype ExactPermit2Payload
Source: mechanisms/evm/types.go:75
ExactPermit2Payload represents the Permit2 payment payload sent by clients. This is the complete payment data including the EIP-712 signature.
type ExactPermit2Payload struct {
Signature string `json:"signature"` // EIP-712 signature (hex, 65 bytes for EOA)
Permit2Authorization Permit2Authorization `json:"permit2Authorization"` // Authorization parameters that were signed
}Fields
Signature string`json:"signature"`EIP-712 signature (hex, 65 bytes for EOA)
Permit2Authorization Permit2Authorization`json:"permit2Authorization"`Authorization parameters that were signed
func ToMap() map[string]interface{}
Source: mechanisms/evm/types.go:81
ToMap converts an ExactPermit2Payload to a map for JSON marshaling.
type FacilitatorEvmSigner
Source: mechanisms/evm/types.go:245
FacilitatorEvmSigner defines the interface for facilitator EVM operations Supports multiple addresses for load balancing, key rotation, and high availability
type FacilitatorEvmSigner interface {
// GetAddresses returns all addresses this facilitator can use for signing
// Enables dynamic address selection for load balancing and key rotation
GetAddresses() []string
// ReadContract reads data from a smart contract
ReadContract(ctx context.Context, address string, abi []byte, functionName string, args ...interface{}) (interface{}, error)
// VerifyTypedData verifies an EIP-712 signature
VerifyTypedData(ctx context.Context, address string, domain TypedDataDomain, types map[string][]TypedDataField, primaryType string, message map[string]interface{}, signature []byte) (bool, error)
// WriteContract executes a smart contract transaction
WriteContract(ctx context.Context, address string, abi []byte, functionName string, dataSuffix []byte, args ...interface{}) (string, error)
// SendTransaction sends a raw transaction with arbitrary calldata
// Used for smart wallet deployment where calldata is pre-encoded
SendTransaction(ctx context.Context, to string, data []byte) (string, error)
// WaitForTransactionReceipt waits for a transaction to be mined
WaitForTransactionReceipt(ctx context.Context, txHash string) (*TransactionReceipt, error)
// GetBalance gets the balance of an address for a specific token
GetBalance(ctx context.Context, address string, tokenAddress string) (*big.Int, error)
// GetChainID returns the chain ID of the connected network
GetChainID(ctx context.Context) (*big.Int, error)
// GetCode returns the bytecode at the given address
// Returns empty slice if address is an EOA or doesn't exist
GetCode(ctx context.Context, address string) ([]byte, error)
}Methods
GetAddresses func() []stringGetAddresses returns all addresses this facilitator can use for signing Enables dynamic address selection for load balancing and key rotation
ReadContract func(ctx context.Context, address string, abi []byte, functionName string, args ...interface{}) (interface{}, error)ReadContract reads data from a smart contract
VerifyTypedData func(ctx context.Context, address string, domain TypedDataDomain, types map[string][]TypedDataField, primaryType string, message map[string]interface{}, signature []byte) (bool, error)VerifyTypedData verifies an EIP-712 signature
WriteContract func(ctx context.Context, address string, abi []byte, functionName string, dataSuffix []byte, args ...interface{}) (string, error)WriteContract executes a smart contract transaction
SendTransaction func(ctx context.Context, to string, data []byte) (string, error)SendTransaction sends a raw transaction with arbitrary calldata Used for smart wallet deployment where calldata is pre-encoded
WaitForTransactionReceipt func(ctx context.Context, txHash string) (*TransactionReceipt, error)WaitForTransactionReceipt waits for a transaction to be mined
GetBalance func(ctx context.Context, address string, tokenAddress string) (*big.Int, error)GetBalance gets the balance of an address for a specific token
GetChainID func(ctx context.Context) (*big.Int, error)GetChainID returns the chain ID of the connected network
GetCode func(ctx context.Context, address string) ([]byte, error)GetCode returns the bytecode at the given address Returns empty slice if address is an EOA or doesn't exist
type MulticallCall
Source: mechanisms/evm/multicall.go:15
MulticallCall describes one batched call. Use CallData for pre-encoded raw calls, or ABI/FunctionName/Args for typed calls.
type MulticallCall struct {
Address string
ABI []byte
FunctionName string
Args []interface{}
CallData []byte
}Fields
Address stringABI []byteFunctionName stringArgs []interface{}CallData []byte
type MulticallResult
Source: mechanisms/evm/multicall.go:24
MulticallResult is the decoded outcome of one batched call.
type MulticallResult struct {
Status string
Result interface{}
Error error
}Fields
Status stringResult interface{}Error error
func Success() bool
Source: mechanisms/evm/multicall.go:41
Success reports whether the call completed successfully.
type NetworkConfig
Source: mechanisms/evm/types.go:311
NetworkConfig contains network-specific configuration See DEFAULT_ASSETS.md for guidelines on adding new chains
type NetworkConfig struct {
ChainID *big.Int
DefaultAsset AssetInfo
}Fields
ChainID *big.IntDefaultAsset AssetInfo
type Permit2Authorization
Source: mechanisms/evm/types.go:64
Permit2Authorization represents the Permit2 authorization parameters. This maps to the PermitWitnessTransferFrom struct used by the Permit2 contract.
type Permit2Authorization struct {
From string `json:"from"` // Signer/owner address (hex)
Permitted Permit2TokenPermissions `json:"permitted"` // Token and amount permitted
Spender string `json:"spender"` // Must be x402Permit2Proxy address
Nonce string `json:"nonce"` // uint256 nonce as decimal string (unique per signature)
Deadline string `json:"deadline"` // Unix timestamp as decimal string - signature expires after this
Witness Permit2Witness `json:"witness"` // Witness data verified by x402Permit2Proxy
}Fields
From string`json:"from"`Signer/owner address (hex)
Permitted Permit2TokenPermissions`json:"permitted"`Token and amount permitted
Spender string`json:"spender"`Must be x402Permit2Proxy address
Nonce string`json:"nonce"`uint256 nonce as decimal string (unique per signature)
Deadline string`json:"deadline"`Unix timestamp as decimal string - signature expires after this
Witness Permit2Witness`json:"witness"`Witness data verified by x402Permit2Proxy
type Permit2TokenPermissions
Source: mechanisms/evm/types.go:49
Permit2TokenPermissions represents the permitted token and amount for Permit2. This is part of the PermitWitnessTransferFrom message structure that gets signed.
type Permit2TokenPermissions struct {
Token string `json:"token"` // Token contract address (hex, e.g., "0x036CbD53842c5426634e7929541eC2318f3dCF7e")
Amount string `json:"amount"` // Amount in smallest unit as decimal string (e.g., "1000000" for 1 USDC)
}Fields
Token string`json:"token"`Token contract address (hex, e.g., "0x036CbD53842c5426634e7929541eC2318f3dCF7e")
Amount string`json:"amount"`Amount in smallest unit as decimal string (e.g., "1000000" for 1 USDC)
type Permit2Witness
Source: mechanisms/evm/types.go:57
Permit2Witness represents the witness data structure for x402Permit2Proxy.
The witness is included in the EIP-712 signature and verified on-chain by the proxy.
Note: Upper time bound is enforced by Permit2's deadline field, not a witness field.
type Permit2Witness struct {
To string `json:"to"` // Destination address for funds (hex)
ValidAfter string `json:"validAfter"` // Unix timestamp (decimal string) - payment invalid before this time
}Fields
To string`json:"to"`Destination address for funds (hex)
ValidAfter string`json:"validAfter"`Unix timestamp (decimal string) - payment invalid before this time
type RPCChainConfig
Source: mechanisms/evm/rpc.go:18
RPCChainConfig configures RPC behavior for a specific chain.
type RPCChainConfig struct {
RPCURL string
}Fields
RPCURL string
type RPCConfig
Source: mechanisms/evm/rpc.go:24
RPCConfig configures RPC behavior for EVM clients that need on-chain reads or fee estimation. Chain-specific entries in RPCByChainID take precedence over the top-level RPCURL.
type RPCConfig struct {
RPCURL string
RPCByChainID map[int64]RPCChainConfig
}Fields
RPCURL stringRPCByChainID map[int64]RPCChainConfig
type TransactionReceipt
Source: mechanisms/evm/types.go:292
TransactionReceipt represents the receipt of a mined transaction
type TransactionReceipt struct {
Status uint64 `json:"status"`
BlockNumber uint64 `json:"blockNumber"`
TxHash string `json:"transactionHash"`
Logs []*goethtypes.Log `json:"logs,omitempty"`
}Fields
Status uint64`json:"status"`BlockNumber uint64`json:"blockNumber"`TxHash string`json:"transactionHash"`Logs []*goethtypes.Log`json:"logs,omitempty"`
type TypedDataDomain
Source: mechanisms/evm/types.go:278
TypedDataDomain represents the EIP-712 domain separator
type TypedDataDomain struct {
Name string `json:"name"`
Version string `json:"version"`
ChainID *big.Int `json:"chainId"`
VerifyingContract string `json:"verifyingContract"`
}Fields
Name string`json:"name"`Version string`json:"version"`ChainID *big.Int`json:"chainId"`VerifyingContract string`json:"verifyingContract"`
type TypedDataField
Source: mechanisms/evm/types.go:286
TypedDataField represents a field in EIP-712 typed data
type TypedDataField struct {
Name string `json:"name"`
Type string `json:"type"`
}Fields
Name string`json:"name"`Type string`json:"type"`
type UptoPermit2Authorization
Source: mechanisms/evm/types.go:376
UptoPermit2Authorization represents the Permit2 authorization parameters for the upto scheme.
type UptoPermit2Authorization struct {
From string `json:"from"` // Signer/owner address (hex)
Permitted Permit2TokenPermissions `json:"permitted"` // Token and amount permitted (max charge)
Spender string `json:"spender"` // Must be x402UptoPermit2Proxy address
Nonce string `json:"nonce"` // uint256 nonce as decimal string
Deadline string `json:"deadline"` // Unix timestamp as decimal string
Witness UptoPermit2Witness `json:"witness"` // Witness data including facilitator
}Fields
From string`json:"from"`Signer/owner address (hex)
Permitted Permit2TokenPermissions`json:"permitted"`Token and amount permitted (max charge)
Spender string`json:"spender"`Must be x402UptoPermit2Proxy address
Nonce string`json:"nonce"`uint256 nonce as decimal string
Deadline string`json:"deadline"`Unix timestamp as decimal string
Witness UptoPermit2Witness`json:"witness"`Witness data including facilitator
type UptoPermit2Payload
Source: mechanisms/evm/types.go:386
UptoPermit2Payload represents the upto Permit2 payment payload sent by clients.
type UptoPermit2Payload struct {
Signature string `json:"signature"` // EIP-712 signature (hex)
Permit2Authorization UptoPermit2Authorization `json:"permit2Authorization"` // Authorization parameters
}Fields
Signature string`json:"signature"`EIP-712 signature (hex)
Permit2Authorization UptoPermit2Authorization`json:"permit2Authorization"`Authorization parameters
func ToMap() map[string]interface{}
Source: mechanisms/evm/types.go:392
ToMap converts an UptoPermit2Payload to a map for JSON marshaling.
type UptoPermit2Witness
Source: mechanisms/evm/types.go:369
UptoPermit2Witness represents the witness data for x402UptoPermit2Proxy. Differs from Permit2Witness by including a Facilitator address field. Only the address matching Facilitator can call settle() on-chain.
type UptoPermit2Witness struct {
To string `json:"to"` // Destination address for funds (hex)
Facilitator string `json:"facilitator"` // Facilitator address authorized to settle (hex)
ValidAfter string `json:"validAfter"` // Unix timestamp (decimal string)
}Fields
To string`json:"to"`Destination address for funds (hex)
Facilitator string`json:"facilitator"`Facilitator address authorized to settle (hex)
ValidAfter string`json:"validAfter"`Unix timestamp (decimal string)
