A self-hosted store with x402 checkout. Digital goods delivered in the paid response; physical goods confirmed with signed fulfillment records. Pay in USDC on Base or Solana — your client picks the rail. No accounts.
git clone https://github.com/nirholas/x402-storefront && cd x402-storefront && npm install && npm run dev| Route | Price | You get back |
|---|---|---|
GET /catalog | free | Items, prices, buy routes |
GET /buy/guide-agentic-commerce | $0.05 | Signed download grant + license (markdown guide) |
GET /buy/dataset-http-402 | $0.02 | Signed download grant + license (JSON dataset) |
GET /buy/art-payment-required | $0.01 | Signed download grant + license (SVG art) |
GET /buy/stickers-x402 | $0.10 | Signed order confirmation + fulfillment record |
GET /buy/tee-pay-per-call | $0.25 | Signed order confirmation + fulfillment record |
GET /download/:token | free | Purchased bytes (from a digital purchase) |
GET /verify | free | Signature check for any artifact |
All items and prices are configured in config/catalog.json — paid routes are generated from it.
Every 402 lists both networks. A buyer holding USDC on Base pays on Base; a buyer holding USDC on Solana pays on Solana. Same route, same artifact, same price.
base-sepolia by default, base for mainnet. EIP-3009 transfer authorization.
0x40252CFDF8B20Ed757D61ff157719F33Ec332402
solana mainnet by default, solana-devnet for testing. SPL transfer.
WwwuGbqHrwF5RG89KhUbmRWEvjnRH9k5kVM5p7T3WwW
X-PAYMENT# 1. Run the store
cp .env.example .env # ships with working payTo addresses for both rails
npm run dev # http://localhost:4021
# 2. See the dual-rail 402 quote (no wallet needed)
curl -s http://localhost:4021/buy/art-payment-required \
| jq '.accepts[] | {network, payTo, maxAmountRequired}'
# 3. Buy for real on Base Sepolia (free test USDC: faucet.circle.com)
export PRIVATE_KEY=0x…
npm run client # pays, verifies signature, downloads the asset
The store ships a one-page checkout at / (see public/index.html)
built on the drop-in @three-ws/x402-payment-modal: every item gets a
Pay & buy button, and the signed artifact renders in-page after payment.
The modal reads both rails from the 402 challenge — Phantom for Solana, an injected
wallet for Base — and ships SIWX re-entry plus per-site spending caps.
Run npm run dev and open localhost:4021.