📺 Explainer video + demo walkthrough
A demo app showing both sides of the x402 protocol (HTTP 402 payments) — a buyer that pays for APIs with USDC, and a seller that charges for an API endpoint. All powered by automatic micropayments on Base.
This project contains two HTTP endpoints that share the same wallet
(X402_PRIVATE_KEY):
| App | File | Role | Description |
|---|---|---|---|
| Buyer | buyer.tsx | Pays for APIs | Web UI that calls paid x402 endpoints using @x402/fetch |
| Seller | seller.tsx | Charges for an API | Hono app with @x402/hono middleware protecting GET /api/random |
Since both use the same wallet, calling the seller from the buyer sends $0.001 USDC from yourself to yourself — a perfect zero-cost demo loop. Gas is sponsored by the xpay facilitator (Base L2 gas costs fractions of a penny, so facilitators subsidize it to drive adoption of x402).
Rendering mermaid diagram...
Rendering mermaid diagram...
buyer.tsx → HTTP entry point for buyer app (Hono router)
seller.tsx → HTTP entry point for seller app (Hono + x402 middleware)
routes/
home.tsx → Buyer landing page with screenshot & random number forms
screenshot.tsx → Screenshot form + POST handler (pays Browserbase)
random.tsx → Random number handler (pays our own seller.tsx)
transactions.tsx → Transaction history table
lib/
x402.ts → x402 client setup (wallet signer + wrapFetchWithPayment)
browserbase.ts → Browserbase session creation via x402
screenshot.ts → Playwright CDP screenshot capture
db.ts → SQLite schema & queries for transaction log
layout.tsx → Shared HTML layout with Twind CSS
| Key | Description |
|---|---|
X402_PRIVATE_KEY | Private key for a Base wallet holding USDC (used by both buyer and seller) |
| Route | Description |
|---|---|
/ | Home — screenshot form, random number button, wallet info |
/screenshot | Capture a website screenshot ($0.01 USDC via Browserbase) |
/random | Get a random number ($0.001 USDC via our seller) |
/transactions | Table of past payments with totals and tx hashes |
| Route | Description |
|---|---|
/ | Homepage explaining the API and pricing |
/api/random | Paid endpoint — returns { random: Math.random() } for $0.001 USDC |
eip155:8453)To run this yourself, you need a Base wallet with USDC and its private key. Here's how to set one up:
X402_PRIVATE_KEY in your val's environment variables0x — the key exported from
Coinbase Wallet doesn't include it, but viem expects it