Skip to content

0.7.0 (6/7): Ethereum Sepolia, the $1 spend cap, named settlement failures - #9

Merged
dzakwannajmi merged 6 commits into
mainfrom
0.7.0/6-ethereum-sepolia
Oct 8, 2026
Merged

dzakwannajmi merged 6 commits into
mainfrom
0.7.0/6-ethereum-sepolia

Conversation

@dzakwannajmi

Copy link
Copy Markdown
Collaborator

Part 6 of 7 of 0.7.0, which is on npm since 2026-10-08. The PRs follow the release branch's commit order and are merged with merge commits, so every commit keeps its hash.

What changes

  • The x402 payment checks pay on Ethereum Sepolia (eip155:11155111) in Circle's USDC.
  • A price or asset the official client's spend controls refuse gets no verdict, and nothing is sent.
  • A settlement that verified but failed names its reason, read from PAYMENT-RESPONSE.
  • The Permit2 fixture logs its facilitator's refusals.

Commits

  • 35b12a6 feat(core): pay Ethereum Sepolia targets
  • 11672d4 feat(cli): Ethereum Sepolia in wasit serve, wallet and the network options
  • 93e04c0 feat(core): no verdict when the SDK client's spend controls refuse the price
  • 178b8a6 fix(core): name a failed settlement's reason, read from PAYMENT-RESPONSE
  • ba2b6cc test(fixtures): the Permit2 fixture logs its facilitator's refusals
  • 888ca1d docs: Ethereum Sepolia, the client's $1 spend cap, and named settlement failures

Verification

Unit tests and the clean install run in CI. The Ethereum Sepolia runs are in docs/evidence/2026-10-06-ethereum-sepolia-verification-run.md (folded into the per-date file in PR 7/7).

🤖 Generated with Claude Code

The payment checks X402-06..10 now also pay on Ethereum Sepolia
(eip155:11155111), through the same EVM adapter as Base Sepolia, with
the payer key in EVM_PRIVATE_KEY. Circle's USDC there has EIP-3009
(read from the contract: authorizationState answers, EIP-712 domain
"USDC" version "2"), and Permit2 and the x402 proxies are deployed, so
a payer needs the token and no ETH.

The SDK ships no default asset for Ethereum Sepolia, and its client's
spend controls refuse any asset that is not a default. The adapter
allows Circle's Sepolia USDC on that network only, with the cap the SDK
puts on its defaults, $1 a payment; every other network is unchanged.

Sepolia makes a block every 12 seconds, so the wait for a settled
transaction is now per network: 10 blocks within 240 seconds there, 30
within 120 on Base Sepolia as before. verifySettlement takes the
network to know which. X402-10's 5-second hold is unchanged: the SDK
facilitator holds validBefore to the clock with a 6-second margin, and
any block that could include the payment is later still.

No public facilitator settles Ethereum Sepolia, so its fixture (port
3008) runs the official SDK's facilitator in process, paying the gas
from EVM_FACILITATOR_PRIVATE_KEY; fixtures.sh starts it only when that
key and EVM_PAYEE_ADDRESS are set, and run-all.sh runs it when it is up.
BNB Smart Chain testnet stays read-only, and replaces Ethereum
Sepolia as the tests' example of a network the payment checks refuse.

Against `wasit serve` on Sepolia, with the funded payer: no-settle fails
X402-06..10, wrong-settlement fails X402-06 after 10 blocks (131 s),
wrong-network skips with nothing sent. The fixture passes X402-01..05.
235 core tests; 2 mutants of the allowance killed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tions

`wasit serve --network eip155:11155111` poses every mode on Ethereum
Sepolia: Circle's Sepolia USDC with its EIP-712 domain, wrong-network
asking for Ethereum mainnet (eip155:1), overprice one million USDC in 6
decimals, v1-challenge on v1's "sepolia". `wasit wallet --network
eip155:11155111` takes it too, through the same profile. `wasit test`
and the MCP tool name it among the networks the payment checks pay on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e price

The official x402 client pays only its default assets, plus the ones an
adapter allows (Circle's USDC on Ethereum Sepolia), and at most $1 a
payment, so that a paywall cannot charge a payer more than it meant to.
Wasit keeps those limits: it pays automatically, and on stellar:pubnet
with real money. A target priced above them used to get X402-06 ERROR
(harness) with the SDK's own advice to change its configuration.

Such a refusal is now ERROR (setup), with nothing sent and the negative
checks skipped, saying which limit: the price in base units against the
$1 cap, or the asset the client does not pay in. It is matched on the
SDK's message (@x402/core 2.28); one it does not recognise passes
through as before.

Live against `wasit serve` on Base Sepolia priced at 2000000 units (2
USDC), with a payer holding 19.8: ERROR (setup) "asks for 2000000 base
units ... more than the $1 a payment", and the paywall received no
payment. 236 core tests; 3 mutants killed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A payment that verified but did not settle came back as "got 402." with
no reason. The official SDK server does say why: it answers with a
PAYMENT-RESPONSE whose success is false and whose errorReason names the
facilitator's failure. Wasit read the reason only from a fresh
challenge's `error` or the body, so it missed it.

The refusal reason now reads PAYMENT-RESPONSE first, as "settlement
failed: <code>" (a long RPC message after the code is dropped), and
X402-06's hint for it says the facilitator did not settle a payment that
verified. A PAYMENT-RESPONSE that claims success is not read as a
failure.

Found on Wasit's own Base Sepolia fixtures: a few runs failed X402-06
with "got 402.", and the fixture's facilitator log showed the public
facilitator's settlement failing at eth_sendRawTransaction
(invalid_exact_evm_transaction_failed). 238 core tests; 4 mutants
killed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A refused settlement reached the client as a bare 402 before Wasit read
PAYMENT-RESPONSE, and the fixture's log was the only place to see why.
It now logs each verify refusal and settle failure with the
facilitator's reason, which is how the intermittent
invalid_exact_evm_transaction_failed on Base Sepolia was found.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nt failures

CHECKS.md, the CLI, MCP and configuration guides, the CLI README, the
agent skill and the site's stack strip name Ethereum Sepolia among the
networks the payment checks pay on, with Circle's Sepolia USDC and the
fixture's own facilitator key. CHECKS.md says the official client's
limits ($1 a payment, its default assets plus Circle's Sepolia USDC)
give no verdict, and that a failed settlement reads "settlement failed:
<reason>"; its X402-08 row now says the public facilitator refuses a
replay at settlement, as measured.

The evidence: on Ethereum Sepolia the lying modes of `wasit serve` fail
and the fixture passes 10/10, the settlement read back with viem (one
Transfer, sent by the fixture's facilitator, payer at 0 ETH); a 2 USDC
paywall gets ERROR (setup) and receives nothing; and on Base Sepolia the
intermittent X402-06 failure is the public facilitator failing to
broadcast its settlement (five of sixteen runs on 2026-10-06), which the
payer-balance evidence now records as found. The wallet and serve-modes
evidence names its commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
wasit Ready Ready Preview Oct 8, 2026 6:51am UTC

@dzakwannajmi
dzakwannajmi merged commit 0a8a5b7 into main Oct 8, 2026
5 checks passed
@dzakwannajmi
dzakwannajmi deleted the 0.7.0/6-ethereum-sepolia branch October 8, 2026 06:52

This branch was successfully deployed

1 active deployment
Preview — 888ca1db Deployed Oct 8, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant