Developer Documentation

Build with
BagsPay

Add x402 payment gating to any API in 10 lines. Accept USDC on Solana with automatic fee sharing to $BAGS holders.


Quick Start

Protect any Hono route with x402 payments. When a request comes in without payment, the middleware returns HTTP 402. When a valid payment is attached, the request passes through.

import { Hono } from "hono"; import { bagspay } from "@bagspay/server"; const app = new Hono(); // This route now requires 0.01 USDC per request app.use("/api/premium/*", bagspay({ price: { amount: "0.01", asset: "USDC" }, payTo: "YOUR_SOLANA_WALLET", facilitatorUrl: "https://facilitator.bagspay.fun", })); app.get("/api/premium/data", (c) => { const payer = c.get("bagspay_payer"); return c.json({ data: "premium content", paidBy: payer }); });

Installation

bun add @bagspay/server # For merchants (accept payments) bun add @bagspay/client # For agents (make payments) bun add @bagspay/core # Shared types & utilities

bagspay() Middleware

The server middleware intercepts requests, checks for an X-PAYMENT header, and settles payments via the facilitator.

ParameterTypeDescription
price.amountstringPrice per request in human units (e.g., "0.01")
price.assetstring"USDC", "SOL", or a token mint address
price.networkstring?CAIP-2 network ID. Defaults to Solana mainnet
payTostringYour Solana wallet address (base58)
facilitatorUrlstringURL of the BagsPay facilitator service
descriptionstring?Human-readable description of what's being paid for
feesFeeConfig?Custom fee split in basis points (default: 97/2/1)

Subscriptions

Recurring payments with off-chain subscription tracking. The first request charges immediately, subsequent requests check subscription status.

import { bagspaySubscription } from "@bagspay/server"; app.use("/api/pro/*", bagspaySubscription({ plan: "pro-monthly", name: "Pro Plan", price: { amount: "5.00", asset: "USDC", interval: "monthly" }, payTo: "YOUR_WALLET", facilitatorUrl: "https://facilitator.bagspay.fun", }));

Fee Configuration

Every payment splits fees automatically via Bags Fee Share V2. The default split is 97% merchant / 2% $BAGS vault / 1% treasury. Customize with basis points (10000 = 100%):

app.use("/api/*", bagspay({ price: { amount: "0.05", asset: "USDC" }, payTo: "YOUR_WALLET", facilitatorUrl: "https://facilitator.bagspay.fun", fees: { merchantBps: 9500, // 95% bagsVaultBps: 400, // 4% treasuryBps: 100, // 1% }, }));

BagsPayClient

For AI agents and apps that need to pay for x402-protected resources. The client automatically handles 402 responses, signs payments, and retries.

import { BagsPayClient, keypairAdapter } from "@bagspay/client"; import { Keypair } from "@solana/web3.js"; const client = new BagsPayClient({ wallet: keypairAdapter(Keypair.generate()), rpcUrl: "https://mainnet.helius-rpc.com/?api-key=YOUR_KEY", maxAutoPayAmount: "1000000", // Max 1 USDC per request (in base units) }); // This automatically: gets 402 -> signs payment -> retries -> returns 200 const res = await client.fetch("https://api.example.com/premium/data"); const data = await res.json();
ParameterTypeDescription
walletWalletAdapterSolana wallet for signing payments
rpcUrlstringSolana RPC endpoint
maxAutoPayAmountstring?Spending limit per request (base units)
autoPayboolean?Auto-pay 402 responses (default: true)
maxPaymentRetriesnumber?Max payment attempts (default: 1)

Wallet Adapters

// For AI agents (headless, no UI) import { keypairAdapter } from "@bagspay/client"; const wallet = keypairAdapter(myKeypair); // For browser apps (Phantom, Solflare, etc.) // Implement the WalletAdapter interface: interface WalletAdapter { publicKey: string; signTransaction(tx: Transaction): Promise<Transaction>; }

Facilitator: POST /settle

Verify a payment and broadcast it to Solana. Called by the server middleware automatically.

POST /settle Content-Type: application/json { "payload": { "x402Version": 1, "scheme": "exact", "network": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", "payload": { "transaction": "<base64-encoded-signed-tx>", "payer": "<base58-wallet-address>" } }, "requirement": { "scheme": "exact", "network": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", "maxAmountRequired": "10000", "payTo": "<merchant-wallet>", "asset": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "maxTimeoutSeconds": 60 } }

POST /verify

Validate a payment without broadcasting. Returns { valid: true/false }.

GET /supported

List supported schemes and networks.

{ "schemes": ["exact"], "networks": ["solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1"] }

GET /health

Health check with Solana RPC and database latency.

{ "status": "healthy", "checks": { "solanaRpc": { "ok": true, "latencyMs": 45 }, "database": { "ok": true, "latencyMs": 1 } } }

Register an Agent on the Marketplace

List your AI agent so others can pay to use it. Every call generates $BAGS fees for holders.

curl -X POST https://marketplace.bagspay.fun/agents/register \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_ADMIN_KEY" \ -d '{ "id": "my-agent", "name": "My Agent", "description": "Does something useful", "pricePerCall": "0.01", "monthlyPrice": "5.00", "endpoint": "https://my-agent.example.com/api" }'
FieldRequiredDescription
idYesLowercase alphanumeric with hyphens, max 64 chars
nameYesDisplay name for the agent
descriptionYesWhat the agent does
pricePerCallYesUSDC price per call (e.g., "0.01")
monthlyPriceNoMonthly subscription price in USDC
endpointNoHTTPS URL your agent listens on

BagsPay - x402 Payment Infrastructure for Solana. Built for the Bags Hackathon.