Skip to main content
This guide demonstrates how to integrate Snack Money’s A2A (Agent-to-Agent) protocol with X402 extension for cryptocurrency payments.

Installation

Clone the example repository:
git clone https://github.com/snack-money/snack-money.git
cd snack-money/snack-money-examples/a2a
yarn install

Configuration

Create a .env file with your configuration:

For Base Network

EVM_PRIVATE_KEY=0x...your-private-key
RECEIVER=username
AMOUNT=0.01
PLATFORM=twitter

For Solana Network

SVM_PRIVATE_KEY=your-solana-private-key-base58
RECEIVER=username
AMOUNT=0.01
PLATFORM=twitter

Available Scripts

Discover Agent Capabilities

View Snack Money’s A2A capabilities:
yarn agent-card
This displays:
  • Agent information and skills
  • Available payment methods
  • Input schemas and requirements
  • X402 extension support

Send Payment via Base

yarn base

Send Payment via Solana

yarn solana

Implementation Examples

Base Network Payment

import axios from "axios";
import { privateKeyToAccount } from "viem/accounts";
import { x402Client } from "@x402/core/client";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { encodePaymentSignatureHeader } from "@x402/core/http";

// Setup
const account = privateKeyToAccount(evmPrivateKey);
const x402 = new x402Client();
registerExactEvmScheme(x402, { signer: account });

// Phase 1: Request payment requirements
const initialRequest = {
  jsonrpc: "2.0",
  id: 1,
  method: "snack-money.pay.twitter",
  params: {
    receiver: "username",
    amount: 0.01,
    description: "Payment via A2A"
  }
};

const response = await axios.post(
  "https://api.snack.money/a2a",
  initialRequest,
  {
    headers: {
      "Content-Type": "application/json",
      "X-A2A-Extensions": "https://a2a.dev/spec/extensions/x402/v0"
    }
  }
);

// Phase 2: Execute on-chain payment
const { taskId, payment } = response.data.result;
const paymentReceipt = await x402.payment.execute(payment);

// Phase 3: Submit payment proof
const proofRequest = {
  jsonrpc: "2.0",
  id: 2,
  method: "snack-money.pay.twitter",
  params: {
    receiver: "username",
    amount: 0.01,
    taskId,
    payment: {
      network: payment.network,
      transactionHash: paymentReceipt.hash
    }
  }
};

const finalResponse = await axios.post(
  "https://api.snack.money/a2a",
  proofRequest,
  {
    headers: {
      "Content-Type": "application/json",
      "X-A2A-Extensions": "https://a2a.dev/spec/extensions/x402/v0",
      "x-payment-signature": encodePaymentSignatureHeader(
        paymentReceipt.signature
      )
    }
  }
);

Solana Network Payment

import { Connection, PublicKey, Transaction } from "@solana/web3.js";
import { createTransferInstruction, getAssociatedTokenAddress } from "@solana/spl-token";
import bs58 from "bs58";

// Setup Solana connection and wallet
const connection = new Connection("https://api.mainnet-beta.solana.com");
const keypair = Keypair.fromSecretKey(bs58.decode(svmPrivateKey));

// Phase 1: Request payment requirements (same as Base)
const response = await axios.post(
  "https://api.snack.money/a2a",
  initialRequest,
  {
    headers: {
      "Content-Type": "application/json",
      "X-A2A-Extensions": "https://a2a.dev/spec/extensions/x402/v0"
    }
  }
);

// Phase 2: Execute Solana USDC transfer
const { taskId, payment } = response.data.result;
const usdcMint = new PublicKey(payment.token);
const recipientPubkey = new PublicKey(payment.recipient);

// Create and send transaction
const transaction = new Transaction().add(
  createTransferInstruction(
    await getAssociatedTokenAddress(usdcMint, keypair.publicKey),
    await getAssociatedTokenAddress(usdcMint, recipientPubkey),
    keypair.publicKey,
    BigInt(payment.amount)
  )
);

const signature = await connection.sendTransaction(transaction, [keypair]);
await connection.confirmTransaction(signature);

// Phase 3: Submit payment proof
const proofRequest = {
  jsonrpc: "2.0",
  id: 2,
  method: "snack-money.pay.twitter",
  params: {
    receiver: "username",
    amount: 0.01,
    taskId,
    payment: {
      network: "solana:mainnet",
      transactionHash: signature
    }
  }
};

Batch Payments

A2A also supports batch payments to multiple recipients:
const batchRequest = {
  jsonrpc: "2.0",
  id: 1,
  method: "snack-money.batch-pay.twitter",
  params: {
    receivers: [
      { receiver: "user1", amount: 0.01 },
      { receiver: "user2", amount: 0.02 },
      { receiver: "user3", amount: 0.03 }
    ],
    description: "Batch payment via A2A"
  }
};

Response Handling

Success Response

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "taskId": "task_abc123",
    "status": "PAYMENT_CONFIRMED",
    "metadata": {
      "x402:transactionId": "1234567890",
      "x402:receipt": "https://snack.money/x/username?txn=1234567890"
    }
  }
}

Error Response

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32602,
    "message": "Invalid params",
    "data": {
      "field": "receiver",
      "reason": "User not found"
    }
  }
}

Testing

Start with small amounts (0.01 USDC = 1¢) to test the integration:
# Test Base network
AMOUNT=0.01 RECEIVER=your-username yarn base

# Test Solana network
AMOUNT=0.01 RECEIVER=your-username yarn solana

Supported Platforms

The A2A protocol supports payments to these platforms:
  • twitter - Twitter/X usernames
  • farcaster - Farcaster usernames
  • github - GitHub usernames
  • email - Email addresses
  • web - Web domains
  • instagram - Instagram usernames

Example Output

🚀 Starting Snack Money A2A Payment Example (Base Network)

🔧 Creating Base signer...
✅ Base signer created: 0x...

🎯 Using skill: snack-money.pay.twitter
💸 Sending 0.01 USDC to @username on twitter...

📋 Phase 1: Requesting payment requirements...
✅ Payment requirements received
   Task ID: task_1234567890
   Network: eip155:8453
   Amount: 10000 USDC (atomic units)

🔐 Phase 2: Executing on-chain payment...
✅ Payment sent: 0x...
   Waiting for confirmation...
✅ Payment confirmed!

📨 Phase 3: Submitting payment proof...
✅ Payment processed successfully!

🧾 Transaction ID: 1234567890
🔗 Receipt: https://snack.money/x/username?txn=1234567890

Complete Example Repository

The full working examples are available at: github.com/snack-money/snack-money/tree/main/snack-money-examples/a2a

Next Steps