MPP.Methods.EVM.Authorization (mpp v0.19.0)

Copy Markdown View Source

EIP-3009 transferWithAuthorization credential for Circle USDC/EURC.

The client signs an off-chain EIP-712 TransferWithAuthorization message. The server submits it to the token contract and pays gas. The EIP-3009 nonce for native Payment-auth is the challengeHash:

keccak256(challenge.id <> challenge.realm)

matching draft-evm-charge-00.md § Authorization Payload and refs/mppx/src/evm/Types.ts challengeHash. settle/2 enforces that contract. settle/3 accepts :expected_nonce for a caller such as MPP.Methods.USDC whose profile binds a different nonce. Circle FiatTokenV2 enforces nonce uniqueness on-chain (authorizationState).

Summary

Functions

Compute the EIP-3009 nonce: keccak256(challenge.id <> challenge.realm).

Return the native Payment-auth EIP-3009 nonce contract.

Return true when this charge can advertise and settle type=authorization.

Parse and validate a type=authorization credential payload.

Recover the EIP-3009 signer for an authorization payload.

Validate, recover, and settle an EIP-3009 authorization; return the tx hash.

Sign an EIP-3009 TransferWithAuthorization with a caller-supplied nonce.

Validate optional "authorization" method_config (name + version).

Types

parsed()

@type parsed() :: %{
  from: String.t(),
  to: String.t(),
  value: String.t(),
  valid_after: non_neg_integer(),
  valid_before: non_neg_integer(),
  nonce: String.t(),
  signature: String.t()
}

Functions

challenge_hash(id, realm)

@spec challenge_hash(String.t(), String.t()) :: String.t()

Compute the EIP-3009 nonce: keccak256(challenge.id <> challenge.realm).

nonce_contract()

@spec nonce_contract() :: :challenge_hash

Return the native Payment-auth EIP-3009 nonce contract.

Native credentials bind nonce to challenge_hash/2. x402 exact uses a different contract (MPP.X402.Nonce) and must not pass through settle/2.

offered?(charge)

@spec offered?(MPP.Intents.Charge.t()) :: boolean()

Return true when this charge can advertise and settle type=authorization.

parse_payload(payload)

@spec parse_payload(map()) :: {:ok, parsed()} | {:error, MPP.Errors.t()}

Parse and validate a type=authorization credential payload.

recover_authorization(parsed, currency, chain_id, name, version)

@spec recover_authorization(
  parsed(),
  String.t(),
  pos_integer(),
  String.t(),
  String.t()
) ::
  {:ok, String.t()} | {:error, MPP.Errors.t()}

Recover the EIP-3009 signer for an authorization payload.

Shared by native settle/2 verification and x402 exact local checks. Does not apply a nonce contract.

settle(payload, charge, opts \\ [])

@spec settle(map(), MPP.Intents.Charge.t(), keyword()) ::
  {:ok, String.t()} | {:error, MPP.Errors.t()}

Validate, recover, and settle an EIP-3009 authorization; return the tx hash.

Pass expected_nonce: nonce in opts to replace the native challengeHash check. The caller must supply the nonce its own profile requires.

sign_transfer(params, private_key)

@spec sign_transfer(map(), String.t()) :: {:ok, String.t()} | {:error, MPP.Errors.t()}

Sign an EIP-3009 TransferWithAuthorization with a caller-supplied nonce.

This is the shared Task 40 primitive. Native Payment-auth callers pass challenge_hash/2; x402 exact callers pass a random or extension-bound nonce. This function does not enforce either contract — settle/2 enforces the native challengeHash rule, and MPP.X402 enforces the x402 rule.

validate_config!(other)

@spec validate_config!(term()) :: :ok

Validate optional "authorization" method_config (name + version).