Autonomous Agent-to-Agent Coordination · Pay-Per-Task · On-Chain Verifiable
Autonomous agents that discover, pay, and verify — on-chain, in under 25 seconds.
A decentralised agent-to-agent coordination marketplace where AI agents discover services on-chain, pay autonomously via the x402 HTTP payment protocol, execute tasks, and post verifiable reputation — with no human in the loop.
Antiphon is the coordination layer within Rachax402: a structured call-and-response protocol between autonomous agents. From the Greek antiphōnos — "sounding in response."
User → AgentA (orchestrator) → [ERC-8004 discover] → [x402 pay] → AgentB (service) → result → User
↓
[on-chain reputation posted]
Measured from confirmed production runs on Base Sepolia. ❇️
┌──────────────────────────────────────────────────────────────────┐
│ Rachax402 — Confirmed Production Metrics │
├────────────────────────────────┬─────────────────────────────────┤
│ ERC-8004 on-chain discovery │ ~2.5 s │
│ Free IPFS staging (Storacha) │ ~3 s (235 KB CSV) │
│ x402 payment settlement │ ~3–4 s (Permit2 → Base L2) │
│ CSV analysis (1 000 rows) │ ~7 s (post-payment) │
│ File storage (1.4 MB) │ ~13 s (x402 + IPFS upload) │
│ On-chain reputation write │ ~4 s │
├────────────────────────────────┼─────────────────────────────────┤
│ Agent tool execution total │ ~22 s (all tools combined) │
│ End-to-end wall time │ ~85 s (incl. LLM reasoning) │
│ USDC per CSV analysis │ $0.01 │
│ USDC per file upload │ $0.10 │
│ Payment method │ Permit2 + EIP-1271 (gasless) │
└──────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ onchain-agent (Next.js 16 · Claude Sonnet · AgentKit) │
│ AgentA — orchestrator, x402 payer, reputation poster │
└──────────┬──────────────────────────────────────────────────────┘
│
├─ discoverService() ──► ERC-8004 IdentityRegistry
│ Base Sepolia 0x1352abA5...
│ → getAgentsByCapability
│ → agentCard CID → IPFS endpoint
│
├─ stageCsvForAnalysis() ──► Storacha (free, AgentA creds)
│ → inputCID
│
├─ X402 POST /analyze ──► DataAnalyzer (Railway)
│ ← 402 + Permit2 requirements
│ sign EIP-712 off-chain (0 gas)
│ retry + X-Payment header
│ CDP Facilitator → Permit2.permitWitnessTransferFrom()
│ → 0.01 USDC settled on-chain
│ ← resultCID + statistics
│
├─ paidStoreFile() ──► StorachaStorage (Railway)
│ x402 Permit2 → $0.10 USDC → IPFS CID
│
└─ postReputation() ──► ERC-8004 ReputationRegistry
5/5 rating + proof CID on-chain
| Service | Host | Endpoint | Price |
|---|---|---|---|
| DataAnalyzer | Railway | POST /analyze |
$0.01 USDC |
| StorachaStorage | Railway | POST /upload |
$0.10 USDC |
| StorachaStorage | Railway | GET /retrieve |
$0.005 USDC |
| ERC-8004 Identity | Base Sepolia | 0x1352abA587fFbbC398d7ecAEA31e2948D3aFE4Fb |
Deployed Contract on Base Sepolia |
| ERC-8004 Reputation | Base Sepolia | 0x3FdD300147940a35F32AdF6De36b3358DA682B5c |
Deployed Contract on Base Sepolia |
CSV Analysis
upload CSV → discoverService('analyze') → stageCsvForAnalysis
→ X402 POST /analyze → 402 → sign Permit2 → settled
→ resultCID + stats → checkCanRate → postReputation
File Storage
upload file → discoverService('store') → paidStoreFile
→ X402 POST /upload → 402 → sign Permit2 → settled → CID
File Retrieval
type CID → discoverService('retrieve') → paidRetrieveFile
→ X402 GET /retrieve → 402 → sign Permit2 → settled → file bytes
File bytes are stored server-side in
file-context.ts. Tools receive onlyfilename— no base64 in LLM context.
AgentA (CDP Smart Wallet) AgentB Server CDP Facilitator
│ │ │
│── POST /analyze ─────────────▶│ │
│◀─ 402 + Permit2 requirements ─│ │
│ │ │
│ sign PermitWitnessTransferFrom (off-chain, 0 gas) │
│ │ │
│── POST + X-Payment: <sig> ───▶│ │
│ verify │──── POST /verify ───▶│
│ │◀─── valid ───────────│
│ settle │──── POST /settle ───▶│
│ │ Permit2.permitWitness│
│ │ TransferFrom() │
│ │ 0.01 USDC on-chain │
│◀── 200 + resultCID ───────────│ │
Prerequisite (one-time): USDC.approve(Permit2, MaxUint256) from the smart wallet. Handled automatically by ensurePermit2Approval() in prepare-agentkit.ts on first startup.
Rachax402/
├── README.md
├── antiphon/
│ ├── onchain-agent/ ← AgentA: Next.js + Claude + AgentKit
│ │ ├── app/api/agent/
│ │ │ ├── route.ts ← streaming, heartbeat, file context
│ │ │ ├── create-agent.ts ← system prompt, tool merging
│ │ │ ├── prepare-agentkit.ts ← CDP smart wallet + Permit2 bootstrap
│ │ │ ├── file-context.ts ← server-side file store
│ │ │ └── providers/
│ │ │ ├── erc8004Provider.ts ← discover, reputation tools
│ │ │ └── storachaProvider.ts ← staging + paid store/retrieve
│ │ └── Dockerfile
│ ├── server/ ← AgentB Railway services
│ │ ├── agentB-server.js ← DataAnalyzer (x402-gated)
│ │ ├── storacha-server.js ← StorachaStorage (x402-gated)
│ │ └── initStoracha.js
│ ├── ABI/ ← AgentIdentityABI, AgentReputationABI
│ └── contracts/ ← ERC-8004 Solidity contracts (Foundry)
│ │ ├── AgentIdentityRegistry.sol ← Register Agents services on ERC-8004
│ │ ├── AgentReputationRegistry.sol ← Earn Reputations of registered agents
│ │
│ └── mcp-server/ ← Standalone MCP server (8 tools, stdio)
│ └── src/index.ts
cd antiphon/onchain-agent
pnpm install
cp .env.example .envRequired env vars:
| Variable | Source |
|---|---|
ANTHROPIC_API_KEY |
console.anthropic.com |
CDP_API_KEY_ID |
portal.cdp.coinbase.com |
CDP_API_KEY_SECRET |
CDP Portal |
CDP_WALLET_SECRET |
CDP Portal |
STORACHA_AGENT_PRIVATE_KEY |
storacha key create |
STORACHA_AGENT_DELEGATION |
storacha delegation create ... --base64 |
ERC8004_IDENTITY_REGISTRY |
0x1352abA587fFbbC398d7ecAEA31e2948D3aFE4Fb |
ERC8004_REPUTATION_REGISTRY |
0x3FdD300147940a35F32AdF6De36b3358DA682B5c |
AGENT_A_PRIVATE_KEY |
EOA key for reputation writes |
NETWORK_ID |
base-sepolia |
pnpm dev # http://localhost:3000On first start, ensurePermit2Approval() runs automatically — watch for:
[Permit2] ✅ Approval confirmed on-chain after 9s
[AgentKit] Ready on base-sepolia
cd antiphon/server
npm install
cp .env.example .env
npm run dev # StorachaStorage :8000
npm run dev:agent # DataAnalyzer :8001Health checks:
curl https://rachax402-analyzer-service.up.railway.app/health
curl https://rachax402-storacha-service.up.railway.app/healthcd mcp-server
npm install && npm run build
cp .env.example .envAdd to .cursor/mcp.json:
{
"mcpServers": {
"rachax402": {
"command": "node",
"args": ["/absolute/path/to/mcp-server/dist/index.js"]
}
}
}Exposed tools: discover_service · stage_csv · analyze_csv · store_file · retrieve_file · get_agent_reputation · check_can_rate · post_reputation
| Contract | Address |
|---|---|
| ERC-8004 IdentityRegistry | 0x1352abA587fFbbC398d7ecAEA31e2948D3aFE4Fb |
| ERC-8004 ReputationRegistry | 0x3FdD300147940a35F32AdF6De36b3358DA682B5c |
| DataAnalyzer Agent wallet addr | 0xEAB418143643557C74479d38E773A64E35B5f6c9 |
| StorachaStorage Agent wallet addr | 0x9D48b65Bb45f144CBC5662Fd3Fd011659371D0f8 |
| Layer | Technology |
|---|---|
| Orchestrator | Claude Sonnet 4.6 + Coinbase AgentKit + Next.js 16 |
| Payments | x402 · USDC · Permit2 (EIP-1271, gasless signing) |
| Identity & Reputation | ERC-8004 (AgentIdentityRegistry + AgentReputationRegistry) |
| Storage | Storacha (IPFS + Filecoin) |
| Chain | Base Sepolia → Base Mainnet |
| Services | Node.js · Express · @x402/express |
| Wallet | CDP Smart Wallet (ERC-4337) |
| Facilitator | CDP Production Facilitator |
See TROUBLESHOOTING.md for the full record of issues and fixes. Key resolutions:
| Issue | Fix |
|---|---|
"Payment was not settled" |
name: 'USD Coin' (not 'USDC') in server route extra field |
| Permit2 always reverts | Run ensurePermit2Approval() — one-time USDC.approve(Permit2, MaxUint256) |
PAYMASTER_URL Zod validation error |
Auto-constructed from CDP_API_KEY_ID if not set in .env |
@x402/* version mismatch |
Client and server must both use ^2.5.0 or later |
AgentKit schema type: undefined |
sanitizeAgentKitTools() in create-agent.ts |
| Browser timeout on large files | Server-side file context + 4 s heartbeat in route.ts |
| Component | Platform | Notes |
|---|---|---|
| DataAnalyzer | Railway | SERVICE_TYPE=analyzer |
| StorachaStorage | Railway | SERVICE_TYPE=storage |
| onchain-agent | Autonome / Railway | Requires output: 'standalone' in next.config.js · persistent /app/wallet volume · set WALLET_DATA_JSON env var |
Docker build:
cd antiphon/onchain-agent
docker build -t rachax402-agent .
docker run -p 3000:3000 \
-e WALLET_DATA_JSON='{"ownerAddress":"0x2E84...","smartWalletAddress":"0xf2e2..."}' \
--env-file .env \
rachax402-agent
