Skip to main content
x402Escrow API Contract: x402Escrow
Solidity: v0.8.22+
License: MIT
Inheritance: Initializable, UUPSUpgradeable, Ownable2StepUpgradeable, AccessControlUpgradeable, ReentrancyGuard

Constants

State Variables

Types

Escrow (Internal Storage)

Packed into a single 32-byte storage slot.

EscrowView (Returned by getEscrow)

Full-width types for off-chain consumption.

Functions

initialize

Initializes the proxy. Can only be called once. Parameters Reverts
  • ZeroAddress() — if any parameter is address(0).
  • NotContract() — if _usdc has no code.

settle

Locks USDC in escrow using the client’s EIP-3009 signed authorization. Parameters Returns Reverts
  • InvalidAmount() — if maxAmount is zero or exceeds type(uint56).max.
  • NotYetValid() — if block.timestamp < validAfter.
  • TimeoutExpired() — if block.timestamp >= validBefore.
  • EscrowAlreadyExists() — if an active escrow with this ID already exists.
  • TransferMismatch() — if the actual USDC received differs from maxAmount.
Emits
  • Deposited(escrowId, client, maxAmount)

release

Settles an active escrow. Pays the facilitator and refunds the remainder to the client. Parameters Behavior
  • Payment goes to msg.sender (the calling facilitator), not a stored address.
  • If facilitatorAmount == 0, the full amount returns to the client.
  • If facilitatorAmount == escrow.amount, nothing returns to the client.
  • Escrow storage is cleared before transfers.
Reverts
  • EscrowNotFound() — if the escrow does not exist or was already settled/refunded.
  • InvalidAmount() — if facilitatorAmount > escrow.amount.
Emits
  • Released(escrowId, msg.sender, facilitatorAmount, clientRefund)

refundAfterTimeout

Refunds the full escrowed amount to the client after the timeout has passed. Permissionless — callable by any address. Parameters Behavior
  • The full amount transfers to the stored client address regardless of who calls this function.
  • Escrow storage is cleared before the transfer.
Reverts
  • EscrowNotFound() — if the escrow does not exist.
  • TimeoutNotReached() — if block.timestamp < escrow.refundAt.
Emits
  • Refunded(escrowId, client, amount)

setTimeout

Updates the default timeout for new escrows. Does not affect existing escrows. Parameters Reverts
  • InvalidTimeout() — if outside the valid range.
Emits
  • TimeoutUpdated(_timeoutSecs)

getEscrow

Returns the current state of an escrow. Parameters Returns: EscrowView with:
  • client — depositor address (zero if the escrow doesn’t exist).
  • amount — USDC locked.
  • refundAt — timestamp when refund becomes available.
  • canRefundtrue if refundAfterTimeout() can be called now.
  • timeUntilRefund — seconds remaining until refund is available (0 if eligible).

Events

Deposited

Emitted when USDC is locked via settle().

Released

Emitted when an escrow is settled via release().

Refunded

Emitted when an escrow is refunded via refundAfterTimeout().

TimeoutUpdated

Emitted when the admin changes the default timeout via setTimeout().

Errors