Capture every X-PAYMENT exchange to JSONL. Optional --reconcile joins against Base USDC Transfer events to detect the #1062 gap in real time.
$ x402trace proxy --port 8402 \
--upstream http://localhost:3000 \
--reconcileDetects timeout-reconciliation gaps, validates Bazaar listings, diffs facilitators, and explains 402s. Read-only. Runs on your laptop. No keys handled.
$ npx x402trace proxy --reconcile --log payments.jsonl [14:23:08] proxy listening :8402 upstream=https://api.example.com [14:23:12] X-PAYMENT received id=35d9aea1 payer=0xADEe…B895 [14:23:12] /verify → {200} payer=0xADEe…B895 [14:23:13] /settle → {200} success=true [14:23:25] upstream timeout {502} id=35d9aea1 [14:23:31] chain.Transfer matched tx=0x116ccf73…ba52 value=1000 {RECONCILED ⚠ settled-but-server-thinks-not id=35d9aea1} tx=0x116ccf73…ba52 value=1000 gap=11904ms payer=0xADEe…B895 → payee=0xADEe…B895
Your buyer signs an EIP-3009 authorization. The facilitator settles on-chain. Your upstream times out. The buyer's wallet is debited and your server thinks nothing happened.
14:23:12 POST /paid-endpoint → pending 14:23:12 facilitator.verify 200 14:23:13 facilitator.settle 200 14:23:25 upstream timeout (10s) 14:23:25 response 502 Bad Gateway # nothing to reconcile. user retries. user # pays twice. support ticket arrives Monday.
14:23:12 X-PAYMENT received id=35d9aea1 14:23:13 /settle 200 14:23:25 upstream 502 14:23:31 chain.Transfer matched tx=0x116c…ba52 {RECONCILED ⚠ settled-but-server-thinks-not} id=35d9aea1 gap=11904ms value=1000 (=$0.001 USDC) → refund flow or replay upstream
Same payment. Different conclusions. Reconciled by coinbase/x402#1062.
x402trace intercepts X-PAYMENT exchanges, captures them to JSONL, and joins them against the chain. Your service code does not change.
Each runs locally. None handles keys. All read-only. Two more (inspect, versions) in --help.
Capture every X-PAYMENT exchange to JSONL. Optional --reconcile joins against Base USDC Transfer events to detect the #1062 gap in real time.
$ x402trace proxy --port 8402 \
--upstream http://localhost:3000 \
--reconcilePre-flight a wallet against a service's 402 challenge. With --diff, runs the payload through multiple facilitators in parallel and surfaces drift.
$ x402trace validate \
--diff cdp,xpay,x402.org \
<wallet> <service-url>Plain-English diagnosis of a captured JSONL log. 15 rules cover CDP min-amount, self-payment, throttling, missing EXTENSION-RESPONSES, gas-estimation failure, and more.
$ x402trace explain payments.jsonlValidates .well-known/x402, extensions.bazaar, and the indexing query. Returns one of looks_correct / implementation_issue / upstream_issue (#2207).
$ x402trace bazaar-check https://my-service.example.comThe explain subcommand runs every rule against your JSONL log. No network calls.
src/diagnose/rules.tscdpMinAmountRuleCDP facilitator rejects amounts below $0.001 USDC.
selfPaymentRulePayer address equals payee address.
facilitatorThrottlingRule403/429 without a documented rate limit.
extensionResponsesMissingRuleSettle succeeded but EXTENSION-RESPONSES header absent (#2207).
gasEstimationFailureRuleIntermittent "unable to estimate gas" on Base mainnet (#1065).
One canonical demo. Two more reconciliations linked from the README.
Three commands. The last runs the canonical Base Sepolia demo end-to-end against a funded test wallet.
Requires Node ≥20 and pnpm. Demo wallet setup in examples/README.md.
# 1. Install + run $ npx x402trace --version # 2. Diagnose a captured log $ x402trace explain ./payments.jsonl # 3. Run the canonical Base Sepolia demo $ git clone https://github.com/fardinvahdat/x402trace.git $ cd x402trace && pnpm install $ ./examples/e2e-timeout-reconciliation.sh
You need a hosted dashboard or multi-tenant SaaS.
x402trace is local-only.
You're paying on a chain other than Base.
x402trace is Base-only.
You want a wallet, a facilitator, or a payment SDK.
x402trace is none of those — use x402.