Skip to main content

x402-aa-wallet

The easiest way for an ERC-4337 / account-abstraction agent to pay x402 API calls — with a dedicated, non-custodial EOA, since its smart-wallet signature doesn't work with x402 yet.

A lightweight, typed SDK: generate a spend wallet, fund it from your agent's own smart wallet, and every request through it pays x402 (HTTP 402) challenges automatically — retried and returned, no manual handling — against any x402 merchant. Originally built for HoodGrow (see "Sponsored by" below), and works the same way against any other x402 API.

flowchart LR
    A[AI Agent] --> B[Request API]
    B --> C[402 Payment Required]
    C --> D[x402_session pays automatically]
    D --> E[Retry request]
    E --> F[Response]

Features

  • 🤖 Built for ERC-4337 / account-abstraction agents
  • 💳 Automatic x402 payment handling — detect a 402, pay, retry, transparently
  • 💰 Optional max_amount_usd spend cap — a real enforcement boundary, not just a docs warning
  • 🔒 Non-custodial — the private key never leaves your process, and is excluded from repr() (safe to log the wallet by accident)
  • ⚡ Minimal dependencies (eth-account, requests, x402)
  • 🌐 Works against any x402-compatible API
  • 📦 Fully typed
  • 🟦 TypeScript implementation also available (see Related projects)

Installation

pip install x402-aa-wallet

Formerly published as hoodgrow-x402-aa, importable as hoodgrow_x402_aa — same code, same maintainers, new name to reflect that it's a general-purpose x402 utility, not a HoodGrow-specific client. See "Sponsored by" below.

Quick start

from x402_aa_wallet import create_spend_wallet, get_usdc_balance, x402_session

# 1. Generate a dedicated spend wallet — locally, once.
wallet = create_spend_wallet()
print("fund this address:", wallet.address)
# store wallet.private_key yourself (env var / secret manager) — this
# library never sees it again after this call returns.

# 2. Fund `wallet.address` with a little USDC on Base — from your agent's
#    own smart wallet, using its own transfer/send call (not this library).

# 3. Check the balance whenever you want to know if it needs topping up.
balance = get_usdc_balance(wallet.address)

# 4. Pay any x402 endpoint with it — payment happens automatically.
#    max_amount_usd is optional but strongly recommended for autonomous
#    use: it refuses to pay any single challenge above this amount
#    instead of trusting whatever the server's 402 response asks for.
session = x402_session(wallet, max_amount_usd=0.5)

# First call: HoodGrow's own hello-world endpoint — $0.001, no API key, a
# real 402 challenge and settlement so you can watch the whole flow work.
ping = session.get("https://www.hoodgrow.com/api/agent/ping")
print(ping.json())

# Then: real data, same wallet, same call shape.
resp = session.get("https://www.hoodgrow.com/api/agent/token/NVDA")
print(resp.json())

Restarting your agent? Rehydrate the same wallet from the key you stored:

from x402_aa_wallet import spend_wallet_from_private_key

wallet = spend_wallet_from_private_key(YOUR_STORED_PRIVATE_KEY)

Why this exists

