mechanisms/evm/exact/facilitator
import "github.com/x402-foundation/x402/go/v2/mechanisms/evm/exact/facilitator"
Constants
Facilitator error constants for the exact EVM scheme
Source: mechanisms/evm/exact/facilitator/errors.go:8
const (
// EIP-3009 Verify errors
ErrInvalidScheme = "invalid_exact_evm_scheme"
ErrNetworkMismatch = "invalid_exact_evm_network_mismatch"
ErrInvalidPayload = "invalid_exact_evm_payload"
ErrMissingSignature = "invalid_exact_evm_payload_missing_signature"
ErrFailedToGetNetworkConfig = "invalid_exact_evm_failed_to_get_network_config"
ErrMissingEip712Domain = "invalid_exact_evm_missing_eip712_domain"
ErrRecipientMismatch = "invalid_exact_evm_recipient_mismatch"
ErrInvalidAuthorizationValue = "invalid_exact_evm_authorization_value"
ErrInvalidRequiredAmount = "invalid_exact_evm_required_amount"
ErrAuthorizationValueMismatch = "invalid_exact_evm_payload_authorization_value_mismatch"
ErrFailedToCheckNonce = "invalid_exact_evm_failed_to_check_nonce"
ErrNonceAlreadyUsed = "invalid_exact_evm_nonce_already_used"
ErrFailedToGetBalance = "invalid_exact_evm_failed_to_get_balance"
ErrInsufficientBalance = "invalid_exact_evm_insufficient_balance"
ErrInvalidSignatureFormat = "invalid_exact_evm_signature_format"
ErrFailedToVerifySignature = "invalid_exact_evm_failed_to_verify_signature"
ErrInvalidSignature = "invalid_exact_evm_signature"
ErrValidBeforeExpired = "invalid_exact_evm_payload_authorization_valid_before"
ErrValidAfterInFuture = "invalid_exact_evm_payload_authorization_valid_after"
ErrEip3009TokenNameMismatch = "invalid_exact_evm_token_name_mismatch"
ErrEip3009TokenVersionMismatch = "invalid_exact_evm_token_version_mismatch"
ErrEip3009NotSupported = "invalid_exact_evm_eip3009_not_supported"
ErrEip3009SimulationFailed = "invalid_exact_evm_transaction_simulation_failed"
// EIP-3009 Settle errors
ErrVerificationFailed = "invalid_exact_evm_verification_failed"
ErrFailedToParseSignature = "invalid_exact_evm_failed_to_parse_signature"
ErrFailedToCheckDeployment = "invalid_exact_evm_failed_to_check_deployment"
ErrFailedToExecuteTransfer = "invalid_exact_evm_failed_to_execute_transfer"
ErrFailedToGetReceipt = "invalid_exact_evm_failed_to_get_receipt"
ErrTransactionFailed = "invalid_exact_evm_transaction_failed"
ErrTransferEventMismatch = "invalid_exact_evm_transfer_event_mismatch"
// Smart wallet errors (shared by EIP-3009 and Permit2)
ErrUndeployedSmartWallet = "invalid_exact_evm_payload_undeployed_smart_wallet"
ErrSmartWalletDeploymentFailed = "smart_wallet_deployment_failed"
ErrFactoryNotAllowed = "eip6492_factory_not_allowed"
ErrUnsupportedPayloadType = "unsupported_payload_type"
// Permit2 verify errors - canonical values live in evm.ErrPermit2*
ErrPermit2InvalidSpender = evm.ErrPermit2InvalidSpender
ErrPermit2RecipientMismatch = evm.ErrPermit2RecipientMismatch
ErrPermit2DeadlineExpired = evm.ErrPermit2DeadlineExpired
ErrPermit2NotYetValid = evm.ErrPermit2NotYetValid
ErrPermit2AmountMismatch = evm.ErrPermit2AmountMismatch
ErrPermit2TokenMismatch = evm.ErrPermit2TokenMismatch
ErrPermit2InvalidSignature = evm.ErrPermit2InvalidSignature
ErrPermit2AllowanceRequired = evm.ErrPermit2AllowanceRequired
// Permit2 settle errors (from contract reverts)
ErrPermit2InvalidAmount = evm.ErrPermit2InvalidAmount
ErrPermit2InvalidDestination = evm.ErrPermit2InvalidDestination
ErrPermit2InvalidOwner = evm.ErrPermit2InvalidOwner
ErrPermit2PaymentTooEarly = evm.ErrPermit2PaymentTooEarly
ErrPermit2InvalidNonce = evm.ErrPermit2InvalidNonce
ErrPermit2612AmountMismatch = evm.ErrPermit2612AmountMismatch
// Permit2 simulation errors
ErrPermit2SimulationFailed = evm.ErrPermit2SimulationFailed
ErrPermit2InsufficientBalance = evm.ErrPermit2InsufficientBalance
ErrPermit2ProxyNotDeployed = evm.ErrPermit2ProxyNotDeployed
ErrErc20ApprovalTxFailed = "erc20_approval_tx_failed"
// ERC-20 approval gas sponsoring errors
ErrErc20ApprovalInsufficientEth = evm.ErrErc20ApprovalInsufficientEth
ErrErc20ApprovalInvalidFormat = "invalid_erc20_approval_extension_format"
ErrErc20ApprovalFromMismatch = "erc20_approval_from_mismatch"
ErrErc20ApprovalAssetMismatch = "erc20_approval_asset_mismatch"
ErrErc20ApprovalWrongSpender = "erc20_approval_spender_not_permit2"
ErrErc20ApprovalTxParseFailed = "erc20_approval_tx_parse_failed"
ErrErc20ApprovalWrongTarget = "erc20_approval_tx_wrong_target"
ErrErc20ApprovalWrongSelector = "erc20_approval_tx_wrong_selector"
ErrErc20ApprovalWrongCalldata = "erc20_approval_tx_wrong_spender"
ErrErc20ApprovalSignerMismatch = "erc20_approval_tx_signer_mismatch"
ErrErc20ApprovalInvalidSig = "erc20_approval_tx_invalid_signature"
ErrErc20ApprovalBroadcastFailed = evm.ErrErc20ApprovalBroadcastFailed
)Functions
func BuildPermit2SettleArgs(permit2Payload *evm.ExactPermit2Payload) (*Permit2SettleArgs, error)
Source: mechanisms/evm/exact/facilitator/permit2_helpers.go:33
BuildPermit2SettleArgs converts a raw ExactPermit2Payload into typed contract-call arguments, deduplicating the struct construction shared by verify simulation and settle.
func CheckPermit2Prerequisites( ctx context.Context, signer evm.FacilitatorEvmSigner, tokenAddress string, payer string, amountRequired string, ) *x402.VerifyResponse
Source: mechanisms/evm/exact/facilitator/permit2_helpers.go:223
CheckPermit2Prerequisites checks proxy deployment and payer token balance.
func ClassifyEIP3009Signature( ctx context.Context, signer evm.FacilitatorEvmSigner, authorization evm.ExactEIP3009Authorization, signature []byte, chainID *big.Int, tokenAddress string, tokenName string, tokenVersion string, ) (*EIP3009SignatureClassification, error)
Source: mechanisms/evm/exact/facilitator/eip3009_helpers.go:124
ClassifyEIP3009Signature checks the signature directly when possible, while preserving smart-wallet signatures for simulation-first verification.
func DiagnoseEIP3009SimulationFailure( ctx context.Context, signer evm.FacilitatorEvmSigner, tokenAddress string, authorization evm.ExactEIP3009Authorization, requiredAmount *big.Int, tokenName string, tokenVersion string, ) string
Source: mechanisms/evm/exact/facilitator/eip3009_helpers.go:281
DiagnoseEIP3009SimulationFailure resolves a failed simulation into the most specific error.
func DiagnosePermit2SimulationFailure( ctx context.Context, signer evm.FacilitatorEvmSigner, tokenAddress string, permit2Payload *evm.ExactPermit2Payload, amountRequired string, ) *x402.VerifyResponse
Source: mechanisms/evm/exact/facilitator/permit2_helpers.go:166
DiagnosePermit2SimulationFailure runs a multicall diagnostic to return the most specific error reason after a simulation failure.
func ExecuteTransferWithAuthorization( ctx context.Context, signer evm.FacilitatorEvmSigner, tokenAddress string, parsed *ParsedEIP3009Authorization, sigData *evm.ERC6492SignatureData, dataSuffix []byte, ) (string, error)
Source: mechanisms/evm/exact/facilitator/eip3009_helpers.go:352
ExecuteTransferWithAuthorization executes the actual transfer onchain.
func HasEIP6492Deployment(sigData *evm.ERC6492SignatureData) bool
Source: mechanisms/evm/exact/facilitator/eip3009_helpers.go:476
func NewExactEvmScheme(signer evm.FacilitatorEvmSigner, config *ExactEvmSchemeConfig) *ExactEvmScheme
Source: mechanisms/evm/exact/facilitator/scheme.go:40
NewExactEvmScheme creates a new ExactEvmScheme Args:
signer: The EVM signer for facilitator operations
config: Optional configuration (nil uses defaults)Returns:
Configured ExactEvmScheme instancefunc ParseEIP3009Authorization( authorization evm.ExactEIP3009Authorization, ) (*ParsedEIP3009Authorization, error)
Source: mechanisms/evm/exact/facilitator/eip3009_helpers.go:83
ParseEIP3009Authorization parses authorization fields into contract-call arguments.
func SendDeployTransaction( ctx context.Context, signer evm.FacilitatorEvmSigner, sigData *evm.ERC6492SignatureData, ) error
Source: mechanisms/evm/exact/facilitator/eip3009_helpers.go:402
SendDeployTransaction submits the ERC-6492 factory deployment transaction and waits for the receipt, returning an error if the deployment transaction reverted.
func SettlePermit2( ctx context.Context, signer evm.FacilitatorEvmSigner, payload types.PaymentPayload, requirements types.PaymentRequirements, permit2Payload *evm.ExactPermit2Payload, facilCtx *x402.FacilitatorContext, config *Permit2FacilitatorConfig, ) (*x402.SettleResponse, error)
Source: mechanisms/evm/exact/facilitator/permit2.go:212
SettlePermit2 settles a Permit2 payment by calling x402ExactPermit2Proxy.settle().
func SimulateEIP3009Transfer( ctx context.Context, signer evm.FacilitatorEvmSigner, tokenAddress string, parsed *ParsedEIP3009Authorization, sigData *evm.ERC6492SignatureData, ) (bool, error)
Source: mechanisms/evm/exact/facilitator/eip3009_helpers.go:199
SimulateEIP3009Transfer runs the transfer via eth_call.
func SimulatePermit2Settle( ctx context.Context, signer evm.FacilitatorEvmSigner, permit2Payload *evm.ExactPermit2Payload, ) (bool, error)
Source: mechanisms/evm/exact/facilitator/permit2_helpers.go:73
SimulatePermit2Settle runs settle() via eth_call (ReadContract). Returns true if the simulation succeeded.
func SimulatePermit2SettleWithPermit( ctx context.Context, signer evm.FacilitatorEvmSigner, permit2Payload *evm.ExactPermit2Payload, eip2612Signature, eip2612Amount, eip2612DeadlineStr string, ) (bool, error)
Source: mechanisms/evm/exact/facilitator/permit2_helpers.go:105
SimulatePermit2SettleWithPermit runs settleWithPermit() via eth_call. The contract atomically calls token.permit() then PERMIT2.permitTransferFrom(), so simulation covers allowance + balance + nonces.
func ValidateErc20ApprovalForPayment(info *erc20approvalgassponsor.Info, payer, tokenAddress string) (reason, message string)
Source: mechanisms/evm/exact/facilitator/erc20_approval.go:22
ValidateErc20ApprovalForPayment validates the ERC-20 approval extension data. Returns ("", "") if valid, or (reason, message) on failure where reason is the error constant and message is a human-readable contextual description.
func VerifyPermit2( ctx context.Context, signer evm.FacilitatorEvmSigner, payload types.PaymentPayload, requirements types.PaymentRequirements, permit2Payload *evm.ExactPermit2Payload, facilCtx *x402.FacilitatorContext, opts *VerifyPermit2Options, ) (*x402.VerifyResponse, error)
Source: mechanisms/evm/exact/facilitator/permit2.go:32
VerifyPermit2 verifies a Permit2 payment payload.
Types
type EIP3009SignatureClassification
Source: mechanisms/evm/exact/facilitator/eip3009_helpers.go:27
EIP3009SignatureClassification captures how the signature should be treated.
type EIP3009SignatureClassification struct {
Valid bool
IsSmartWallet bool
IsUndeployed bool
SigData *evm.ERC6492SignatureData
}Fields
Valid boolIsSmartWallet boolIsUndeployed boolSigData *evm.ERC6492SignatureData
type ExactEvmScheme
Source: mechanisms/evm/exact/facilitator/scheme.go:26
ExactEvmScheme implements the SchemeNetworkFacilitator interface for EVM exact payments (V2)
type ExactEvmScheme struct {
// contains filtered or unexported fields
}func CaipFamily() string
Source: mechanisms/evm/exact/facilitator/scheme.go:57
CaipFamily returns the CAIP family pattern this facilitator supports
func GetExtra(_ x402.Network) map[string]interface{}
Source: mechanisms/evm/exact/facilitator/scheme.go:63
GetExtra returns mechanism-specific extra data for the supported kinds endpoint. For EVM, no extra data is needed.
func GetSigners(_ x402.Network) []string
Source: mechanisms/evm/exact/facilitator/scheme.go:69
GetSigners returns signer addresses used by this facilitator. Returns all addresses this facilitator can use for signing/settling transactions.
func Scheme) Scheme() string
Source: mechanisms/evm/exact/facilitator/scheme.go:52
Scheme returns the scheme identifier
func Settle( ctx context.Context, payload types.PaymentPayload, requirements types.PaymentRequirements, fctx *x402.FacilitatorContext, ) (*x402.SettleResponse, error)
Source: mechanisms/evm/exact/facilitator/scheme.go:96
Settle settles a V2 payment on-chain. Routes to EIP-3009 or Permit2 settlement based on payload type.
func Verify( ctx context.Context, payload types.PaymentPayload, requirements types.PaymentRequirements, fctx *x402.FacilitatorContext, ) (*x402.VerifyResponse, error)
Source: mechanisms/evm/exact/facilitator/scheme.go:75
Verify verifies a V2 payment payload against requirements. Routes to EIP-3009 or Permit2 verification based on payload type.
type ExactEvmSchemeConfig
Source: mechanisms/evm/exact/facilitator/scheme.go:13
ExactEvmSchemeConfig holds configuration for the ExactEvmScheme facilitator
type ExactEvmSchemeConfig struct {
// EIP6492AllowedFactories is the allowlist of factory contract addresses (hex strings,
// case-insensitive) that the facilitator will call when deploying an undeployed smart wallet
// via ERC-6492. A non-empty list enables ERC-4337 smart wallet deployment. An empty list
// (the default) denies all factory deployment calls. Facilitators must explicitly list every
// factory they trust to prevent arbitrary transaction injection via attacker-controlled
// ERC-6492 signature wrappers.
EIP6492AllowedFactories []string
// SimulateInSettle reruns transfer simulation during settle. Verify always simulates.
SimulateInSettle bool
}Fields
EIP6492AllowedFactories []stringEIP6492AllowedFactories is the allowlist of factory contract addresses (hex strings, case-insensitive) that the facilitator will call when deploying an undeployed smart wallet via ERC-6492. A non-empty list enables ERC-4337 smart wallet deployment. An empty list (the default) denies all factory deployment calls. Facilitators must explicitly list every factory they trust to prevent arbitrary transaction injection via attacker-controlled ERC-6492 signature wrappers.
SimulateInSettle boolSimulateInSettle reruns transfer simulation during settle. Verify always simulates.
type ParsedEIP3009Authorization
Source: mechanisms/evm/exact/facilitator/eip3009_helpers.go:17
ParsedEIP3009Authorization contains the parsed transfer arguments used by verify and settle.
type ParsedEIP3009Authorization struct {
From common.Address
To common.Address
Value *big.Int
ValidAfter *big.Int
ValidBefore *big.Int
Nonce [32]byte
}Fields
From common.AddressTo common.AddressValue *big.IntValidAfter *big.IntValidBefore *big.IntNonce [32]byte
type Permit2FacilitatorConfig
Source: mechanisms/evm/exact/facilitator/permit2.go:205
Permit2FacilitatorConfig holds optional settlement-time configuration.
type Permit2FacilitatorConfig struct {
// SimulateInSettle re-runs simulation during settle
// When false (default), the settle path skips simulation since verify already ran it
SimulateInSettle bool
}Fields
SimulateInSettle boolSimulateInSettle re-runs simulation during settle When false (default), the settle path skips simulation since verify already ran it
type Permit2SettleArgs
Source: mechanisms/evm/exact/facilitator/permit2_helpers.go:14
Permit2SettleArgs holds the parsed and typed arguments for settle() / settleWithPermit().
type Permit2SettleArgs struct {
Permit struct {
Permitted struct {
Token common.Address
Amount *big.Int
}
Nonce *big.Int
Deadline *big.Int
}
Owner common.Address
Witness struct {
To common.Address
ValidAfter *big.Int
}
Signature []byte
}Fields
Permit struct { Permitted struct { Token common.Address Amount *big.Int } Nonce *big.Int Deadline *big.Int }Owner common.AddressWitness struct { To common.Address ValidAfter *big.Int }Signature []byte
type VerifyPermit2Options
Source: mechanisms/evm/exact/facilitator/permit2.go:19
VerifyPermit2Options controls optional behaviour for VerifyPermit2.
type VerifyPermit2Options struct {
// Simulate enables onchain simulation. Defaults to true when zero-value.
Simulate *bool
}Fields
Simulate *boolSimulate enables onchain simulation. Defaults to true when zero-value.
