A2A-compliant agent server with x402 V2 cryptocurrency micropayments. Screenshots, PDFs, and document generation — pay per request with USDC on Base + SKALE.
- /.well-known/agent.json alias for agent-card.json - POST /a2a alias for POST / - tasks/send method alias for message/send - Standalone HTTP 402 endpoints at /x402/screenshot and /x402/pdf Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|---|---|---|
| public | ||
| .gitignore | ||
| package.json | ||
| README.md | ||
| server.mjs | ||
| SUBMISSION.md | ||
| test.mjs | ||
A2A x402 Gateway
Pay-per-request AI agent services via A2A protocol + x402 V2 micropayments
An A2A-compliant agent server that exposes screenshot, PDF, and document generation services with x402 V2 cryptocurrency micropayments on Base + SKALE networks. Features SIWx session authentication for repeat access.
Built by OpSpawn for the SF Agentic Commerce x402 Hackathon.
Live Demo
- Demo Page: https://a2a.opspawn.com/demo
- Agent Card: https://a2a.opspawn.com/.well-known/agent-card.json
- Dashboard: https://a2a.opspawn.com/dashboard
- Demo Video: https://a2a.opspawn.com/public/demo-video.mp4
How It Works
Agent Client → A2A Gateway → 402: Pay USDC → Service Delivery
- Agent sends A2A message (JSON-RPC over HTTP)
- Gateway returns payment requirements (x402 payment details for paid skills)
- Agent signs USDC transfer on Base network
- Gateway delivers result (screenshot, PDF, or HTML)
Agent Skills
| Skill | Price | Description |
|---|---|---|
| Web Screenshot | $0.01 USDC | Capture any webpage as PNG |
| Markdown to PDF | $0.005 USDC | Convert markdown to styled PDF |
| Markdown to HTML | Free | Convert markdown to styled HTML |
Quick Start
npm install
npm start
Server starts on http://localhost:4002
Key Endpoints
GET /.well-known/agent-card.json— A2A agent discoveryPOST /— A2A JSON-RPC endpoint (message/send, tasks/get, tasks/cancel)GET /x402— x402 service catalogGET /dashboard— Web dashboardGET /api/info— Agent info + payment detailsGET /api/payments— Payment event log
Protocol Details
A2A Protocol (v0.3)
This server implements the Agent-to-Agent Protocol specification:
- AgentCard at
/.well-known/agent-card.jsonfor agent discovery - JSON-RPC 2.0 message format
- Task lifecycle: submitted → working → completed/failed/input-required
- Skills with input/output modes and pricing metadata
x402 V2 Payment Protocol
Payment requirements are returned via A2A task metadata using x402 V2 with CAIP-2 network IDs:
{
"x402.payment.required": true,
"x402.version": "2.0",
"x402.accepts": [{
"scheme": "exact",
"network": "eip155:8453",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"payTo": "0x7483a9F237cf8043704D6b17DA31c12BfFF860DD",
"maxAmountRequired": "10000",
"price": "$0.01"
}, {
"scheme": "exact",
"network": "eip155:324705682",
"gasless": true
}]
}
To pay, resend the message with payment proof in metadata:
{
"metadata": {
"x402.payment.payload": {
"scheme": "exact",
"network": "base",
"signature": "0x..."
}
}
}
Example: A2A Client
Free Skill (Markdown to HTML)
const response = await fetch('http://localhost:4002', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
id: '1',
method: 'message/send',
params: {
message: {
messageId: 'msg-1',
role: 'user',
kind: 'message',
parts: [{ kind: 'text', text: '# Hello World\n\nConverted by A2A agent.' }],
},
configuration: { blocking: true },
},
}),
});
const { result } = await response.json();
// result.status.state === 'completed'
// result.status.message.parts[1].data.html contains the HTML
Paid Skill (Screenshot)
// Step 1: Send request (returns payment-required)
const r1 = await fetch('http://localhost:4002', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0', id: '2', method: 'message/send',
params: {
message: {
messageId: 'msg-2', role: 'user', kind: 'message',
parts: [{ kind: 'text', text: 'Screenshot https://example.com' }],
},
configuration: { blocking: true },
},
}),
});
const { result: task } = await r1.json();
// task.status.state === 'input-required'
// task.status.message includes x402 payment requirements
// Step 2: Sign payment with ethers.js and resend with payment proof
// (See a2a-x402 npm package for client-side payment signing)
Architecture
┌─────────────┐ A2A JSON-RPC ┌──────────────┐ HTTP ┌──────────┐
│ Agent Client │ ──────────────────── │ A2A Gateway │ ─────────── │ SnapAPI │
│ (any LLM) │ │ (port 4002) │ │ (port 3001)│
└─────────────┘ └──────────────┘ └──────────┘
│
x402 Payment
│
┌──────────────┐
│ Base Network │
│ (USDC) │
└──────────────┘
Tech Stack
- Runtime: Node.js 22
- Protocol: A2A v0.3 (JSON-RPC 2.0 over HTTP)
- Payments: x402 V2 (SDK v2.3.0) on Base + SKALE (USDC)
- Auth: SIWx (CAIP-122 wallet sessions)
- Backend: Express 5
- Facilitator: PayAI (facilitator.payai.network)
- Services: SnapAPI (Puppeteer + Chrome)
Tests
npm start &
npm test
19 tests covering:
- Health check and agent card discovery
- x402 service catalog
- Free skill execution (markdown → HTML)
- Paid skill payment requirements (screenshot, PDF)
- Payment submission and service delivery
- Task lifecycle (get, cancel)
- Error handling (invalid requests, unknown methods)
Configuration
| Environment Variable | Default | Description |
|---|---|---|
PORT |
4002 | Server port |
SNAPAPI_URL |
http://localhost:3001 | Backend SnapAPI URL |
SNAPAPI_API_KEY |
demo-key-001 | SnapAPI authentication key |
License
MIT