Skip to content

0.7.0 (3/7): X402-08 to X402-10, and Permit2 on Base Sepolia - #6

Merged
dzakwannajmi merged 4 commits into
mainfrom
0.7.0/3-negative-checks-permit2
Oct 8, 2026
Merged

dzakwannajmi merged 4 commits into
mainfrom
0.7.0/3-negative-checks-permit2

Conversation

@dzakwannajmi

Copy link
Copy Markdown
Collaborator

Part 3 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

  • Three negative payment checks: X402-08 Payment Replay Rejected, X402-09 Underpayment Rejected, X402-10 Expired Authorization Rejected. Sixteen checks in all.
  • Base Sepolia targets that use Permit2, including the EIP-2612 gas-sponsoring extension.

Commits

  • 25a9d9d feat(core): X402-08 replay, X402-09 underpayment, X402-10 expired authorization
  • 5a70778 docs: sixteen checks, X402-06..10 as the payment checks, and the evidence
  • 384f0b8 feat(core): pay Base Sepolia targets that use Permit2
  • c6b8667 docs: name the Permit2 commit in the Base Sepolia evidence

Verification

Unit tests and the clean install run in CI. The runs on Stellar and Base Sepolia are in docs/evidence/2026-10-05-x402-negative-checks-run.md and the Base Sepolia file (folded into the per-date file in PR 7/7).

🤖 Generated with Claude Code

…horization

X402-07 checked one way a payment can be bad: a corrupted signature. A
payment can also be wrong with a valid signature, and a server that only
checks signatures, or skips the facilitator's verify, would accept it.
Three negative checks now cover the ways the spec names:

- X402-08 sends the exact headers X402-06's accepted payment used, again.
  Each authorization is single-use (x402 v2 §10.1). Skipped when the
  challenge advertises payment-identifier, whose cached replies are
  legitimate.
- X402-09 signs, with the official client, for half the price, then sets
  `accepted` back to the advertised terms, so only the amount is wrong
  (Stellar: must equal requirements.amount exactly; EVM: step 3).
- X402-10 signs with maxTimeoutSeconds 1, which both clients turn into the
  authorization's lifetime, waits it out (5 s on Base Sepolia, 20 s on
  Stellar) and sends it.

A negative check now needs an accepted baseline: if the target refused
X402-06's valid payment, X402-07 to X402-10 are skipped, not passed, since
refusing everything proves nothing. A refusal shows the target's stated
reason when it gives one. No "settle before serve" check: the default
authorization flow runs the resource before settling (spec §6.1).

The interactive dashboard took its read-only exclusions from a hard-coded
list of X402-06/07; it now takes them from core (X402_PAYMENT_CHECK_IDS),
which would otherwise have left X402-08..10 spinning as pending.

Live on Wasit's fixtures: 10/10 on Stellar and on Base Sepolia, refused
for the reasons the checks are about; against wasit serve --mode
no-settle, X402-06..10 all fail on both chains. 5 new offline tests on a
throwaway EVM key (EIP-3009 signs without RPC), 9 mutants killed.

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

The catalogue grew to sixteen checks and the x402 payment checks are now
X402-06 to X402-10, so every place that counted thirteen or named only
X402-06/07 says so: the READMEs, the guides, SKILL.md and the site (the
MCP tool row, the logo strip's check count, the docs pages).

The evidence write-up records the runs: Wasit's fixtures 10/10 on Stellar
and Base Sepolia, each refusal quoted with the reason the target gave;
wasit serve --mode no-settle failing all five payment checks on both
chains; how each altered payment was built; and why there is no
settle-before-serve check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A target can advertise Permit2 instead of EIP-3009. The SDK client handles
it, but needs a signer that can read the chain (allowance, permit nonce)
to sign the one-time approval as a gas-sponsored EIP-2612 permit. The EVM
payer is now built with toClientEvmSigner and the run's RPC endpoint;
EIP-3009 signing stays offline.

A Permit2 target without gas sponsoring, where this run's payer never
approved Permit2, answers permit2_allowance_required: that is the payer's
setup, not the target's defect, so X402-06 reports ERROR (setup) and the
negative checks are skipped. X402-06's failure now carries the target's
stated reason when it gives one, keeping its old wording otherwise.

A Permit2 fixture (port 3006, eip2612GasSponsoring declared) joins
fixtures.sh and run-all.sh. Live, with a payer holding no ETH: 10/10 on
both Base Sepolia fixtures, each refusal for its own reason; the Permit2
settlement read back as one Approval to Permit2 and one Transfer to the
payee, gas paid by the facilitator. 206 core tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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:45am UTC

@dzakwannajmi
dzakwannajmi merged commit afaed21 into main Oct 8, 2026
5 checks passed
@dzakwannajmi
dzakwannajmi deleted the 0.7.0/3-negative-checks-permit2 branch October 8, 2026 06:47

This branch was successfully deployed

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