Agentic week: what exactly did the payment buy?
This week, an x402 paywall let a paid route through for free because it read the path differently from the router, and a new x402 scheme made the request part of what gets signed. Both answer the same question: what exactly did the payment buy?
Between 18 and 25 September, 17 pull requests merged into x402-foundation/x402, down from 30 the week before. phdargen authored 4, CarsonRoscoe 3 and PhilBot402 2. The other eight came from eight different accounts, one each. The count is small, but the week carried a paywall bypass, a new settlement rail, a foundation member with a payments business behind it, and x402 showing up in a BlackRock research paper.
The common thread runs from last week's roundup. Then, the paywall and the handler read different requests. This week the gap moved in two directions. It showed up again at the path layer, and one new scheme closed part of it by design.
1. /api%2Fpremium: the paywall that matched a different path
PR #3502, opened by CarsonRoscoe on 16 September and merged on 21 September, fixes an unpaid-access path in the Python SDK. The mechanism takes two sentences. The FastAPI and Flask middleware matched protected routes on the escaped request path (raw_path, RAW_URI or REQUEST_URI). Starlette and Werkzeug dispatch literal routes on the decoded path.
So for a literal route like GET /api/premium, a request for /api%2Fpremium did not match any protected pattern. requires_payment() returned false and the middleware passed the request through. The framework then decoded the path and sent it straight to the paid handler. There was no payment header, no verification and no settlement. The PR reproduces it against a real Uvicorn server:
# before the fix
curl http://localhost:8000/api/premium
# 402 Payment Required
curl --path-as-is http://localhost:8000/api%2Fpremium
# 200 OK, full paid body
What makes this worth reading closely is how the code got here. In August, #3044 moved Go's route matching onto the escaped path. The goal was to stop a decoded separator from widening a wildcard capture, and #3073 ported that to Python. That was the right call for wildcards and the wrong one for literals. One fix to path handling set up the next hole. Counting #3036, the 4 August wildcard line-terminator bypass, this is the fourth path-handling fix in the SDKs since the start of August.
The fix does not pick a winner. It carries both representations. HTTPRequestContext gains a decoded_path taken from each framework's own routing view, and route lookup requires payment if either the escaped path or the decoded path matches. For requests without encoding the two strings are equal, so the extra check does nothing.
An automated drift check opened issue #3541 on 21 September and rated the gap "medium" for the other SDKs. It noted that Go adapters passed only EscapedPath() and @x402/fastify passed the raw request.url. The TypeScript and Go ports, #3542 and #3543, merged on 22 September and cover Express, Hono, Fastify, Next, Gin, Echo and net/http. All three SDKs released the same day: @x402/core 2.27.0 on npm, x402 2.24.0 on PyPI and Go v2.27.0.
%2F in the path at the edge.
2. Lightning lands in x402, and Block joins the foundation
On 24 September Block announced that it has joined the x402 Foundation and that it "has contributed Bitcoin Lightning payments to the x402 protocol." The contribution in the repository is PR #2861, merged the day before. It came from benthecarman, whose GitHub profile lists Spiral, Block's Bitcoin development group. The PR was opened on 15 July and adds a 760-line specification, scheme_exact_lnbtc.md. It is not an implementation.
The shape is simple. The resource server returns a fresh BOLT11 invoice in extra.invoice. The client pays it and sends back the 32-byte preimage. The facilitator checks SHA-256(preimage) == payment_hash, checks that the invoice signing key equals payTo (a 33-byte compressed secp256k1 key), and atomically records network:payment_hash in a replay store. Networks use a new lnbtc namespace, keyed to Bitcoin's genesis hash following the BIP-122 CAIP-2 convention: lnbtc:000000000019d6689c085ae165831e93 for mainnet. Amounts are millisatoshis. Only the upfront flow is allowed, and the server "MUST NOT call /verify."
Several consequences are spelled out. "Settlement does not move funds": the money moved before the preimage existed. An in-memory replay store is explicitly non-compliant, because a restart would let a spent preimage be claimed again. SettlementResponse.payer must be omitted, because Lightning has no stable payer address. Overpayment buys nothing extra, and there is no refund path. A shared custodial node is ruled out: a tenant who can issue invoices under the same node key could pay its own invoice and use the preimage against another tenant's requirement.
The important part is request binding. The invoice's signed description hash must equal a requestHash computed as SHA-256 over a JCS-canonicalized (RFC 8785) object. The http:1 profile covers the method, the target URL under RFC 9421 rules, a hash of the body bytes and a server-configured list of headers. The mcp:1 profile covers the server URI, tools/call, the tool name, the arguments and selected _meta members. A preimage for /article/A fails with invalid_exact_lnbtc_request_mismatch when presented for /article/B at the same price. EVM exact works differently: the EIP-3009 authorization signs from, to, value, a validity window and a nonce, and nothing about the request. In lnbtc, what was bought is part of what was signed. That would not stop a middleware that never asks for payment, as in item 1. It does mean a proof cannot be moved from one request to another.
Two caveats. First, nothing implements it yet. Two Lightning implementation PRs are still open, #1873 (Python, since March) and #2262 (TypeScript, since May, still named bip122). Earlier Lightning PRs going back to November 2025 were closed without merging. Second, this is Lightning's second home in the 402 world. When we audited L402 in August, the Lightning method in Tempo's MPP specs was written by Lightspark. The x402 method now comes from Block. Lightning Labs, which invented L402, wrote neither.
3. Coinbase for Agents pays from an exchange balance
Coinbase added US equities and x402 payments to Coinbase for Agents this week (coverage dated 22 September). The launch post on coinbase.com returned 403 to our fetches, but the operative text is in the Coinbase for Agents skill document. That text describes a different kind of x402 buyer. The agent pays "directly from your Coinbase USDC balance": an exchange balance, reached through OAuth on the remote MCP server or a CDP API key in the CLI.
The remote MCP server at agents.coinbase.com/mcp exposes three x402 tools. coinbase_x402_resources searches a curated catalog for free. coinbase_x402_fetch pays and retrieves in one call. coinbase_x402_pay authorizes and returns a header. Fetch works only on curated catalog URLs and x402 v2. The providers listed are Nansen, Arkham, Glassnode, Dripstack, Exa, You.com and Massive. Payments are "USDC on Base only, with a 5 USDC per-payment cap". A caller's max_amount can tighten the catalog ceiling but not raise it. The document is blunt: "A prompt budget is not a server-enforced session or daily limit." Retries are keyed by an idempotency_key, and "omitting or changing it can create another hold." The document says not to claim native SIWX support, and the ChatGPT trading integration leaves x402 out.
We probed the endpoint on 25 September. An unauthenticated POST /mcp returns 401 with WWW-Authenticate: Bearer resource_metadata="https://agents.coinbase.com/.well-known/oauth-protected-resource" and a scope list. The metadata document returns 200 and names login.coinbase.com as the authorization server. That is RFC 9728 done correctly. The same day, Coinbase's Wallet MCP at mcp.base.org still answered Bearer realm="mcp" with no metadata pointer, and its metadata path still returned 404, exactly as in our 21 September audit.
The ten advertised scopes cover portfolios, accounts, products, orders, trades and transfers. None of them names payments, and the document does not say which scope the x402 tools require. A user who grants "trade" access may also have granted "pay for data" access without seeing it. As an operator you cannot fix that from the seller side, but you should know it when you read those grants.
4. BlackRock writes x402 into the thesis
BlackRock's "The Machine-Native Economy" is an 11-page paper by Will Su, Robert Mitchnick, Jay Jacobs and William Helm. Press coverage began this week. Its framing line is "AI represents machine-native intelligence, while digital assets represent machine-native money." On payments, it names x402 and says that by "providing 24/7, near-real-time, verifiable settlement, x402 can reduce the resource provider's counterparty exposure and enable the immediate release of requested data or services upon payment confirmation." It puts stablecoin market capitalization above $300 billion as of September 2026. It names Ethereum and Circle's Arc, "where USDC is designed to serve as the native gas asset," as settlement venues.
Two details matter more than the headline. The paper's conclusion is careful: "The ecosystem remains nascent, with agentic payment activity and compute-market liquidity still limited." And its compute section cites Stripe's 19 August agreement to acquire OpenRouter, a model gateway routing across 400+ models from more than 80 providers. The paper reads that deal as "an early strategic signal that model routing and compute-usage optimization are becoming part of the financial infrastructure surrounding AI."
The on-chain side moved the same week. PR #3523 (merged 23 September) records the x402 Upto Permit2 proxy at its canonical address on Arc Mainnet, with both Exact and Upto on Arc Testnet. The Exact proxy "is not currently deployed at its canonical address" on mainnet. For scale, the x402.org homepage on 25 September showed 75.41 million transactions and $24.24 million over the last 30 days, from 94.06K buyers and 22K sellers. That is roughly 32 cents per transaction. The site does not publish a methodology, so the figures are not comparable with TRM's screened totals from last week.
5. Smaller fixes, same question
PR #3521 (merged 21 September, shipped in @x402/evm 2.27.0) replaced a parseInt in the TypeScript getEvmChainId. parseInt stops at the first non-digit, so eip155:8453abc became chain 8453, eip155:0x2105 became 0 and eip155:1e3 became 1. That value is signed into the EIP-712 domain for Permit2, EIP-3009 and batch settlement. The network schema only requires a colon. Go and Python already rejected these inputs. We looked at x402's network identifiers in the ERC-7930 audit, and this is the same problem one layer down.
PR #3126 corrects the Starknet exact spec. The old text told a facilitator that found a payload's nonce already consumed to look up the consuming transaction and report success. The PR explains the problem: "A settled payload is public, so anyone who replayed it would be given a second success, and every success releases a resource." A consumed nonce is now terminal.
PR #3205 adds a transferExecutor method to the Hedera spec, spec only for now, for payers whose funds a contract controls, including HIP-336 allowance delegations. The PR lists agent-wallet contracts among them, and other chains already cover the case in exact. One correction to our own record: @x402/cardano and @x402/casper, which we reported as 404 on npm, were first published late on 18 September as 2.26.0 and are now at 2.27.0. Elsewhere, A2A merged a coherent task-history timeline in #2129. It deliberately reuses an existing stream event because the Go, Java and Rust SDKs hard-error on unknown ones.
What it means for LLM4Agents
The path bypass is the item with immediate operational weight. An OpenAI-compatible gateway has a small, literal route table: chat completions, embeddings, models. That is exactly the literal-route case the bug hit. If the layer that meters a call and the layer that dispatches it normalize the path differently, some calls go unpriced. On routes where the model travels in the body, no legitimate client needs an encoded separator in the path. Rejecting them costs nothing and removes the whole class.
The lnbtc binding matters more than the rail. It is the first x402 scheme in which the payment commits to the request, and the construction does not depend on Lightning: a JCS object over method, URL, body hash and chosen headers, hashed and signed. For a gateway, the matching object is the endpoint, the model and the prompt body. A receipt carrying that hash lets an agent, or its auditor, prove which call a payment covered. Today, on EVM, the payer's signature covers the transfer and nothing about the call it paid for.
Coinbase's buyer adds a population of agents that pay from custodial balances, reach sellers only through a curated catalog, and retry under idempotency keys. Typical per-call LLM prices sit far below a 5 USDC cap. The constraints that matter are catalog listing, and handling a repeated payment for the same logical call as a duplicate, not as a second sale.
BlackRock's paper is useful for what it cites. BlackRock is citing Stripe's purchase of a model router as evidence that routing is becoming financial infrastructure. That is our category. It confirms the demand thesis, and it also names a competitor with a far deeper billing stack than ours. The difference we can defend is stablecoin-native, per-call settlement on an open protocol that the same paper names first.
Staying on the frontier
Five steps, in order.
First, close the path class this week. Upgrade any x402 SDK in the request path to @x402/* 2.27.0, Python 2.24.0 or Go v2.27.0. Reject percent-encoded separators on API routes at the edge. Add a test per paid route that sends the encoded variant with --path-as-is and expects a 402 or a 400, never a 200.
Second, put a request hash in every receipt. Reuse the structure of the lnbtc http:1 binding object with our own domain tag: method, target URI, body hash and configured headers, canonicalized with JCS. Return its digest with the settlement response. Borrowing a published construction beats inventing one, and it is ready for the day a scheme on our rails needs it.
Third, make the endpoint catalog-ready. Custodial buyers find sellers through curated lists. Stable resource URLs, an input schema and prices that match the live 402 are the entry ticket. Duplicate payments for one logical call should resolve to one delivery.
Fourth, test upto on Arc Testnet. Token-metered LLM calls are the natural fit for the upto scheme, and upto is the proxy already live at its canonical address on Arc Mainnet. A testnet run now is cheap insurance if Arc becomes the venue the institutional thesis points at.
Fifth, prepare for Lightning, but do not build it yet. Wait for an SDK that implements lnbtc. Meanwhile, write down the prerequisites the spec imposes: a receiver node key used only for this service, a restart-durable replay store with an atomic insert keyed on network:payment_hash, and reconciliation that works without a payer address.
Pay per call, in stablecoins, over an OpenAI-compatible API
Register an agent, fund it, and start routing. No prepaid credit, no monthly minimum.
Register an agent