Circle Nanopayments Explained: Gas-Free USDC Payments Down to $0.000001

Photo of Thomas CosiallsThomas Cosialls

Blockchains have a floor price. Every onchain transfer pays gas, so a payment smaller than its own gas cost makes no economic sense: on most networks, anything under a cent is dead on arrival. That floor is exactly where the next wave of commerce wants to live. AI agents do not buy like humans; they pay per API call, per second of compute, per dataset read, and each of those events is worth a fraction of a cent.

Circle Nanopayments removes the floor. Payments are signed off-chain at zero gas cost, verified in milliseconds, and settled onchain in batches of thousands, so a single transaction's gas is split across every payment inside it. The result: USDC payments down to $0.000001, gas-free for both buyer and seller, live on mainnet across 12 EVM chains.

In this article we will unpack how it works, compare it to the standard x402 flow we covered in our previous x402 tutorial, and then build the whole loop in Node.js: an Express API priced at $0.0001 per request, and a buyer client that deposits once and pays per call with nothing but signatures.

What is Circle Nanopayments?

Nanopayments is a payment rail built by Circle on top of two existing pieces:

  • Circle Gateway, Circle's unified USDC balance. You deposit USDC into a non-custodial Gateway Wallet contract on any supported chain, and that deposit becomes a single crosschain balance you can spend or withdraw on any other supported chain in under 500 ms.
  • The x402 protocol, the open standard that puts the HTTP 402 Payment Required status code to work: servers advertise a price in a machine-readable way, and clients pay it with a signed stablecoin authorization.

Nanopayments combines the two: buyers spend their Gateway balance through x402-style signed authorizations, and Circle Gateway acts as the facilitator that verifies each payment instantly and settles them onchain in bulk. Circle launched it on mainnet in April 2026 as part of its Agent Stack, with early adopters including Alchemy, QuickNode, Goldsky and blockrun.ai, and support across Ethereum, Base, Arbitrum, OP Mainnet, Polygon PoS, Avalanche, Unichain, Sonic, World Chain, Sei, HyperEVM and Arc.

The economics: why batching changes everything

The core insight is simple. If every payment is its own onchain transaction, every payment pays full gas, and the smallest viable payment is roughly $0.01 even on cheap L2s. If ten thousand payments share one settlement transaction, the gas per payment is divided by ten thousand, and a $0.000001 payment suddenly carries negligible overhead.

Per-payment settlement vs batched settlement: five individual transactions each paying gas, versus thousands of payments netted by Circle Gateway into a single onchain transaction
Batching amortizes one transaction's gas across every payment inside it, moving the minimum viable payment from about $0.01 to $0.000001.

Gateway does more than concatenate payments. It nets them: it collects signed authorizations off-chain, computes the net balance change per account across the whole batch, and applies only those net changes onchain. A buyer who made 5,000 calls to the same seller becomes a single balance update, not 5,000 transfers. That is what lets the system absorb machine-speed payment streams without pushing machine-speed load onto the chain.

Per-payment settlementNanopayments (batched)
Onchain transactions1 per payment1 per thousands of payments
Gas per paymentfull gas, every timeamortized across the batch
Practical minimum payment~$0.01$0.000001
Payment latencyseconds (block confirmation)milliseconds (offchain verification)
Who pays gasbuyer or facilitator, per paymentGateway, once per batch

The payment lifecycle

Here is the full life of a nanopayment, from funding to final settlement:

Nanopayments sequence diagram: one-time deposit, 402 negotiation, offchain EIP-3009 signature, instant settlement via Circle Gateway, and periodic batched onchain settlement
The Nanopayments lifecycle. Steps 1-8 repeat per request at zero gas; steps 0 and 9 are the only onchain transactions.
  1. Deposit (once). The buyer deposits USDC into the Gateway Wallet contract. This is the only transaction the buyer ever pays gas for.
  2. Request and negotiate. The buyer requests a paid resource; the seller answers 402 Payment Required with a PAYMENT-REQUIRED header describing price, network and destination.
  3. Sign. The buyer signs an EIP-3009 TransferWithAuthorization message off-chain, authorizing Gateway to move exactly the advertised amount from their balance to the seller. Zero gas.
  4. Settle and serve. The buyer retries with the PAYMENT-SIGNATURE header. The seller forwards the authorization to Gateway's settle endpoint; Gateway verifies the signature, locks the buyer's funds, credits the seller's balance, and answers in a few hundred milliseconds. The seller serves the resource immediately.
  5. Batch onchain. Periodically, Gateway nets all pending authorizations and submits one onchain transaction. Once confirmed, sellers can withdraw their balance to any supported chain.

