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.