Architecture
- Agent discovers the Key0 service via
/.well-known/agent.jsonand requests access via A2A - Key0 issues an x402 challenge; agent pays USDC on Base
- Key0 verifies the on-chain transfer and notifies your backend
- Key0 issues a JWT (locally or via your backend) and returns it to the agent
- Agent uses the JWT to call your protected API directly
What This Example Demonstrates
Configuration Reference
Core Settings
Backend Communication
Storage
Gas Wallet and Refunds
Agent Card Metadata
Code Walkthrough
Storage Backend Selection
The service selects its storage layer at startup based on a single environment variable. Both backends implement the sameIChallengeStore and ISeenTxStore interfaces, so the rest of the code is storage-agnostic.
- Redis
- Postgres
SET NX for double-spend prevention. Best for low-latency, single-region deployments.Regardless of which storage backend you choose, the BullMQ refund cron always requires a Redis connection. If you use Postgres for storage, set
REDIS_URL or BULLMQ_REDIS_URL separately for the job queue.Auth Strategy Configuration
When Key0 communicates with your backend (to notify payments or request token issuance), it authenticates using one of three strategies:Token Issuance Modes
After payment verification, Key0 needs to issue a credential. The standalone service supports two modes:- Native (local JWT)
- Remote (delegate to backend)
Key0 signs a JWT locally using Your backend validates the token using the same
AccessTokenIssuer. The token includes the challenge ID, resource ID, plan ID, and transaction hash:KEY0_ACCESS_TOKEN_SECRET. Best when Key0 and your backend share a secret.Plan Catalog
The service defines a multi-tier pricing structure that agents discover via the A2A agent card:unitAmount, and the entire payment/verification/delivery flow proceeds automatically.
Payment Notifications
After a payment is verified and a credential is issued, Key0 notifies your backend so you can activate the subscription, update billing records, or trigger downstream workflows:The payment notification is fire-and-forget. If the backend is unreachable, the error is logged but the agent still receives their token. Design your backend to handle idempotent replays if needed.
Refund Cron Setup
The BullMQ-based refund cron automatically processes refunds for challenges that reached the PAID state but failed delivery. It runs on a configurable interval and only processes challenges older than a grace period:PAID -> REFUND_PENDING -> REFUNDED (or REFUND_FAILED), sending USDC back to the payer on-chain.
Running the Example
1
Start infrastructure
You need Redis running (required for BullMQ, and optionally for storage). If using Postgres for storage, start that as well.
2
Configure environment variables
Create a
.env file in the examples/standalone-service directory:3
Install dependencies
4
Start the service
Endpoints
Once running, the service exposes:Testing
Verify the agent card
Check health
Run a full payment flow
Point an agent at this service to run a complete discovery-to-payment-to-access flow.Test MCP discovery
Production Checklist
Before deploying to production:- Set
KEY0_NETWORK=mainnet - Use a strong, randomly generated
KEY0_ACCESS_TOKEN_SECRET(64+ characters) - Set
BACKEND_AUTH_STRATEGYtoshared-secretorjwt - Configure
KEY0_PUBLIC_URLto your actual domain - Set
KEY0_WALLET_PRIVATE_KEYto enable automatic refunds - Use a managed Redis (e.g., Upstash, ElastiCache) or managed Postgres
- Run behind a reverse proxy (nginx, Cloudflare) with TLS
- Set
KEY0_WALLET_ADDRESSto a dedicated payment-receiving wallet
Source code
examples/standalone-service/server.ts