The critical property: by step 4 the seller's payment is guaranteed and their balance credited, even though nothing has touched the chain yet. Verification latency and settlement finality are decoupled, which is what makes per-request pricing usable inside a hot code path.

Nanopayments vs standard x402

If you read our tutorial on gating an API with x402, the flow above will look familiar: same status code, same headers, same EIP-3009 signatures. The differences are all in where the money sits and how it settles:

Standard x402 (exact scheme)Nanopayments
Buyer fundsUSDC in the buyer's walletUSDC deposited in a Gateway balance
Settlementone onchain tx per payment, right after verificationinstant offchain credit, batched onchain later
Facilitatoryour choice (x402.org, Coinbase CDP, ...)Circle Gateway
Sensible price range$0.001 and up$0.000001 and up
Seller receivesUSDC in their wallet, per paymentGateway balance, withdrawable on any supported chain
Buyer wallet typeany EOAEOA only (no smart accounts)

The two are complementary. A $5 report sold a few hundred times a day is perfectly served by standard x402 and lands straight in your wallet. A $0.0001 inference call served a million times a day only works batched. Because both speak x402, a seller can expose both and let each buyer pick the option their client supports.

Architecture and trust model

Nanopayments architecture: buyer with EOA wallet and GatewayClient, seller Express API with Gateway middleware, Circle Gateway facilitator with TEE verification, and the settlement layer of 12 supported chains
The moving pieces. The buyer talks HTTP to the seller; only Gateway and the one-time deposit ever touch a chain.

The obvious question about batching: while payments wait in a batch, why can't Circle tamper with them? The design answer is a Trusted Execution Environment. Every signature is verified and every batch is computed inside an AWS Nitro Enclave, and the enclave signs the batch result with a key that only the audited enclave image can access; even Circle operators cannot extract it. The Gateway Wallet smart contract verifies the enclave's signature before executing a batch and reverts anything unauthorized, and the enclave produces cryptographic attestations that anyone can independently check.

On top of that, deposits stay non-custodial: funds live in the Gateway Wallet contract, not with Circle, and the contract includes a 7-day trustless withdrawal path, so you can exit with your funds even if Gateway itself goes dark. This is also why payment authorizations must remain valid for at least 7 days plus a buffer; the signature has to outlive the worst-case settlement path.

Tutorial: accept and send nanopayments in Node.js

Let's build both sides on testnet. The seller is an Express API selling /premium-data at $0.0001 per request; the buyer is a script that deposits once, then pays per call with signatures only. Everything uses Circle's @circle-fin/x402-batching SDK.

Prerequisites

  • Node.js 22.6+ (it runs TypeScript directly via type stripping, so no build step)
  • Two EOA addresses: one to receive funds (seller, address only) and one to pay (buyer, private key required)
  • Testnet USDC for the buyer from Circle's faucet, plus a little native gas token for the single deposit transaction
  • One caveat up front: the buyer must be a plain EOA. Smart contract accounts are not supported, because Gateway verifies signatures off-chain with ecrecover, which is incompatible with EIP-1271 contract signatures.

Part 1: the seller

Create the server project:

mkdir nano-seller && cd nano-seller npm init -y && npm pkg set type=module npm pkg set scripts.start="node --env-file=.env server.ts" npm install @circle-fin/x402-batching @x402/core @x402/evm viem express typescript npm install --save-dev @types/node @types/express

Configure the receiving address through the environment:

.env
SELLER_ADDRESS=0xYourSellerAddress

Then the whole server:

server.ts
import express from 'express'
import { formatUnits } from 'viem'
import { createGatewayMiddleware } from '@circle-fin/x402-batching/server'

type PaidRequest = express.Request & {
  payment?: {
    verified: boolean
    payer: string
    amount: string
    network: string
    transaction?: string
  }
}

const sellerAddress = process.env.SELLER_ADDRESS as `0x${string}` | undefined
if (!sellerAddress) throw new Error('SELLER_ADDRESS not configured')

const gateway = createGatewayMiddleware({
  sellerAddress,
  facilitatorUrl: 'https://gateway-api-testnet.circle.com',
})

const app = express()

app.get('/premium-data', gateway.require('$0.0001'), (req: PaidRequest, res) => {
  const { payer, amount, network } = req.payment!
  console.error(`Paid ${formatUnits(BigInt(amount), 6)} USDC by ${payer} on ${network}`)

  res.json({
    signal: 'Funding rates flipped negative on three venues.',
    paid_by: payer,
  })
})

