Pay-per-request access to Fuse Network blockchain data and business payment infrastructure. The same endpoints accept payment over two protocols simultaneously:
- x402 — USDC on Base via the x402 protocol, settled by the Coinbase CDP facilitator. Payable from any x402 client, including the Solid Agent Wallet and the Coinbase Agentic Wallet.
- MPP (Machine Payments Protocol, co-authored by Tempo
and Stripe) — three rails on one wire:
- Tempo USDC (stablecoin, sub-second finality on Tempo mainnet
4217/ Moderato testnet42431) - Stripe — Visa, Mastercard, and digital wallets via Stripe Shared Payment Tokens
- Bitcoin Lightning via Spark
- Tempo USDC (stablecoin, sub-second finality on Tempo mainnet
Both protocols cohabit a single 402 response: x402 clients read
X-PAYMENT-REQUIRED, MPP clients read WWW-Authenticate: Payment (one entry
per method). See src/middleware/dual-pay.ts for
the dispatch + composite-challenge logic.
- URL: https://ai.fuse.io
- x402 settlement: Base mainnet (eip155:8453), USDC
- MPP settlement: Tempo (testnet by default), Stripe (USD), Lightning (BTC)
- Data network: Fuse mainnet (chain 122) via explorer.fuse.io Blockscout + viem
| Method | Path | Price | Description |
|---|---|---|---|
| GET | /api/fuse/stats |
$0.01 | Real-time Fuse network statistics from Blockscout. |
| GET | /api/fuse/wallet/:address |
$0.05 | Balance, tx count, token-transfer count, last activity for any Fuse wallet. |
| GET | /api/fuse/defi/opportunities |
$0.10 | Live Fuse-chain DeFi products (DefiLlama TVL + Solid.xyz APY windows). |
| POST | /api/fuse/loyalty/create |
$5.00 | Deploys a real LoyaltyToken ERC-20 (mintable, burnable, owner + minter ACL) on Fuse via viem. Caller is the owner. |
| POST | /api/fuse/loyalty/mint |
$0.50 | Mints additional units of an existing LoyaltyToken (requires the deployer still holds the minter role). |
| GET | /api/fuse/loyalty/balance/:token/:address |
$0.02 | Reads any Fuse ERC-20 balance via viem. |
Free routes:
GET /health— health checkGET /openapi.json— OpenAPI 3.1.0 spec. Each paid operation carries:x-payment-info.price+x-payment-info.protocols(x402scan-flavored)x-payment-info.offers[]— one entry per MPP method (tempo / stripe / lightning) so MPP-aware agents can pre-select before issuing the request
GET /.well-known/x402— well-known v1 discovery fallback
Document root also exposes x-service-info (categories + docs links) per the
MPP discovery spec.
/loyalty/create deploys a token on the caller's behalf:
- The caller's
owneraddress (passed in the request body) becomes the on-chain owner and receives the initial supply. - This service's deployer wallet is seeded as an initial minter so
/loyalty/mintworks out of the box. - The owner can revoke the server's mint privilege at any time by calling
setMinter(deployerAddress, false)on the token contract. After that,/loyalty/mintwill revert for that token.
This service never holds the owner role and cannot transfer ownership, pause, or burn caller-owned tokens.
- TypeScript on Node 20+ (run with
tsx) - express 5.x
- x402 path: @x402/express, @x402/core, @coinbase/x402
- MPP path: mppx (wevm), stripe, @buildonspark/lightning-mpp-sdk
- viem — Fuse RPC + ERC-20 reads/writes + contract deployment
- zod — request validation
- Blockscout REST API at
explorer.fuse.io, DefiLlama, Solid Analytics
-
Copy
.env.exampleto.envand fill in the required values.x402 (always required):
PAY_TO_WALLET— wallet that receives x402 USDC payments on Base.CDP_API_KEY_ID/CDP_API_KEY_SECRET— Coinbase CDP credentials (https://portal.cdp.coinbase.com).DEPLOYER_PRIVATE_KEY— Fuse-mainnet EOA used to deploy loyalty tokens and mint on the caller's behalf. Needs a small FUSE balance for gas.
MPP (required when
MPP_ENABLED=true, which is the default):MPP_SECRET_KEY— HMAC key binding challenge IDs to contents. Generate once withnode -e "console.log(require('crypto').randomBytes(32).toString('base64'))". Treat as root-of-trust.TEMPO_PAY_TO— recipient address on Tempo (testnet Moderato or mainnet, selected byTEMPO_TESTNET).STRIPE_SECRET_KEY—sk_test_…for development,sk_live_…in prod. Stripe account must have machine payments enabled.STRIPE_NETWORK_ID— Business Network profile ID from the Stripe Dashboard.BTC_MNEMONIC— server-side Spark wallet seed for Lightning. UseBTC_NETWORK=regtestfor local dev (free),signetfor public testnet,mainnetfor real BTC.
To ship MPP code dark, set
MPP_ENABLED=false— all MPP env vars become optional and the server runs in x402-only mode (current production behavior). -
Install + run:
pnpm install pnpm dev # tsx watch pnpm test # patches/extensions-forward smoke test pnpm build # tsc --noEmit (typecheck only)
pnpm start runs the same TypeScript entry under tsx without a build
step.
x402 (Base USDC) — fund PAY_TO_WALLET with USDC on Base for receiving;
no inbound funding needed (clients pay you).
Tempo testnet (Moderato, chain 42431) — get free test stablecoins (pathUSD / AlphaUSD / BetaUSD / ThetaUSD) for any address at docs.tempo.xyz/quickstart/faucet.
Tempo mainnet (chain 4217) — bridge USDC from Ethereum / Base / Arbitrum
/ Optimism / Polygon via relay.link/bridge. The
default mainnet token is USDC.e at 0x20C000000000000000000000b9537d11c60E8b50.
Stripe — no wallet, payments land directly in the connected Stripe account.
Lightning — for testing, use the Spark testnet faucet; for production,
the server's Spark wallet (seeded by BTC_MNEMONIC) needs no inbound balance
since each payment generates a fresh BOLT11 invoice paid by the client.
Deployed on Vercel behind the ai.fuse.io custom domain. Configure all
secrets as Vercel environment variables for the Production environment —
nothing is hardcoded in vercel.json.
Entry point: src/index.ts (compiled by @vercel/node).
Each protected route returns a 402 challenge until a valid X-PAYMENT
header is presented. Example with curl:
curl -i https://ai.fuse.io/api/fuse/statsFor real consumption use a wallet-aware client such as the Solid Agent Wallet or the Coinbase Agentic Wallet — both sign the 402 challenge and resend automatically, settling in USDC on Base.
MPP clients read the WWW-Authenticate: Payment … headers on the 402, pick
a method, sign a credential, and resend with Authorization: Payment …. The
mppx CLI does this automatically:
npx mppx pay https://ai.fuse.io/api/fuse/statsDiscovery: agents can fetch /openapi.json and pre-select a method from
x-payment-info.offers[] before issuing the request, avoiding the
challenge round-trip.
┌──────────────────────────────────┐
request ───▶│ src/middleware/dual-pay.ts │
│ │
│ ┌─ Authorization: Payment │
│ │ → mpp.compose() verify │
│ │ → req.__mppPaid = true │
│ │ │
│ ├─ X-PAYMENT │
│ │ → next() (let x402 run) │
│ │ │
│ └─ (no creds) │
│ → pre-build MPP challenges, │
│ hook res.writeHead to add │
│ WWW-Authenticate on 402 │
└─────────────┬────────────────────┘
│ next()
▼
┌──────────────────────────────────┐
│ @x402/express paymentMiddleware │
│ (skipped if __mppPaid) │
└─────────────┬────────────────────┘
│ paid?
▼
┌──────────────────────────────────┐
│ route handler (stats / wallet / │
│ defi / loyalty.*) │
└──────────────────────────────────┘
Single source of truth for the route → price table lives in
PAID_ROUTES at the top of src/index.ts.