Batch-settlement scheme specification for EVM#2051
Batch-settlement scheme specification for EVM#2051CarsonRoscoe merged 7 commits intox402-foundation:mainfrom
Conversation
|
@phdargen is attempting to deploy a commit to the Coinbase Team on Vercel. A member of the Team first needs to authorize it. |
|
Why use this for state channels not #1907? Hub route = one channel, N payees. This is the biggest structural advantage. An agent opens one channel and pays any hub-connected API. Batch-settlement is strictly unidirectional/pairwise, a new channel (and deposit) per payer↔payee pair. For an agent calling 20 services, that's 20 escrows vs 1. Bidirectional Bidirectional channels let funds be used for agent↔agent, user↔agent, user↔user payments. claimWithSignature makes funds not usable for state channel payments. Doing 1 channel payer>payee shows yall are missing the whole reason for using state channels for APIs, if an API only costs $0.001 then this fucks them in gas. Hub route lets 1 channel do any payee so 1 wei payments are fine. |
|
If receiver are the server to then do one channel, n payees theres no flow in the spec. |
|
Also {
"scheme": "batch-settlement",
"network": "eip155:8453",
"amount": "100000",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"payTo": "0xServerReceiverAddress",
"maxTimeoutSeconds": 3600,
"extra": {
"receiverAuthorizer": "0xReceiverAuthorizerAddress",
"withdrawDelay": 900,
"name": "USDC",
"version": "2"
}
}shows this is closed vs open source where anyone can have their own servers since there's no url. how does an API say where to sign with? the APIs could be server but then thats a new infra every API needs |
|
Separate from the hub-routing question, I think one thing needs to be explicit in the spec is signer discovery. The voucher model is clear. The “where does the client learn the signer or authorizer it should bind to?” path feels implicit. Even one simple rule would help: if the authorizer is not the default receiver path, surface it in the requirement payload in a way the client can treat as authoritative for that accept entry. |
…nelState and compute channelID from EIP712Hash
|
Agree with @jithinraj's signer-discovery point. From the perspective of low-value paid API calls, I think this needs to be normative before SDKs copy the scheme. A client should be able to answer, from the
I would also love the spec to call out minimum receipt/observability fields for operators: |
|
Hi @jithinraj @Bortlesboat, |
CarsonRoscoe
left a comment
There was a problem hiding this comment.
Agree on making the authorizer explicit rather than falling back to payTo. Servers should return everything a client needs to fully rediscover a channel independently.
On the broader direction question: we looked at three prior state-channel proposals before landing here (including the cited model), so this wasn't a quick decision. The short answer is that we think bidirectional channels are a valid and interesting design, but they're solving a somewhat different problem, and we didn't want to conflate the two in a single scheme.
The specific use case we're targeting is: people who already use exact or upto and want a more economical version where they can defer and batch payments. That framing drove a few concrete choices:
-
Unidirectional channels fit the buyer/seller flow naturally. In x402 the happy path is funds flowing one direction, client -> server. Unidirectionality means the server never needs to lock capital, which in turn means it never needs to host sensitive signing material for the channel itself. The
receiverAuthorizerdesign is intentional here: every x402 scheme so far avoids requiring servers to keep signing keys on the hot path, and this one only slightly compromises by allowing you to EITHER bring singing material for a hot wallet (no funds required) OR use your facilitator's signer as your authorizer. Bidirectionality would break that property, requiring the keys with funds to be required by the server. -
Simpler off-chain state means simpler recovery. The only invariant the server tracks is
chargedCumulativeAmount; the only invariant the client tracks ischargedCumulativeAmount + amountfor the next voucher. State loss is well-defined in both directions, fall back to onchaintotalClaimed. Bidirectional balance conservation (balA + balB == totalBalance) adds a harder-to-recover invariant and a dispute path that we don't need for this use case. -
No intermediary in the funds flow. The hub model is powerful for multi-payee fan-out, but it introduces a fee layer and a trust surface between the client and server. x402's design principle has been that the disclosed amount is exactly what flows from client to server, any income splitting happens in the periphery via
payTorouting contracts. We wanted to preserve that here. -
Dynamic pricing is native. Since this is essentially "batched upto", the server charges actual cost up to a ceiling per request. With a hub/ticket model, amounts tend to be fixed at quote time, which doesn't map as cleanly to metered workloads.
None of this is a knock on the bidirectional approach, hub-routed bidirectional channels are genuinely useful for different scenarios (multi-payee fan-out, bidirectional flows, etc.) and could absolutely be their own scheme. We just didn't want to stretch batch-settlement to cover both use cases at the cost of the simplicity that makes it a practical upgrade path from exact/upto.
|
Ah are we still able to get #1907 pulled then as it's the only reason havent deployed yet since need to know if its in the standard before use it. This isnt the case, you might be thinking about LN. hub just credits into a channel and can move funds in if need, direct is pretty much just a 1 way until a pays, theres no reason b needs to lock funds or hub. x402s lets you do direct. |
Summary
Introduces the
batch-settlementpayment scheme specification for EVM chains, following the network agnostic specification introduced in #1145 by @CameronWhiteside.This scheme enables capital-backed, high-throughput, low-cost payments using stateless unidirectional payment channels. Clients deposit funds into onchain escrow once and sign off-chain cumulative vouchers per request. Servers batch-claim vouchers across many channels in a single transaction and settle earned funds with a separate sweep transfer, reducing per-request latency and gas costs.
Key Features
ChannelConfigstruct (channelId = keccak256(abi.encode(config))), fully reconstructible from the 402 response for recovery after client state lossmaxClaimableAmount; old vouchers are naturally superseded, eliminating the need for noncesactualPrice <= amount) within that ceilingclaimWithSignatureaggregates claims across many channels (only onchain accounting, no transfers);settlesweeps claimed-but-unsettled funds to the receiver in one transfereip3009(e.g. USDCreceiveWithAuthorization) orpermit2as a universal ERC-20 fallbackpayerAuthorizersupports fast ECDSA recovery (EOA) or EIP-1271 smart-wallet verification (zero address).receiverAuthorizerauthorizes claims and refunds via EIP-712 and can be a server-owned address or a facilitator-provided delegaterefundWithSignaturewhen the server cooperates;initiateWithdraw/finalizeWithdrawwith a 15 min – 30 day configurable delay as unilateral fallbackUse Cases
Links
x402BatchSettlement contract: #1950
Related work
Deferred scheme: #426
Session scheme: #2080