Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.mrdn.finance/llms.txt

Use this file to discover all available pages before exploring further.

The Nanopayments Gateway is Meridian’s integration of Circle Gateway nanopayments. The buyer funds a unified USDC balance once on any supported chain, then makes many gas-free, sub-cent ($0.000001 minimum) payments that Circle batches into a single onchain settlement. Each individual x402 payment is verified instantly by signature, while Circle’s Gateway System aggregates the signed authorizations and settles net positions in bulk. The Meridian facilitator wraps Circle’s @circle-fin/x402-batching/server SDK and exposes it through the standard /v1/verify and /v1/settle endpoints.

Nanopayments Gateway UI

Deposit and withdraw USDC against the Gateway Wallet contract from a hosted UI.

Endpoints

Settle Batched Payment

POST /v1/settle settles a batched payment via Circle Gateway.

Verify Batched Payment

POST /v1/verify verifies a batched payment without settling.

Gateway Status

GET /v1/batched-sample reports Gateway connectivity for diagnostics.
The buyer never submits an on-chain transaction at payment time. Funds move from their pre-funded Gateway Wallet balance through Circle’s batched settlement. Withdrawals from the Gateway Wallet are subject to a 7-day delay enforced by the Gateway Wallet contract.

Detection

A payment is routed through the Nanopayments Gateway when both of these are present in paymentRequirements.extra:
{
  "extra": {
    "name": "GatewayWalletBatched",
    "version": "1"
  }
}
This check is performed by isBatchPayment() from @circle-fin/x402-batching/server inside the facilitator’s /v1/verify and /v1/settle handlers. There are no separate URLs for batched flows. Clients call the same endpoints used for default x402 settlement, and the facilitator inspects extra to decide where to forward the request.

Supported networks

isGatewayEnabledForNetwork() returns true for every network listed below. Testnets are always enabled, and mainnets are gated by the GATEWAY_MAINNET_ENABLED flag in the facilitator (currently true). The Meridian facilitator will accept requests for these networks and forward them to Circle.
Three networks listed in the facilitator’s CAIP-2 map are not currently supported by Circle’s Gateway API for nanopayments: ink, megaeth, and fluent-testnet. The facilitator will forward the request, but Circle will reject it. See Circle’s Gateway Supported Blockchains for the authoritative list (column Nanopayments: Yes). Networks marked with [!] below are configured locally but not yet supported by Circle.

Testnets

NetworkCAIP-2 chain IDCircle domainGateway WalletUSDC
base-sepoliaeip155:8453260x0077777d7EBA4688BDeF3E311b846F25870A19B90x036CbD53842c5426634e7929541eC2318f3dCF7e
optimism-sepoliaeip155:1115542020x0077777d7EBA4688BDeF3E311b846F25870A19B90x5fd84259d66Cd46123540766Be93DFE6D43130D7
fluent-testnet [!]eip155:20994n/a0x0077777d7EBA4688BDeF3E311b846F25870A19B9n/a

Mainnets

NetworkCAIP-2 chain IDCircle domainGateway WalletUSDC
ethereumeip155:100x77777777Dcc4d5A8B6E418Fd04D8997ef11000eE0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
baseeip155:845360x77777777Dcc4d5A8B6E418Fd04D8997ef11000eE0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
optimismeip155:1020x77777777Dcc4d5A8B6E418Fd04D8997ef11000eE0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85
arbitrumeip155:4216130x77777777Dcc4d5A8B6E418Fd04D8997ef11000eE0xaf88d065e77c8cC2239327C5EDb3A432268e5831
avalancheeip155:4311410x77777777Dcc4d5A8B6E418Fd04D8997ef11000eE0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E
polygoneip155:13770x77777777Dcc4d5A8B6E418Fd04D8997ef11000eE0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359
unichaineip155:130100x77777777Dcc4d5A8B6E418Fd04D8997ef11000eE0x078d782b760474a361dda0af3839290b0ef57ad6
ink [!]eip155:57073n/a0x77777777Dcc4d5A8B6E418Fd04D8997ef11000eE0x2D270e6886d130D724215A266106e6832161EAEd
soniceip155:146130x77777777Dcc4d5A8B6E418Fd04D8997ef11000eE0x29219dd400f2Bf60E5a23d13Be72B486D4038894
worldchaineip155:480140x77777777Dcc4d5A8B6E418Fd04D8997ef11000eE0x79A02482A880bCe3F13E09da970dC34dB4cD24D1
seieip155:1329160x77777777Dcc4d5A8B6E418Fd04D8997ef11000eE0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392
hyperevmeip155:999190x77777777Dcc4d5A8B6E418Fd04D8997ef11000eE0xb88339CB7199b77E23DB6E890353E22632Ba630f
megaeth [!]eip155:4326n/a0x77777777Dcc4d5A8B6E418Fd04D8997ef11000eEn/a
The Gateway Wallet addresses are deployed by Circle at the same address on every supported EVM chain (verified against Circle’s contract addresses page). The facilitator forwards batched requests to:
  • Testnet: https://gateway-api-testnet.circle.com (explicit URL passed to BatchFacilitatorClient).
  • Mainnet: the default URL baked into @circle-fin/x402-batching/server. The facilitator constructs new BatchFacilitatorClient() with no url override.
Both clients are lazy-initialized singletons.

Funding the Gateway Wallet

Buyers fund the Gateway Wallet contract on each source chain they want to spend from. Available balance is unified across deposits, so a single signed payment can be settled from any chain that has been funded.

Deposit flow

  1. USDC.approve(gatewayWallet, value). One-time per source chain.
  2. GatewayWallet.deposit(usdcAddress, value). Pulls USDC and credits the depositor’s balance. Circle also exposes depositFor, depositWithPermit, and depositWithAuthorization on the wallet contract.
  3. After the deposit transaction is finalized onchain, the credit becomes part of availableBalance and can be spent. Time-to-finality is chain-specific:
    Chain familyConfirmationsApprox. time
    Ethereum, Arbitrum, Base, OP, Unichain, World Chain~65 ETH blocks~13 – 19 minutes
    Avalanche, Sonic~1~8 seconds
    HyperEVM, Sei~1~5 seconds
    Polygon PoS~2 – 3~8 seconds
    Source: Circle’s Required block confirmations table.
Sending USDC to the Gateway Wallet via a plain ERC-20 transfer instead of one of the deposit methods will result in loss of funds. Always call a deposit* method on the wallet contract.

Withdrawal flow

Circle’s Gateway Wallet supports two withdrawal paths:
  • Instant (preferred): submit a same-chain transfer through the Gateway API. Funds round-trip through a burn on the source chain and a mint on the destination (same chain), so the withdrawal still requires a user-signed authorization. Pays only burn-tx gas.
  • Trustless (fallback for when Circle’s API is unavailable): on-chain only, with a 7-day delay enforced by the withdrawalBlock value on the Gateway Wallet contract.
The hosted Nanopayments Gateway UI currently exposes the trustless path:
  1. GatewayWallet.initiateWithdrawal(usdc, value). Moves balance from availableBalance to withdrawingBalance and records withdrawalBlock.
  2. After block.number >= withdrawalBlock, call GatewayWallet.withdraw(usdc). Moves the unlocked amount from withdrawableBalance back to the buyer’s wallet.
Source: Circle’s Withdrawal documentation.

Balance views

The Gateway Wallet exposes per-token, per-depositor views the SDK reads:
ViewMeaning
availableBalanceSpendable balance for nanopayments
withdrawingBalanceAmount in the 7-day delay window
withdrawableBalanceAmount past the delay, ready to claim
totalBalanceavailable + withdrawing + withdrawable
withdrawalBlockBlock at which a pending withdrawal becomes withdrawable
isTokenSupportedtrue if the Gateway Wallet accepts deposits of this token
The hosted Nanopayments Gateway UI wraps these calls so end users do not have to call the contract directly.

extra field reference

In the Nanopayments Gateway path, only extra.name and extra.version are read by the Meridian facilitator. They are the routing trigger that isBatchPayment() checks. Everything else inside extra is passed through to Circle’s Gateway API verbatim by transformForGateway(), which spreads paymentRequirements and overrides network, asset, and amount only.
FieldRequiredRead by Meridian?Description
nameRouting onlyMust be the literal string "GatewayWalletBatched". Together with version, it is the trigger for isBatchPayment().
versionRouting onlyMust be the literal string "1".
verifyingContractNo (pass-through)Gateway Wallet contract address used by the client SDK as the EIP-712 verifyingContract when signing.
creditedRecipientNo (pass-through)Forwarded to Circle. Note: in the default x402 path Meridian reads this field, but the batched path returns before that code runs.
platformNo (pass-through)Forwarded to Circle. The platform / platformFeeBps settlement logic in the facilitator is not executed in the batched path.
platformFeeBpsNo (pass-through)Forwarded to Circle. Gateway batched payments do not currently charge a Meridian platform fee.
destinationChainIdNo (pass-through)Forwarded to Circle.
The buyer-side SDK sets paymentRequirements.asset to the Gateway Wallet contract so the EIP-712 domain has the correct verifyingContract. transformForGateway() swaps that back to the network’s USDC address (from NETWORK_USDC) before forwarding to Circle, since Circle expects the actual token address.

Implementation notes

  • The facilitator-side glue lives in apps/facilitator/src/gateway/index.ts. It owns the testnet/mainnet client routing, the Gateway Wallet ↔ USDC asset swap, and the CAIP-2 network mapping that Circle’s API requires.
  • The deposit/withdraw UI lives in apps/circle-gateway and is also hosted at nanopayments.mrdn.finance.
  • Circle recommends calling settle() directly for production batched flows rather than the legacy verify() + settle() two-step.

See also

Meridian

Circle (authoritative source for the upstream API and contracts)