Skip to content

0.7.0 (2/7): x402 payment checks on Base Sepolia - #5

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

dzakwannajmi merged 6 commits into
mainfrom
0.7.0/2-base-sepolia

Conversation

@dzakwannajmi

Copy link
Copy Markdown
Collaborator

Part 2 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 go through a per-chain adapter, and pay on Base Sepolia (eip155:84532) in its USDC with EIP-3009. The settlement is read from the receipt's ERC-20 Transfer log.
  • wasit serve --network eip155:84532.
  • A Base Sepolia fixture, started by fixtures.sh and run by run-all.sh.
  • x402 SDK 2.28, with @x402/evm and viem.

Commits

  • 552f798 chore(core): x402 SDK 2.28, with @x402/evm and viem for EVM payments
  • 17b52de refactor(core): x402 payment checks go through a per-chain adapter
  • 282004c feat(core): x402 payment checks on Base Sepolia
  • fb21760 feat(cli): wasit serve on Base Sepolia
  • 7d27551 test(fixtures): a Base Sepolia x402 fixture, run by fixtures.sh and run-all.sh
  • f0ccd04 docs: x402 payment checks on Base Sepolia, with the evidence

Verification

Unit tests and the clean install run in CI. The Base Sepolia runs, lying servers and an honest fixture with the settlement read back, are in docs/evidence/2026-10-05-base-sepolia-verification-run.md (folded into the per-date file in PR 7/7).

🤖 Generated with Claude Code

M4 adds payment checks on Base Sepolia, which need @x402/evm. It depends
on @x402/core ~2.28, so the other x402 packages move from 2.19 to 2.28
with it, keeping one copy of @x402/core in the tree: a client from one
copy registering a scheme from another is the kind of split the 0.4.0
cross-check bug came from. viem is the signer and RPC client @x402/evm
uses.

Nothing else changes in this commit. Verified on the bumped tree: build,
core 180 and cli 45 tests, both typechecks, verify:clean-install, and the
local fixtures on Stellar testnet (x402 7/7 with X402-06 settled
on-chain, MPP-01 PASS, channel 3 passed and 2 skipped).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
X402-06 and X402-07 called Stellar code directly: the signer, the
settlement lookup, the reference format and the signature corruption.
Supporting another chain would have meant branching inside each check.

A PaymentChain adapter now supplies those (x402/chains), and the checks
ask it for the run's network. Stellar's adapter wraps the existing code
unchanged; corruptAuthSignature moves into it and is still exported from
simulator.ts. readSettlementReference takes the chain as an optional
third argument, defaulting to Stellar, so its callers and tests are
unaffected. A network no adapter pays on is still stopped at preflight,
now with a message that lists the networks the payment checks do pay on.

No behaviour change otherwise: 180 core tests pass, and the full flow
against the Stellar fixture is still 7/7 with X402-06 settled on-chain.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The payment checks paid on Stellar only. An EVM adapter now pays on eip155:84532 with the exact
scheme's EIP-3009 method (USDC's transferWithAuthorization): the payer
signs off-chain and the facilitator pays the gas, so a payer needs the
token and nothing else (scheme_exact_evm.md).

X402-06 holds the settlement to the receipt's ERC-20 Transfer log by the
Stellar rules: the transaction succeeded, exactly one token transfer,
the advertised amount of the advertised token, to payTo, from this run's
payer. ERC-721 transfers share the event signature and are not read as
token transfers. The receipt is awaited in blocks, as Stellar awaits
ledgers: missing after 30 blocks, no verdict if the RPC stops advancing.
X402-07 flips the first byte of the EIP-3009 signature, leaving the
authorization intact, so only signature verification can refuse it.

Front ends read the payer key by network: STELLAR_PRIVATE_KEY on
Stellar, EVM_PRIVATE_KEY on Base Sepolia. A key for the wrong chain, or a
malformed one, now stops the run at preflight, before anything is sent;
the message never echoes the key. The default RPC is viem's Base Sepolia
endpoint, https://sepolia.base.org, overridable with --rpc-url.

Offline only so far: 19 new tests (199 core), 15 mutants killed. The
Stellar fixture is still 7/7. A live Base Sepolia run, and the docs, come
next.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
wasit serve posed only as a Stellar paywall. --network eip155:84532 now
poses the same four modes on Base Sepolia: the SDK's default Base Sepolia USDC (6 decimals)
with its EIP-712 domain ("USDC", "2") in extra, wrong-network asking for
Base mainnet (eip155:8453), overprice asking for one million USDC in 6
decimals, EVM-shaped payees and settlement hashes. The payee defaults to
EVM_PAYEE_ADDRESS there, STELLAR_PAYEE_ADDRESS on Stellar.

Network differences live in one profile per network; the modes are
unchanged. On Stellar the only visible change is that wrong-network now
names "Stellar mainnet".

Run with wasit test --network eip155:84532 and a throwaway, unfunded key
(EIP-3009 signing is off-chain): no-settle fails X402-06 and X402-07,
wrong-network gets the payment checks skipped, and wrong-settlement fails
X402-06 once the real Base Sepolia RPC has produced 32 blocks without the
cited transaction. Nothing settled. 9 new tests (cli 54).

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

The Base Sepolia twin of the Stellar x402 fixture: the same route and
price, settled through the same public facilitator, on port 3005. It
needs EVM_PAYEE_ADDRESS, so fixtures.sh starts it only when .env has one
and skips it otherwise, and run-all.sh adds its suite only when it is up:
a Stellar-only setup runs exactly as before. .env.example documents
EVM_PRIVATE_KEY and EVM_PAYEE_ADDRESS.

Run on Base Sepolia with a payer holding 20 USDC and no ETH: wasit test
--network eip155:84532 is 7/7, X402-06 settled in tx 0xb182df33...7e91.
Read back independently: one Transfer from the payer to the payee for
10000 units, the gas paid by the facilitator, the payer still at 0 ETH.
X402-07's forged signature was refused and nothing settled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The payment checks now pay on Base Sepolia, so the docs say so, now that
it has been run. CHECKS.md describes what X402-06 and X402-07 do there
(the receipt's Transfer log; the forged EIP-3009 signature), the networks
note lists the three networks the payment checks pay on, and Common
failures explains what a Base Sepolia payer needs: USDC and no ETH. The
CLI, MCP and configuration guides, the CLI README and SKILL.md name
EVM_PRIVATE_KEY and --network eip155:84532. CHANGELOG records the change.

The evidence write-up records the runs: servers that skip settlement or
cite a missing transaction fail X402-06 and X402-07, a mainnet request
gets nothing sent, and Wasit's own fixture passes 7/7 with the settlement
read back independently on-chain, the payer holding no ETH.

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:44am UTC

@dzakwannajmi
dzakwannajmi merged commit 9fbf020 into main Oct 8, 2026
5 checks passed
@dzakwannajmi
dzakwannajmi deleted the 0.7.0/2-base-sepolia branch October 8, 2026 06:45

This branch was successfully deployed

1 active deployment
Preview — f0ccd04b 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