Skip to main content
HomeLanding pagesPydantic AI wallet
LANDING PAGE

Pydantic AI wallet

8 min read·Last updated June 2, 2026

A Pydantic AI wallet is a reusable Tool that pays for what the agent calls. Its body calls a small local Node proxy built on createX402Client from @blockchain0x/x402, settling any HTTP 402 in USDC on Base. Define it once as a standalone Tool, pass it to any agent via tools=[], and bind each agent's wallet through typed deps so one tool serves many wallets.

What the wallet tool is

A Pydantic AI wallet is a reusable tool that gives an agent the ability to pay. The agent calls it with a target, and the tool, through a small local proxy, settles any 402 in USDC on Base and returns the result. The agent gets a wallet the way it gets any capability in Pydantic AI: as a tool attached to it, called when a task needs to pay.

There is no Blockchain0x Pydantic AI package. The wallet tool is a pattern you build from @blockchain0x/node and @blockchain0x/x402, calling a Node proxy because the x402 client is Node-only. This page is the focused artifact; for the broad integration overview see pydantic-ai-payments, and for the task walkthrough see how-to-add-payments-to-pydantic-ai-agent. The payment API product page is the reference.

Build it as a standalone Tool

The reusable shape in Pydantic AI is a standalone Tool object, not an inline @agent.tool bound to one agent. Define the function once, wrap it in a Tool, and you can pass it to any number of agents via tools=[].

PYTHON
import requests
from pydantic_ai import RunContext, Tool
from dataclasses import dataclass

@dataclass
class WalletDeps:
    proxy_url: str  # this agent's wallet proxy, e.g. "http://127.0.0.1:8787"

def pay_and_fetch(ctx: RunContext[WalletDeps], url: str) -> str:
    """Fetch a URL, paying in USDC if it requires payment. Returns the body."""
    res = requests.post(ctx.deps.proxy_url, json={"url": url}, timeout=30)
    return res.text if res.status_code == 200 else f"Failed: {res.status_code}"

wallet_tool = Tool(pay_and_fetch, takes_ctx=True)

Now wallet_tool is a reusable object. Pass it to an agent with Agent("openai:gpt-4o", deps_type=WalletDeps, tools=[wallet_tool]), run with WalletDeps(proxy_url=...), and the agent can pay. That is the wallet tool: one Tool, attachable anywhere.

One tool, many agents, many wallets

The standalone Tool plus typed deps is what makes the wallet reusable across a fleet without copying code. The same wallet_tool object goes on every agent that should pay, and the deps decide which wallet each run uses.

PYTHON
researcher = Agent("openai:gpt-4o", deps_type=WalletDeps, tools=[wallet_tool])
writer = Agent("openai:gpt-4o", deps_type=WalletDeps, tools=[wallet_tool])

researcher.run_sync("...", deps=WalletDeps(proxy_url="http://127.0.0.1:8787"))  # researcher's wallet
writer.run_sync("...", deps=WalletDeps(proxy_url="http://127.0.0.1:8788"))      # writer's wallet

Two agents, one shared tool object, two wallets selected by deps. Run one proxy per wallet on its own port with that wallet's key, and the dashboard attributes spend per agent while a compromised agent can only spend its own balance. Shared code, separate accounts, expressed the Pydantic AI way through dependencies rather than duplicated tools.

A fixed-wallet variant

When an agent always uses one wallet and you do not need per-run selection, you can skip deps and use a tool_plain, which takes no context. This is the simpler artifact for a single-agent, single-wallet service.

PYTHON
def pay_and_fetch_fixed(url: str) -> str:
    """Fetch a URL, paying in USDC if required."""
    res = requests.post("http://127.0.0.1:8787", json={"url": url}, timeout=30)
    return res.text if res.status_code == 200 else f"Failed: {res.status_code}"

fixed_tool = Tool(pay_and_fetch_fixed, takes_ctx=False)

Use the deps form when wallets vary per agent or per run, and the fixed form when one agent owns one wallet for its lifetime. Both are the same pattern; the difference is only whether the proxy address comes from deps or is baked in.

Keep the surface small

Whichever form you build, keep the tool's surface to one obvious operation: pay-by-calling. Give it a URL and it returns the body, having settled any payment. That single operation covers the common case, an agent paying for data, an API, or another agent, and it is enough for almost every use.

Resist adding an open-ended "send payment to an arbitrary address" operation. It is a far larger attack surface than pay-for-what-you-call, and the wallet's spend limit, set in the dashboard, already bounds what any form of the tool can spend, so the tool does not need to enforce budgets itself. A small, predictable wallet tool is easier for the model to use correctly and easier for you to reason about; let the spend limit be the backstop and keep the tool to what the agent genuinely needs.

Return a typed result, not a blob

Because Pydantic AI is about typed outputs, the wallet tool is a good place to validate the data you just paid for rather than returning a raw string. When the paid response has a known shape, parse it into a Pydantic model inside the tool and return that; validation then catches a malformed or surprising payload before it reaches the model's reasoning, and you spent real money on that response, so catching a bad one early matters.

PYTHON
from pydantic import BaseModel

class Quote(BaseModel):
    symbol: str
    price: float

def pay_for_quote(ctx: RunContext[WalletDeps], url: str) -> Quote:
    """Fetch a paid price quote, validated."""
    res = requests.post(ctx.deps.proxy_url, json={"url": url}, timeout=30)
    return Quote.model_validate_json(res.text)

This keeps the generic pay_and_fetch for arbitrary URLs and adds a typed tool where the shape is known, which is the Pydantic AI idiom: pay, validate, then reason. Use the generic tool for exploration and a typed one for the sources you call often enough to model. The two coexist on the same agent, and the model picks whichever the task needs, so you do not have to choose one approach for the whole agent.

Compatibility

Because the wallet tool is an ordinary Tool, it works across Pydantic AI's surfaces.

Pydantic AI surface Works? Notes
Standalone Tool in tools=[] Yes Reusable across agents
takes_ctx=True with typed deps Yes Per-agent wallet via RunContext
takes_ctx=False (tool_plain) Yes Fixed-wallet variant
run_sync / run / streaming Yes The tool runs inside the agent's tool call
Payment client language Node The proxy bridges Python Pydantic AI to the Node x402 client

When to use it

Reach for the wallet tool when agents need to pay for what they call and you want that capability as one reusable unit rather than per-tool glue. It fits when several agents share the same paying behavior, since you define the Tool once and bind wallets through deps, and when payment should be a capability the model can invoke deliberately.

It is the wrong shape when only one specific tool should ever pay (wrap that tool's own call through the proxy instead) or when the agent is purely internal with no paid calls. Match it to whether paying is a general capability the agents need or a one-off behavior of a single tool.

Pricing

The tool is free; you build it from open packages. What you pay is the wallet platform fee per agent on the pricing page: Free is $0 per agent per month at a 5% transaction fee, Pro is $9 at 2%, and Business is $29 at 1%. Per-agent pricing means each agent that transacts through the tool is billed on its own wallet, so a fleet where only some agents pay only incurs fees for those agents.

What to ship today

Define pay_and_fetch as a standalone Tool, attach it to an agent with tools=[], start a proxy with a sk_test_ key, and make one paid call on Base Sepolia. For multiple agents, run a proxy per wallet and select it through deps. For the broad integration overview see pydantic-ai-payments. Pricing is on the pricing page.

FAQ

Frequently asked questions.

Is there a Pydantic AI wallet package from Blockchain0x?

No. The wallet tool is a Tool you build around createX402Client from @blockchain0x/x402, calling a small local Node proxy because the x402 client ships for Node. There is no dedicated Pydantic AI adapter package; the tool plus proxy is the pattern, which keeps every payment identifier on the verified Node surface.

What does the wallet tool let the agent do?

Pay for what it calls. The agent invokes the tool with a target, the tool posts it to the proxy, and the proxy settles any HTTP 402 in USDC on Base and returns the result. That single pay-by-calling operation covers paying data APIs, paid tools, and other agents, bounded by the wallet's spend limit.

How is this different from the Pydantic AI payments page?

The payments page is the broad integration reference, covering both the pay and earn sides. This page is one concrete artifact: a reusable wallet Tool you define once and pass to many agents via tools=[], with each agent's wallet bound through typed deps. Same proxy underneath; this is the tool you actually attach to agents.

How does one tool serve different wallets?

Through Pydantic AI's typed dependencies. The tool reads the proxy address from RunContext, and you run each agent with a deps value pointing at that agent's wallet proxy. The tool code is shared; the deps decide which wallet pays, so the same Tool object can serve a whole fleet with per-agent attribution and isolation.

Which network and token does it use?

USDC, 6 decimals, on Base. A sk_test_ key (on the proxy) settles on Base Sepolia (eip155:84532), a sk_live_ key on Base mainnet (eip155:8453). The proxy reads the network from the key prefix, so the same tool works on either by swapping the proxy's key.

Create your free agent wallet in 5 minutes.

First payment confirmed in under ten minutes. Free to start.