x402's "exact" EVM scheme settles payment via an EIP-3009 ECDSA signature, which an account-abstraction owner key (often a P256/WebAuthn passkey, or even secp256k1 but the wrong address) usually can't produce — full ERC-1271/ERC-6492 smart-wallet support is still an open, unshipped facilitator feature (see coinbase/x402#639). The fix is giving the agent a small, dedicated EOA it funds itself, purely for x402 spending. Full writeup: hoodgrow.com/blog/x402-account-abstraction-eoa.

Non-custodial — read this before using it

We never see your private key. Nobody does but you.

  • create_spend_wallet() generates a fresh secp256k1 keypair entirely inside your own process, using eth_account. Nothing is transmitted, logged, or persisted by this library.
  • The private key is returned to you once, in memory. Store it yourself (env var, secret manager) — this library keeps no copy after the call returns.
  • SpendWallet excludes private_key from its repr() — direct attribute access (wallet.private_key) still works, but print(wallet), an unhandled exception's traceback, or a logging call that stringifies the object won't show it.
  • Funding the spend wallet is your agent's job, using your agent's own smart-wallet infrastructure. This library never moves funds itself — it only tells you the address to send to and (via get_usdc_balance) how much is there.
  • The published package is open source. Don't trust this description — read src/x402_aa_wallet/, it's short.

Spend cap

x402_session accepts max_amount_usd:

session = x402_session(wallet, max_amount_usd=0.10)

Without it, x402_session pays whatever a 402 response asks for — a misbehaving or compromised merchant returning a much larger amount than expected gets paid in full, silently. With max_amount_usd set, a payment requirement above the cap is filtered out before signing (via a real x402ClientSync policy, not a client-side amount check bolted on after the fact), and if that leaves nothing payable, the request raises instead of proceeding.

The cap only evaluates a requirement whose asset is a known 6-decimal Circle USDC deployment (Base mainnet or Base Sepolia) — anything else is excluded rather than evaluated with a guessed decimal count, since guessing wrong could make a genuinely large charge on a different-decimals asset look small enough to slip through.

API

Function Returns
create_spend_wallet() A new SpendWallet(address, private_key, account)
spend_wallet_from_private_key(key) Rehydrates a SpendWallet from a key you already have
get_usdc_balance(address, rpc_url=DEFAULT_BASE_RPC_URL) USDC balance (float, human units) on Base
x402_session(wallet, *, max_amount_usd=None, network=NETWORK) A requests.Session that auto-pays x402 challenges — wallet can be a SpendWallet, an eth_account LocalAccount, or a raw private key string. max_amount_usd — see "Spend cap" above; network overrides the default eip155:8453 (Base mainnet)

get_usdc_balance talks to Base over plain JSON-RPC (eth_call) — no web3.py dependency, one read-only call. Override rpc_url if you run your own node.

Use cases

  • AI assistants and copilots
  • MCP servers
  • Autonomous agents built on ERC-4337 smart wallets
  • Multi-agent systems
  • Research agents
  • Trading bots
  • Automation workflows

Payment safety

Every payment x402_session makes is real USDC on Base mainnet — not reversible. Only fund the spend wallet with what you're willing to spend, and never reuse an EOA that also holds funds you care about for anything else. Set max_amount_usd (see "Spend cap" above) for any autonomous/agent use — don't rely on funding discipline alone as the only safety boundary.

Sponsored by

Built and maintained by the team behind HoodGrow — stock token data for Robinhood Chain — to pay their own x402-protected API. Released as a standalone, general-purpose tool because the AA/x402 gap this solves isn't specific to HoodGrow.

Related projects

Once your agent has a wallet that pays for itself, the next step is an agent that already knows what to call:

  • hoodgrow-mcp — an MCP server for HoodGrow's stock-token API. Free tier, no signup required for a key.
  • x402-aa-wallet (TypeScript) — TypeScript implementation of this package
  • x402 — the HTTP 402 payment protocol

Development

pip install -e ".[dev]"
pytest

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

x402_aa_wallet-0.2.1.tar.gz (12.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

x402_aa_wallet-0.2.1-py3-none-any.whl (11.7 kB view details)

Uploaded Python 3

File details

Details for the file x402_aa_wallet-0.2.1.tar.gz.

File metadata

  • Download URL: x402_aa_wallet-0.2.1.tar.gz
  • Upload date:
  • Size: 12.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for x402_aa_wallet-0.2.1.tar.gz
Algorithm Hash digest
SHA256 b869c432fd6bcf156fc763325850622d1f41397935e8e8c7f22459898bae9c10
MD5 3db0db6f3c5ff9a40b23682085b0f22a
BLAKE2b-256 784527da7bb0b3215fee5bc65cf8407bc20c63ad743108508f3b4cc379c49937

See more details on using hashes here.

Provenance

The following attestation bundles were made for x402_aa_wallet-0.2.1.tar.gz:

Publisher: publish.yml on MeMikko/hoodgrow-x402-aa

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file x402_aa_wallet-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: x402_aa_wallet-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 11.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for x402_aa_wallet-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9f8d02a427bc5e5a189b20ccc0fbd38ee890cb1089a900986630fc8e41e7e24c
MD5 fcbf5083fdd1e96993c2fb73d12f6db7
BLAKE2b-256 000c67c8d6659f40c1e5bbba7a2ed6d4ffab760cf30351e199a9c780fd623ae4

See more details on using hashes here.

Provenance

The following attestation bundles were made for x402_aa_wallet-0.2.1-py3-none-any.whl:

Publisher: publish.yml on MeMikko/hoodgrow-x402-aa

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page