Skip to content

Conversation

@kamiyo-ai
Copy link

Summary

Adds x402 (HTTP 402 Payment Required) support to ShadowWire, enabling privacy-preserving API monetization with Bulletproof-shielded payments.

  • Client: X402Client class that detects 402 responses, pays via ShadowWire transfer, and retries with an X-Payment header
  • Server: x402Paywall() Express middleware that gates routes behind payment, delegating verification and settlement to an external facilitator
  • Discovery: createDiscoveryDocument() for .well-known/x402 endpoint generation
  • Hardening: Cross-platform base64 (Node + browser), fetch timeouts via AbortController, 16KB header size limits, early proof validation in middleware

New exports

Export Type Purpose
X402Client class Payer-side: request → 402 → pay → retry
x402Paywall function Express middleware for paid endpoints
createPaymentRequired function Build 402 response bodies
verifyPayment function Verify payment via facilitator
settlePayment function Settle payment via facilitator
createDiscoveryDocument function Generate .well-known/x402

Payment flow

Client                    Server                  Facilitator
  │                         │                         │
  ├─ GET /api/data ────────►│                         │
  │◄── 402 + requirements ──┤                         │
  │                         │                         │
  ├─ ShadowWire transfer ──►│                         │
  │                         │                         │
  ├─ GET /api/data ────────►│                         │
  │   + X-Payment header    ├─ POST /verify ─────────►│
  │                         │◄── { isValid: true } ───┤
  │                         ├─ POST /settle ─────────►│
  │                         │◄── { success: true } ───┤
  │◄── 200 + data ──────────┤                         │

New shadowwire scheme

The x402 accepts array includes a shadowwire scheme alongside the standard exact scheme, advertising Bulletproof-based private payments with amount hiding.

Test plan

  • npm run build passes clean
  • Client: X402Client.request() handles non-402, 402 with payment, and 402 rejection flows
  • Client: pay() rejects non-shadowwire schemes before initiating transfer
  • Middleware: returns 402 with correct headers when no X-Payment present
  • Middleware: rejects oversized headers (>16KB) with 400
  • Middleware: rejects invalid/non-shadowwire proofs before calling facilitator
  • Middleware: verifies and settles via facilitator, attaches req.x402
  • Encoding: encodePaymentHeader / decodePaymentHeader round-trip correctly
  • Browser: base64 helpers work without Node Buffer

Verify endpoint: send {paymentHeader, resource, maxAmount} instead of
{paymentRequirements}, read `valid` not `isValid` from response.

Settle endpoint: send {paymentHeader, merchantWallet, amount, asset}
instead of {paymentRequirements}, read `txHash` not `transaction`.

Add X-API-Key header support (required by facilitator auth middleware).
Update example facilitator URL to x402.kamiyo.ai.
@kamiyo-ai
Copy link
Author

The verify and settle functions don't match the KAMIYO facilitator API contract. The requests will fail as-is. I pushed fixes to kamiyo-ai/ShadowWire@feat/x402-payment-protocol — here's what changed:

Verify endpoint (/verify)

  • Request body: {paymentHeader, resource, maxAmount} — not {x402Version, paymentHeader, paymentRequirements}
  • Response field: valid not isValid, error in error not invalidReason

Settle endpoint (/settle)

  • Request body: {paymentHeader, merchantWallet, amount, asset} — not {x402Version, paymentHeader, paymentRequirements}
  • Response field: txHash not transaction, plus amount, fee, net, network

Auth

  • All facilitator endpoints require X-API-Key header (maps to merchant wallet via api_keys table)
  • Added apiKey to X402MiddlewareConfig (required field)

Other

  • Updated X402VerifyResult to match actual response shape (balance, sufficient, resource)
  • Updated req.x402 in middleware to expose txHash, amount, fee, net, network instead of signature/amountHidden
  • Example facilitator URL: https://x402.kamiyo.ai

Commit: kamiyo-ai/ShadowWire@62fd190

Fix inverted content-type check in safeParseBody. Restrict
findCompatibleRequirement to shadowwire-only schemes. Add retry
backoff on 5xx after payment. Add Vary: X-Payment header to prevent
cache poisoning. Reject proof resource mismatch before calling
facilitator. Improve abort detection for non-DOM runtimes. Remove
unadvertised 'exact' scheme from discovery document.
- Add X402InvalidSchemeError, X402HeaderTooLargeError, X402FacilitatorError
- Replace generic error strings with typed errors in x402.ts
- Add JSDoc to public x402 exports
- Add vitest with 35 test cases covering encode/decode, request flow,
  middleware, verify/settle, and discovery document
- Fix Unicode-unsafe browser base64 (btoa/atob → TextEncoder path)
- Add x402Version validation in decodePaymentHeader
- Use URL API for facilitator endpoint composition
- Wrap onPayment callback in try/catch to prevent post-settlement crashes
- Split x402-payment.ts into focused x402-server.ts and x402-client.ts
Make facilitatorUrl optional in X402MiddlewareConfig with a built-in
default so SDK consumers don't need to specify it explicitly.
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