app.get('/free', (_req, res) => {
  res.json({ status: 'ok' }) // Routes without gateway.require() stay free.
})

app.listen(3000, () => console.error('Listening on http://localhost:3000'))

That is the entire seller integration: one middleware, one dollar-string price. gateway.require('$0.0001') answers unpaid requests with a 402 and a base64-encoded offer in the PAYMENT-REQUIRED header; when a request arrives with a valid PAYMENT-SIGNATURE, the middleware calls Gateway's settle endpoint, gets the payment guaranteed in a few hundred milliseconds, attaches the details to req.payment, and lets your handler run. Your handler code never touches a blockchain.

By default the middleware accepts payments from every Gateway-supported network; you can restrict it with a networks: ['eip155:5042002'] option if you want to pin specific chains. Note the price: $0.0001 is a tenth of the practical minimum of standard x402, and you could go four orders of magnitude lower.

Start it and probe without paying:

npm start curl -i http://localhost:3000/premium-data
402 response
HTTP/1.1 402 Payment Required
PAYMENT-REQUIRED: eyJ4NDAyVmVyc2lvbiI6Mi...

Part 2: the buyer

In a separate project:

mkdir nano-buyer && cd nano-buyer npm init -y && npm pkg set type=module npm pkg set scripts.pay="node --env-file=.env pay.ts" npm install @circle-fin/x402-batching viem typescript npm install --save-dev @types/node
.env
PRIVATE_KEY=0xYourBuyerPrivateKey

The whole buyer fits in one script: check balances, deposit once if needed, then pay.

pay.ts
import { GatewayClient } from '@circle-fin/x402-batching/client'

const privateKey = process.env.PRIVATE_KEY as `0x${string}` | undefined
if (!privateKey) throw new Error('PRIVATE_KEY not configured')

const client = new GatewayClient({
  chain: 'arcTestnet',
  privateKey,
})

// 1. Where do we stand?
const balances = await client.getBalances()
console.log(`Wallet USDC:  ${balances.wallet.formatted}`)
console.log(`Gateway USDC: ${balances.gateway.formattedAvailable}`)

// 2. One-time top-up of the Gateway balance (USDC has 6 decimals).
if (balances.gateway.available < 1_000_000n) {
  console.log('Depositing 1 USDC into the Gateway Wallet...')
  const deposit = await client.deposit('1')
  console.log(`Deposit tx: ${deposit.depositTxHash}`)
}

// 3. Pay for the resource. No gas, no transaction: just a signature.
const { data, status } = await client.pay('http://localhost:3000/premium-data')
console.log(`Status: ${status}`)
console.log('Response:', data)

// 4. The balance moved by exactly $0.0001.
const updated = await client.getBalances()
console.log(`Gateway USDC after: ${updated.gateway.formattedAvailable}`)

Run it against your local server:

npm run pay
Wallet USDC: 10.0 Gateway USDC: 0.0 Depositing 1 USDC into the Gateway Wallet... Deposit tx: 0x83f2...9a1c Status: 200 Response: { signal: 'Funding rates flipped negative on three venues.', paid_by: '0xYourBuyerAddress' } Gateway USDC after: 0.9999

Behind client.pay(), the SDK made the first request, parsed the 402 offer, signed the EIP-3009 authorization against the GatewayWalletBatched domain, retried with the PAYMENT-SIGNATURE header, and returned the paid response. Call it in a loop and you will see the balance drop by 0.0001 per call with zero gas spent; the deposit in step 2 never runs again. If you want to check whether an arbitrary URL accepts Gateway payments before paying, client.supports(url) does exactly that.

Withdrawing your revenue

Both sides hold value as a Gateway balance, and Gateway is crosschain by construction. Withdraw to the same chain or any other supported one:

withdraw.ts
// Same chain as the client: immediate.
const sameChain = await client.withdraw('5')
console.log(`Withdrew ${sameChain.formattedAmount} USDC - tx: ${sameChain.mintTxHash}`)

// Or receive on a different chain entirely.
const crossChain = await client.withdraw('5', { chain: 'baseSepolia' })
console.log(`Withdrew to ${crossChain.destinationChain}`)

This is a quietly powerful detail for sellers: you can accept nanopayments from buyers on a dozen chains and withdraw the aggregate on the single chain your treasury lives on.

Going to mainnet

