Overview
The Hello EOA A2A demo is a minimal merchant/client example using the official A2A JS SDK with the x402 payments extension. This example demonstrates a fully functional payment flow where a client signs an EIP-3009 authorization and a server verifies and settles it on-chain.What It Does
Server (Merchant)
- Advertises the x402 extension in its AgentCard
- On first message: returns a Task with
input-requiredandx402.payment.required(payment terms) - On payment submission: verifies EIP-712 signature, publishes
payment-pending, callstransferWithAuthorization, then publishespayment-completedand appends tox402.payment.receipts
Client (Buyer)
- Fetches AgentCard and sends a message
- Receives payment terms
- Signs EIP-3009 using a wallet
- Submits
x402.payment.payloadwith the originaltaskId
Prerequisites
- Node.js 18+
Installation
Configuration
Set these environment variables. You can place them in a local.env file and use export $(grep -v '^#' .env | xargs) to load them into your shell before running the scripts.
| Variable | Description |
|---|---|
RPC_URL | JSON-RPC endpoint for your network (Base / Base Sepolia) |
MERCHANT_PRIVATE_KEY | Merchant signer (submits settlement) |
CLIENT_PRIVATE_KEY | Client signer (signs EIP-3009) |
ASSET_ADDRESS | Token contract (USDC) for your network |
X402_NETWORK | ”base” or “base-sepolia” (placed in payment requirements) |
PRICE_USDC | Human-readable price (e.g., 1 or 1.50) |
PRICE_ATOMIC | (Optional) Exact smallest-units string; overrides PRICE_USDC |
MAX_TIMEOUT_SECONDS | (Optional) Default 600 |
Notes
- Merchant address is derived from
MERCHANT_PRIVATE_KEY - Token decimals are read from the
ASSET_ADDRESSat runtime - The server includes a precise EIP-712 domain in
accepts[0].extra.domain; the client uses it for signing
Running the Demo
1. Start the Merchant Server
http://localhost:10000
- AgentCard:
http://localhost:10000/.well-known/agent-card.json
2. Run the Client
Expected Output
The client will display:Verifying Transactions
You can verify a transaction’s logs using:- Network information
- Method (e.g.,
transferWithAuthorization) - Decoded arguments
- Token Transfer/Authorization events
Files
| File | Purpose |
|---|---|
server.js | Merchant A2A server + x402 settlement (EIP-3009) |
client.js | Buyer that signs EIP-712/EIP-3009 and submits the payload |
verify.js | Helper to decode ERC-20 Transfer and EIP-3009 events |
package.json | Scripts (server, client, verify) |
Spec Compliance
- Activation header: Server echoes
X-A2A-Extensions, client attaches it to all requests - Metadata keys: Per spec -
x402.payment.status,x402.payment.required,x402.payment.payload,x402.payment.receipts
Technical Details
EIP-3009 Payment Flow
- Client receives payment requirements from server
- Client signs EIP-712 typed data containing payment details
- Server verifies the signature matches expected parameters
- Server calls
transferWithAuthorizationon the USDC contract - On-chain transfer occurs, emitting Transfer and Authorization events
- Server returns receipt with transaction hash
Signature Format
The signature uses EIP-712 typed data signing, which provides:- Human-readable structured data
- Domain separation for security
- Replay protection via nonces
- Type safety for signed parameters
References
- A2A JS SDK - Official Agent-to-Agent JavaScript SDK
- x402 Protocol - Payment protocol specification
- EIP-3009 - Transfer With Authorization standard
- EIP-712 - Typed structured data hashing and signing