Charge agents in stablecoins, on-chain, with no humans in the loop. Multi-chain · replay-proof · fully typed end to end.
Quick start · How it works · Architecture · Contributing
Devnet walkthrough: sign in → live revenue → on-chain transactions → create an endpoint → mint an API key. (watch as MP4)
AI agents call millions of APIs every day, and almost none of them pay. Paygate is the missing payment layer for that agentic economy.
When an agent calls your API without paying, Paygate replies with HTTP 402 and
a signed, single-use payment challenge. The agent pays in USDC (on Solana or
Base), signs the request, and retries. Paygate verifies the signature and the
on-chain settlement, then your handler runs. Money goes straight to your wallet —
Paygate never custodies funds.
// three lines and your API charges agents per call
app.use(
paygate({
apiKey: process.env.PAYGATE_API_KEY!,
endpoints: { 'GET /api/weather': '0.001' }, // 0.001 USDC / call
}),
);| 🔒 Replay-proof by construction | Each payment is bound to one request via a server-issued single-use nonce and a payer signature over the request digest — on both managed and self-hosted paths. |
| 💸 Money is never a float | Integer base units (bigint) everywhere; decimal strings only on the wire. No rounding surprises billing real money. |
| 📜 One wire contract | Server, SDKs, and any future gateway import the same @paygate/protocol schemas. The 402 shape can't drift between implementations. |
| ⛓️ Pluggable chains | Solana and Base today behind a single Chain interface. Adding a chain is one register() call. |
| 📨 Durable webhooks | HMAC-signed, retried with backoff, and logged — delivered by a job queue, not fire-and-forget. |
| 🔑 Hardened by default | API keys hashed (sha-256), scoped & rotatable; JWT auth fails closed; validated typed config at boot. |
Agent Provider (paygate SDK) Paygate facilitator
│ GET /api/weather │ │
│ ──────────────────────────────▶ │
│ │ mint single-use challenge │
│ │ ────────────────────────────────▶
│ 402 { requirements } │ ◀────────────────────────────── │
│ ◀────────────────────────────── │
│ │
│ sign(digest) → pay USDC on-chain → build X-Payment payload │
│ │
│ GET /api/weather +X-Payment │ │
│ ──────────────────────────────▶ verify payload │
│ │ ────────────────────────────────▶
│ │ verify signature │
│ │ consume nonce (1× only) │
│ │ confirm transfer on-chain │
│ 200 { data } │ ◀── 200 valid ────────────────── │
│ ◀────────────────────────────── handler runs │
Two independent guards stop replay: the signature binding (can't reuse a payment on a different request) and the single-use nonce (can't reuse it on the same one). Full detail in ARCHITECTURE.md.
npm install paygateimport express from 'express';
import { paygate } from 'paygate/express';
const app = express();
app.use(
paygate({
apiKey: process.env.PAYGATE_API_KEY!, // from your Paygate account
endpoints: { 'GET /api/weather': '0.001' }, // 0.001 USDC per call
}),
);
app.get('/api/weather', (_req, res) => res.json({ city: 'São Paulo', temp: '28°C' }));
app.listen(3000);npm install paygate-agentimport { PaygateAgent, SolanaAgentWallet } from 'paygate-agent';
const agent = new PaygateAgent({
wallets: [new SolanaAgentWallet({ privateKey: process.env.SOLANA_KEY! })],
limits: { maxPerCall: 10_000n, maxPerDay: 1_000_000n }, // base units
});
// transparently handles 402 → signs → pays → retries
const res = await agent.fetch('https://api.example.com/api/weather');
console.log(await res.json());| Package | Path | Description |
|---|---|---|
@paygate/protocol |
packages/protocol |
Money, x402 wire contract (zod), signed request binding — the source of truth |
@paygate/chains |
packages/chains |
Solana + Base behind one Chain interface |
@paygate/db |
packages/db |
Canonical Prisma schema + client |
paygate |
packages/sdk |
Provider middleware (Express adapter) |
paygate-agent |
packages/agent |
Autonomous paying client (multi-chain wallets) |
@paygate/server |
apps/server |
Fastify gateway + x402 facilitator + webhook worker |
@paygate/dashboard |
apps/dashboard |
Next.js dashboard |
pnpm install
cp .env.example .env
docker compose up -d # postgres + redis
pnpm db:migrate # create schema
pnpm --filter @paygate/server dev # API → http://localhost:3001
pnpm --filter @paygate/server worker:dev # webhook worker
pnpm --filter @paygate/dashboard dev # dashboard → http://localhost:3000| Command | Description |
|---|---|
pnpm build |
Build every package (Turborepo) |
pnpm test |
Run all unit tests (Vitest) |
pnpm typecheck |
Strict type check across the workspace |
pnpm db:migrate |
Apply Prisma migrations |
| Layer | Technology |
|---|---|
| Protocol | x402 (HTTP 402 Payment Required) |
| Chains | Solana, Base — stablecoin (USDC) settlement |
| Server | Node.js · Fastify · TypeScript |
| Database | PostgreSQL · Prisma |
| Queue / cache | Redis · BullMQ |
| Dashboard | Next.js · Tailwind |
| Tooling | pnpm workspaces · Turborepo · Vitest |
Issues and PRs are welcome! Before opening a PR, please run:
pnpm build && pnpm test && pnpm typecheckAdding a new chain is just implementing the Chain interface in
@paygate/chains — see ARCHITECTURE.md.
MIT © Paygate contributors
