Skip to content

Batching provider settlements — measured 95–140× gas reduction at N=1,000 / R=5 #297

Description

@changshenhan

What this is

We build Mist — an open-source batch settlement
layer for x402 (contracts live on Base mainnet, every number below is measured and
reproducible). ClawRouter's traffic profile — many requests, few providers — is exactly
where batch settlement pays. This is the arithmetic and three integration paths; no
pitch beyond that.

The measured cost of per-payment settlement

We measured what one x402 payment actually costs on Base with real USDC bytecode and
mainnet receipts (gas ledger):
61,105–90,053 gas per payment (warm/fresh payee). At 1,000 requests that is
61–90M gas — 15–23% of an entire 400M-gas Base block — and the bill swings with base
fee (which has historically moved >10×).

What batching does

Mist aggregates N payments to R recipients into one optimistic settlement epoch:
ledger off-chain, one commit (operator bond in escrow) + one settle (net per
recipient) on-chain, a 6-hour challenge window, then claim and bond release. Measured
amortization, including claim rows:

per-payment gas ≈ (246,000 + 78,958 × R) / N

At a ClawRouter-like profile — N = 1,000 requests, R = 5 providers:

Direct (one tx per request) Batched
On-chain gas 61–90M 246k + 78,958 × 5 ≈ 641k
≈ 95–140× cheaper
Cost shape floats with base fee fixed per epoch

(At N = 1,000 / R = 1: ≈ 325 gas per payment, 188×.)

The first question: providers want instant USDC

Optimistic settlement is epoch + window; providers want funds now. These don't
conflict as long as providers are off the batch path:

Path 1 — self-hosted, the router fronts the float (we'd start here). ClawRouter
deploys its own BatchSettler and registers as operator — the contracts are open
source and permissionless, which fits the one-wallet, no-third-party design. Client
payments arrive as standard x402; ClawRouter is the recipient-of-record, pays providers
instantly from its float, and each epoch recoups what was already paid. Providers see
zero change. The cost is working capital: the float must cover Σnet for the 6-hour
window — roughly one window of your own provider outflow, computable from your traffic
numbers. Honest boundary: recipient-of-record = self-address is self-pay-self-receive
(our own mainnet demo has the same boundary; stated plainly). The operator bond is
chosen per commit and returned in full on honest settlement — mainnet-verified:
0.0005 ETH escrowed for the window, releaseBond returned it in full (six txs on
Basescan, mainnet life cycle).

Path 2 — managed facilitator, zero client change. Point the 402's
payTo/facilitator at a Mist gateway. Clients still sign a standard EIP-3009
authorization — verified end-to-end against the official @x402/axios + @x402/evm
v2 client with zero modifications. Fits when a provider itself accepts epoch
semantics.

Path 3 — providers join as native recipients. Most complete; requires providers
to change payout expectations. Not near-term.

Honest boundaries

  • Finality is epoch-level: acceptance is instant and ledgered; the on-chain net
    settles per epoch, claimable after the 6-hour challenge window.
  • The fraud-challenge path is protocol-complete and permissionless; its on-chain
    proof seam is currently a placeholder verifier (the real ZK prover is a separate
    workstream, documented as such).
  • When recipients don't repeat, batching loses ~30% versus direct — our own
    article says so. If your provider set were extremely fragmented, this would cut
    against the idea; at R = 5 it doesn't.

An entry in the upstream x402 third-party extensions list is currently in review
(PR #3321).

Happy to go deeper on any part. The full life cycle just ran on Base mainnet
(commit → settle → 6-hour window → claim → releaseBond), so every number above has
a receipt behind it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions