Documentation

arc-agent-pay — Python SDK for AI agents that autonomously pay for API services using USDC nanopayments on Arc via the x402 protocol.

Install

The core SDK has minimal dependencies. Install only what you need:

bash
pip install arc-agent-pay
ExtraAddsUse when
[agent]openai, python-dotenvBuilding agents that synthesize with an LLM
[server]fastapi, uvicorn, python-dotenvRunning your own x402-gated API server
[demo]all of the aboveRunning the full research agent demo

Quick start

Create .env:

.env
AGENT_PRIVATE_KEY=<your hex private key>

# LLM synthesis — pick one:
ARCAPIS_TOKEN_ID=<tokenId>   # on-chain via arcapis.com (recommended)
# OPENAI_API_KEY=sk-proj-... # or OpenAI directly

Run the demo agent:

bash
uv run python -m demo.run "USDC payments on Arc network"
uv run python -m demo.run "crypto whale activity" --budget 0.05
uv run python -m demo.run "AI agent economy 2026" --verbose

Or use the SDK directly:

python
from arc_agent_pay import PaymentClient, ServiceRegistry
from arc_agent_pay.models import Chain
from eth_account import Account

registry = ServiceRegistry()
services = registry.search("crypto prices")

account = Account.from_key("0x" + private_key)

async with PaymentClient(
    account=account,
    budget_usdc="0.05",
    chain=Chain.ARC_TESTNET,
) as client:
    response = await client.get(services[0].url)  # 402 → pay → retry
    data = response.json()
    print(client.summary())

How it works

Every API call goes through the x402 payment flow automatically:

text
1. Agent calls  GET /prices
2. Server returns  402 Payment Required  + PAYMENT-REQUIRED header
3. PaymentClient parses the header — price: 0.001 USDC, pay_to: 0x…
4. Signs EIP-3009 TransferWithAuthorization  (off-chain, no gas yet)
5. Retries with  X-402-Payment  header
6. Server verifies signature → calls transferWithAuthorization on-chain
7. Arc Testnet confirms → tx hash returned in PAYMENT-RESPONSE header
8. 200 OK — agent gets the data

Chain:    Arc Testnet · chain ID 5042002
USDC:     0x3600000000000000000000000000000000000000
Protocol: EIP-3009 v2 (transferWithAuthorization)

SDK API reference

PaymentClient

Async httpx wrapper that intercepts HTTP 402 responses, signs EIP-3009 authorizations, and retries automatically. Enforces a session budget via BudgetGuard.

python
PaymentClient(
    account: eth_account.Account,
    budget_usdc: str = "0.10",
    chain: Chain = Chain.ARC_TESTNET,
    on_event: Callable[[str, dict], None] | None = None,
)
get(url, **kwargs)Authenticated GET with auto-payment
post(url, **kwargs)Authenticated POST with auto-payment
summary()Returns payment audit dict

ServiceRegistry

In-memory registry of x402-gated API services. Search by keyword or tag.

python
ServiceRegistry()
search(query, max_results=5)Keyword/tag search → list[Service]
register(service)Add a Service to the registry
all()Return all registered services

BudgetGuard

Tracks cumulative spend for a session and raises BudgetExhaustedError when the limit is reached.

python
BudgetGuard(budget_usdc: str)
check_and_record(amount_usdc)Raises if over budget, else records
remainingDecimal — remaining USDC
spentDecimal — total spent this session

Wallets & funding

Two EOA wallets are needed, both funded with Arc Testnet USDC:

RoleEnv varPurpose
Agent (payer)AGENT_PRIVATE_KEYSigns EIP-3009 authorizations off-chain
Server (facilitator)SERVER_PRIVATE_KEYPays gas, submits transferWithAuthorization on-chain

Generate a fresh EOA:

bash
uv run python -c "
from eth_account import Account
import secrets
a = Account.from_key('0x'+secrets.token_hex(32))
print('key:', a.key.hex())
print('addr:', a.address)
"

Fund from a Circle wallet:

bash
circle wallet transfer <ADDRESS> --amount 5 --address 0x40a2f3926fb79b91b8012c8f1dc3a1c6e4ded2cc --chain ARC-TESTNET --testnet

Live API endpoints

Publicly deployed at web-production-175cc.up.railway.app

EndpointPriceData source
GET /prices$0.001 USDCSynthetic crypto prices
POST /research$0.005 USDCSynthetic research brief
GET /news$0.002 USDCSynthetic headlines
GET /whales$0.010 USDCReal — Arc Testnet Blockscout