|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +This is a Python-based SDK that extends the A2A (Agent-to-Agent) protocol with x402 payment capabilities. The SDK enables agents to handle payments during A2A interactions, supporting both buyer (client) and seller (server) roles. |
| 8 | + |
| 9 | +## Development Commands |
| 10 | + |
| 11 | +### Setup |
| 12 | + |
| 13 | +```bash |
| 14 | +# Install Python 3.13 |
| 15 | +uv python install 3.13 |
| 16 | + |
| 17 | +# Install dependencies including dev tools |
| 18 | +uv sync --frozen --group dev |
| 19 | +``` |
| 20 | + |
| 21 | +### Testing |
| 22 | + |
| 23 | +```bash |
| 24 | +# Run all tests |
| 25 | +uv run -- pytest |
| 26 | + |
| 27 | +# Run specific test file |
| 28 | +uv run -- pytest python/ampersend-sdk/tests/unit/x402/treasurers/test_naive.py |
| 29 | + |
| 30 | +# Run only slow tests |
| 31 | +uv run -- pytest -m slow |
| 32 | +``` |
| 33 | + |
| 34 | +### Linting & Formatting |
| 35 | + |
| 36 | +```bash |
| 37 | +# Check linting (uses ruff for imports and unused imports) |
| 38 | +uv run -- ruff check --output-format=github python |
| 39 | + |
| 40 | +# Check formatting |
| 41 | +uv run -- ruff format --diff python |
| 42 | + |
| 43 | +# Apply formatting |
| 44 | +uv run -- ruff format python |
| 45 | + |
| 46 | +# Type checking (strict mode enabled) |
| 47 | +uv run -- mypy python |
| 48 | +``` |
| 49 | + |
| 50 | +### Lockfile |
| 51 | + |
| 52 | +```bash |
| 53 | +# Verify lockfile is up to date |
| 54 | +uv lock --check |
| 55 | + |
| 56 | +# Update lockfile |
| 57 | +uv lock |
| 58 | +``` |
| 59 | + |
| 60 | +## Architecture |
| 61 | + |
| 62 | +### Workspace Structure |
| 63 | + |
| 64 | +This is a uv workspace with two main packages: |
| 65 | + |
| 66 | +- `python/ampersend-sdk/`: Core SDK implementation |
| 67 | +- `python/examples/`: Example buyer and seller agents |
| 68 | + |
| 69 | +### Core Components |
| 70 | + |
| 71 | +**X402Treasurer (Abstract Base Class)** |
| 72 | + |
| 73 | +- Handles payment authorization decisions via `onPaymentRequired()` |
| 74 | +- Receives payment status updates via `onStatus()` |
| 75 | +- Implementation example: `NaiveTreasurer` auto-approves all payments |
| 76 | + |
| 77 | +**X402Wallet (Protocol)** |
| 78 | + |
| 79 | +- Creates payment payloads from requirements |
| 80 | +- Two implementations: |
| 81 | + - `AccountWallet`: For EOA (Externally Owned Accounts) |
| 82 | + - `SmartAccountWallet`: For smart contract wallets with ERC-1271 signatures |
| 83 | + |
| 84 | +**Client Side (Buyer)** |
| 85 | + |
| 86 | +- `X402Client`: Extends A2A BaseClient with payment middleware |
| 87 | +- `X402RemoteA2aAgent`: Remote agent wrapper with treasurer integration |
| 88 | +- `x402_middleware`: Intercepts responses, handles PAYMENT_REQUIRED states, submits payments recursively |
| 89 | + |
| 90 | +**Server Side (Seller)** |
| 91 | + |
| 92 | +- `X402A2aAgentExecutor`: Wraps ADK agents with payment verification |
| 93 | +- `make_x402_before_agent_callback()`: Creates callbacks that check payment before agent execution |
| 94 | +- `to_a2a()`: Converts ADK agent to A2A app with x402 support |
| 95 | +- Uses layered executor pattern: OuterA2aAgentExecutor → X402ServerExecutor → InnerA2aAgentExecutor |
| 96 | + |
| 97 | +### Key Architectural Patterns |
| 98 | + |
| 99 | +**Middleware Pattern**: Client uses `x402_middleware` to recursively handle payment required responses by: |
| 100 | + |
| 101 | +1. Detecting PAYMENT_REQUIRED status in task responses |
| 102 | +2. Calling treasurer to authorize payment |
| 103 | +3. Submitting payment and recursing with new message |
| 104 | + |
| 105 | +**Executor Composition**: Server uses nested executors to separate concerns: |
| 106 | + |
| 107 | +- Outer layer handles A2A task lifecycle events |
| 108 | +- Middle layer (X402ServerExecutor) verifies payments |
| 109 | +- Inner layer runs the actual agent |
| 110 | + |
| 111 | +**Protocol-based Wallets**: X402Wallet is a Protocol (structural typing), allowing any object with `create_payment()` to be used without inheritance. |
| 112 | + |
| 113 | +## Environment Variables |
| 114 | + |
| 115 | +Examples require these variables (see `.env.example`): |
| 116 | + |
| 117 | +- `EXAMPLES_A2A_BUYER__PRIVATE_KEY`: Private key for buyer's EOA wallet |
| 118 | +- `EXAMPLES_A2A_BUYER__SELLER_AGENT_URL`: URL of seller agent (default: <http://localhost:8001>) |
| 119 | +- `GOOGLE_API_KEY`: Required for seller's google_search tool |
| 120 | +- `EXAMPLES_A2A_SELLER__PAY_TO_ADDRESS`: Ethereum address to receive payments |
| 121 | + |
| 122 | +## Important Notes |
| 123 | + |
| 124 | +- Python version: 3.13+ required |
| 125 | +- Type checking is strict mode (`mypy --strict`) |
| 126 | +- The x402-a2a dependency comes from a git repository with a specific revision |
| 127 | +- This SDK is marked as "unofficial" in the package description |
| 128 | +- Tests use async mode with function-scoped fixtures |
0 commit comments