Three changes take the tutorial to production:

  1. Facilitator URL: point facilitatorUrl at https://gateway-api.circle.com instead of the testnet endpoint.
  2. Chain: switch the GatewayClient chain to a mainnet network (for instance Base; see Circle's supported chains list for the exact identifiers) and fund the buyer with real USDC.
  3. Key handling: the buyer's private key now authorizes real spending. Keep it in a secret manager, give the wallet a small float rather than treasury funds, and cap per-request prices in your client logic. The seller still holds no secrets at all, only a public receiving address.

Use cases: what sub-cent payments unlock

A working $0.000001 payment is a new primitive, and the interesting products are the ones the old $0.01 floor made impossible:

  • Agentic payments. An AI agent with a funded Gateway balance can buy data, tools and compute autonomously, paying per call without a human, a card form, or an API key. This is the headline use case: x402 processed over $100M in payments within months of launch, and Circle positions Nanopayments as the machine-native rail under it.
  • True usage-based billing. Price your API at its marginal cost: $0.0001 per request, $0.000005 per row, per token, per millisecond of GPU time. No subscriptions, no prepaid credit systems, no monthly invoicing infrastructure.
  • Machine-to-machine marketplaces. Services buying from services: a scraper paying a proxy per request, an agent paying another agent for a subtask, an oracle selling individual data points. At machine frequency, only batched settlement keeps up.
  • Streaming money. Pay-per-second content, per-minute compute leases, per-chunk file delivery: any metered resource can settle continuously in payments too small to notice individually.

Limits and gotchas

  • EOA wallets only. Gateway's off-chain ecrecover verification rules out smart accounts and EIP-1271 signatures. If your agents live in smart wallets today, they need an EOA spending key for nanopayments.
  • Buyers pre-fund. The deposit model means buyer funds sit in the Gateway balance before spending. It is non-custodial with a 7-day trustless exit, but it is still a float to manage, unlike plain x402 where funds stay in the wallet until each payment.
  • Authorizations must be long-lived. Payment signatures need at least 7 days plus a buffer of validity (maxTimeoutSeconds around 604,900), a direct consequence of the trustless-withdrawal window. Do not hand-roll shorter expirations; the settle endpoint will reject them.
  • Solana is the exception. Gateway's unified balance covers Solana, but Nanopayments today is EVM-only; the 12 nanopayments-enabled chains are all EVM.
  • Not for large transfers. Above roughly a cent per payment, standard x402 with per-payment settlement is simpler and gives the seller immediate onchain finality. Batching earns its complexity below that line.

Frequently asked questions

Is Circle Nanopayments custodial? No. Deposits sit in the Gateway Wallet smart contract, batches are computed and signed inside an attested TEE that even Circle operators cannot reach into, and a 7-day trustless withdrawal path exists regardless of Circle's availability.

Does the buyer or seller ever pay gas? Only the buyer's one-time deposit (and any withdrawal) is an onchain transaction. Every payment in between is an off-chain signature; Gateway pays the gas for batch settlement.

How small can a payment be? $0.000001, one millionth of a dollar, which is also one base unit of USDC.

Do I need Circle API keys? No. The settle endpoint is unauthenticated and the system is permissionless: a receiving address is all a seller needs, a funded EOA is all a buyer needs.

Where this fits

Nanopayments completes a stack we have been building with clients all year: x402 gives HTTP a price tag, and Gateway's batched settlement gives that price tag four more decimal places. Together they make "charge exactly what one request costs" a real billing model for APIs, agents and data products, with no billing system to build.

At Etherwave Labs we integrate the full x402 family end to end: pricing and gating your API, wiring Gateway or another facilitator, and equipping agents with safe spending wallets. We covered the broader protocol on our x402 service page, and if you want per-request USDC revenue in production, talk to us.

More articles

Cover image for Uniswap v4 Explained: What Changed From v3, How Hooks Work, and a Complete Liquidity Management Tutorial

Uniswap v4 Explained: What Changed From v3, How Hooks Work, and a Complete Liquidity Management Tutorial

A deep dive into Uniswap v4 for liquidity providers: the singleton architecture, flash accounting, and hooks compared to v3, followed by a hands-on TypeScript tutorial covering every position operation: mint, increase, decrease, collect fees, and burn.

Read more
Cover image for Gate an API Endpoint with x402: Accept USDC Payments on Your Node.js Server

Gate an API Endpoint with x402: Accept USDC Payments on Your Node.js Server

A full, hands-on tutorial to monetize an Express API with the x402 payment protocol: gate an endpoint behind a USDC price on Base, then pay for it programmatically from JavaScript and Python clients.

Read more

Ready to take your project to the next level?

Contact us today to discuss how we can help you achieve your goals in the blockchain space.