Skip to content

Commit b76ee4e

Browse files
committed
fix(metamask-agent-wallet): correct x402 v2 payment payload and related issues
Review on the PR found the v2 PaymentPayload reused the v1 top-level shape, so a v2 facilitator rejects it for missing 'accepted'. Build the v2 envelope per the spec (nest the chosen requirements under 'accepted', forward the top-level 'resource'); v1 is unchanged. Also: backdate validAfter instead of '0' to match the reference client; prefer the EIP-3009 option over Permit2 and report Permit2-only offers as unsupported; read the settlement receipt from the response body when the header is absent; surface the rejection reason from the PAYMENT-REQUIRED header when a paid retry fails; document the v2 payload difference, multi-network selection, and unsupported cases. Verified against the official x402 SDK and the v2 spec vectors, end to end on Base Sepolia against real facilitators (v1 and v2), and against a real third-party endpoint up to contract-level verification.
1 parent 21e1cf9 commit b76ee4e

3 files changed

Lines changed: 273 additions & 78 deletions

File tree

skills/metamask-agent-wallet/references/x402.md

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,39 @@ in the wallet. The script is pure Python standard library (run with `python3`).
2121

2222
The script handles both protocol versions: v1 (requirements in the `402` body, retry header
2323
`X-PAYMENT`) and v2 (requirements in the `PAYMENT-REQUIRED` header, retry header
24-
`PAYMENT-SIGNATURE`).
24+
`PAYMENT-SIGNATURE`). The payload envelope also differs: v1 puts `scheme`/`network` at the top
25+
level, while v2 nests the chosen requirements under `accepted` and forwards the top-level
26+
`resource` (see the x402 v2 spec, PaymentPayload schema). The script builds the correct envelope
27+
per version.
28+
29+
### Supported
30+
31+
- The `exact` scheme on EVM networks (`eip155:*`) using EIP-3009
32+
`transferWithAuthorization`, protocol v1 and v2.
33+
34+
### Not supported (rejected with a clear error)
35+
36+
- The Permit2 asset transfer method (`extra.assetTransferMethod: "permit2"`) and its gas-sponsoring
37+
extensions. An EIP-3009 option on the same asset is preferred when offered; a Permit2-only offer
38+
is reported as unsupported. Signing a Permit2 authorization is a separate flow.
39+
- Other schemes such as `upto`, and non-EVM networks (e.g. Solana).
40+
- Offers that omit the EIP-712 domain `name`/`version` in `extra`. The reference client falls back
41+
to reading them on-chain; this script does not, so it asks for an offer that includes them rather
42+
than risk signing the wrong domain.
2543

2644
## Usage
2745

46+
`scripts/x402_pay.py` is a helper script (not an `mm` subcommand). Two things follow from that:
47+
call it by its **full path inside this skill's directory**, since the shell's working directory is
48+
not stable between commands and a bare `scripts/x402_pay.py` will not be found; and **do not pass
49+
the global `--toon`/`--format` flags** to it, as it always prints JSON (it accepts and ignores them
50+
if passed). Let `SKILL_DIR` be this skill's base directory (the folder containing `SKILL.md`).
51+
2852
Inspect first (read-only: no signing, no spending), show the result to the user, then pay.
2953

3054
```bash
31-
python3 scripts/x402_pay.py inspect <url> [--method M] [--data BODY]
32-
python3 scripts/x402_pay.py pay <url> --confirm [--method M] [--data BODY] [--asset <contract>] [--network <network>]
55+
python3 "$SKILL_DIR/scripts/x402_pay.py" inspect <url> [--method M] [--data BODY]
56+
python3 "$SKILL_DIR/scripts/x402_pay.py" pay <url> --confirm [--method M] [--data BODY] [--asset <contract>] [--network <network>]
3357
```
3458

3559
`inspect` prints the payment requirement(s) as JSON, including the human-readable amount, asset
@@ -44,9 +68,9 @@ same as a `GET`. `--data` defaults to a JSON content type, overridable with `--c
4468
### Example
4569

4670
```bash
47-
python3 scripts/x402_pay.py inspect https://api.example.com/premium
71+
python3 "$SKILL_DIR/scripts/x402_pay.py" inspect https://api.example.com/premium
4872
# review the amount / payTo / resource with the user, then:
49-
python3 scripts/x402_pay.py pay https://api.example.com/premium --confirm
73+
python3 "$SKILL_DIR/scripts/x402_pay.py" pay https://api.example.com/premium --confirm
5074
```
5175

5276
## What the script checks

0 commit comments

Comments
 (0)