Pydantic AI betalingsintegratie.
Er is geen Pydantic AI-pakket, en je hebt er geen nodig. Registreer een getypte functie met @agent.tool_plain, roep de echte blockchain0x-client aan, en jouw agent kan USDC verplaatsen op Base.
Er is geen Pydantic AI-specifiek pakket, en je hebt er ook geen nodig. Pydantic AI maakt van een functie een gevalideerde tool met , dus wikkel je de echte Python client in een getypeerde functie en kan de agent USDC versturen, facturen afwikkelen en wallets uitlezen. Het werkt met OpenAI, Anthropic, Google, Mistral, Groq en elke andere Pydantic AI-provider, omdat de tool de HTTP API aanroept en niet het model. Betalingen worden afgerekend op Base.
De typing van Pydantic AI wint. Gebruik het ook voor betalingen.
Het hele punt van Pydantic AI is sterke typing: agentinvoer is getypt, uitvoer is getypt, afhankelijkheden zijn getypt, herhalingen zijn getypt. Het framework weigert onjuist gevormde gegevens aan de grens in plaats van ze door te laten dringen via de LLM-aanroep. Je wallet-tool steunt precies daarop - verklaar de argumenten met types, en Pydantic AI bouwt een gevalideerd schema op uit de handtekening en docstring voordat het model ooit is toegestaan om het aan te roepen.
Het praktische voordeel: als het model probeert send_usdc aan te roepen met een float in plaats van een basis-eenheid string, gebeurt de fout bij de validatielaag van Pydantic voordat er een HTTP-aanroep naar ons is. Je ziet een duidelijke ValidationError met een nuttige boodschap in plaats van een 422 van de API met cryptische veldpaden. Dat is de hele reden om de client hier zelf te wikkelen in plaats van een generieke adapter te gebruiken - je houdt de typing helemaal tot de draad.
Installeer Pydantic AI en de kern SDK. Twee sleutels.
Er is geen blockchain0x Pydantic AI-pakket om toe te voegen. Je installeert Pydantic AI (Python 3.10+) en de echte blockchain0x kern SDK, en schrijft dan de functie hieronder. Dat is de hele afhankelijkheidslijst.
pip install pydantic-ai blockchain0xexport OPENAI_API_KEY=sk-... export BLOCKCHAIN0X_API_KEY=sk_test_... # sk_test_ = Base Sepolia, sk_live_ = Base mainnet
OPENAI_API_KEY (of het equivalent voor welke provider je ook gebruikt). BLOCKCHAIN0X_API_KEY is een sk_test_ testnet- of sk_live_ mainnet-sleutel uit je dashboard; de client leest die uit de omgeving. Als je agent ook geld ontvangt, heeft de webhook handler daarnaast BLOCKCHAIN0X_WEBHOOK_SECRET nodig.
Een getypte functie die betaalt, geregistreerd als een tool.
Hieronder is de hele integratie. send_usdc roept de echte blockchain0x-client aan; @agent.tool_plain registreert het met een schema dat is opgebouwd uit de type hints en docstring. Voer het uit en de agent verplaatst USDC op Base, met de argumenten gevalideerd vóór de oproep.
from pydantic_ai import Agent from blockchain0x import Client blockchain0x = Client() # reads BLOCKCHAIN0X_API_KEY from the environment agent = Agent( "openai:gpt-4o", system_prompt="You pay vendor invoices in USDC within owner-set limits.", ) # Register a plain function as a tool. No dedicated package needed. @agent.tool_plain def send_usdc(agent_id: str, to: str, amount_wei: str) -> str: """Send a USDC payment from an agent wallet. amount_wei is USDC base units (6 decimals), so "10000" is 0.01 USDC. """ return str( blockchain0x.payments.create(body={"agentId": agent_id, "to": to, "amountWei": amount_wei}) ) result = agent.run_sync( "Pay 0.01 USDC from agent agt_123 to 0xVendor for the dataset." ) print(result.output)
When the agent decides to pay, it calls send_usdc, the SDK submits the transfer, and you get a transaction hash back. amount_wei is base units, so 0.01 USDC is "10000". A sk_test_ key keeps it on Base Sepolia until you switch to sk_live_. Want a typed result object instead of a string? Set the agent's output_type to your own Pydantic model and return it from the tool. Add read and settle functions the same way.
Bevestig inkomende betalingen met een ondertekende webhook.
Als je agent ook USDC ontvangt, bevestig het dan met de webhook in plaats van te polleren. De verify-helper wordt geleverd in de Node SDK; in een Python-service verifieer je handmatig tegen de gedocumenteerde HMAC. Als je getypte evenementen wilt, definieer dan je eigen Pydantic-model en model_validate_json de ruwe body nadat de handtekening is gecontroleerd - de typing is aan jou om toe te voegen. Voorbeeld van FastAPI hieronder.
import hmac, hashlib, os, time from fastapi import FastAPI, Request, HTTPException app = FastAPI() SECRET = os.environ["BLOCKCHAIN0X_WEBHOOK_SECRET"].encode() @app.post("/webhooks/payment") async def receive(request: Request): raw = await request.body() # RAW bytes - do not parse first sig = request.headers.get("X-Blockchain0x-Signature", "") ts = request.headers.get("X-Blockchain0x-Timestamp", "") parts = dict(p.split("=", 1) for p in sig.split(",") if "=" in p) t, v1 = parts.get("t", ts), parts.get("v1", sig) want = hmac.new(SECRET, t.encode() + b"." + raw, hashlib.sha256).hexdigest() if not hmac.compare_digest(want, v1) or abs(time.time() - int(t)) > 300: raise HTTPException(status_code=401) if request.headers.get("X-Blockchain0x-Event-Type") == "payment.received": await trigger_followup() # USDC landed - run the next step return {"ok": True}
Het algoritme is HMAC-SHA256 over de string t.rawBody, een constante tijdsvergelijking, en een replayvenster van 300 seconden. Lees het ruwe lichaam via await request.body(), nooit request.json() opnieuw-serialized, omdat dat de bytes verandert die de handtekening dekt. De verzonden evenementen zijn payment.received, payment.sent, wallet.deployed, en webhook.test; narrow op de X-Blockchain0x-Event-Type header om te takken.
De client die je aan het wikkelen bent is open. Lees het.
Er is geen Pydantic AI starter package om te klonen - de bovenstaande recipe is de integratie. De blockchain0x SDKs zijn open source op GitHub; deze recipe omhult de Python SDK (blockchain0x-python), met de volledige method surface in de docs. Lees die als referentie voor de function bodies.
github.com/tosh-labs/blockchain0x-pythonDe volledige SDK method surface en scopes zijn gedocumenteerd in de docs. Begin met een sk_test_ key op Base Sepolia en schakel daarna over naar sk_live_ wanneer de functie doet wat je verwacht.
Vijf Pydantic AI-specifieke valkuilen om te vermijden.
De sterke typing van Pydantic AI vangt de meeste integratiefouten aan de grens; dit zijn de weinigen die erdoorheen glippen.
Er is geen Pydantic AI-pakket - je registreert een tool
Blockchain0x levert adapters voor LangChain en CrewAI plus de MCP-server; er is geen speciaal Pydantic AI-pakket. Het bovenstaande recept is het pad: een eenvoudige getypte functie versierd met @agent.tool_plain die de echte blockchain0x-client aanroept. Pydantic AI leest de handtekening en docstring om een gevalideerd hulpschema op te bouwen, wat precies de typwin is waarvoor u naar Pydantic AI kwam.
Houd het bedrag een string; laat Pydantic de lijn vasthouden
payments.create takes amountWei: a string of USDC base units (6 decimals), so 0.01 USDC is "10000" and 5 USDC is "5000000". Type the tool argument as str and Pydantic AI rejects a float at the boundary with a clear ValidationError, before any HTTP call. That is the whole point of doing this in Pydantic AI - the malformed value never reaches the API.
send_payment kan vroeg 503 beantwoorden
payments.create probeert standaard niet opnieuw en kan 503 retourneren totdat de chain adapter is aangesloten op jouw netwerk. Vang de fout op binnen je tool en retourneer een duidelijk bericht waar het model op kan reageren, in plaats van de agent te laten draaien. De automatisch geminte idempotency key betekent dat een handmatige herhaling niet dubbel betaalt.
Provider-geprefixeerde modelstrings
Pydantic AI gebruikt provider-geprefixeerde modelstrings: 'openai:gpt-4o', 'anthropic:claude-3-5-sonnet-latest', 'google-gla:gemini-1.5-pro'. Het weglaten van het voorvoegsel geeft een cryptische 'onbekend model' fout. Je tool is provider-agnostisch omdat het de HTTP API aanroept, niet het model - wissel het voorvoegsel vrijelijk uit en de walletfunctie blijft ongewijzigd.
tool_plain versus tool (RunContext)
Gebruik @agent.tool_plain wanneer de functie niets nodig heeft van de run, zoals hierboven. Als je de afhankelijkheden van de agent binnen de tool wilt hebben (een client-id per aanvraag, een uitgavenlimiet), gebruik dan @agent.tool en verklaar het eerste argument als ctx: RunContext[Deps] om ctx.deps te lezen. Het mengen van de twee - het verklaren van een ctx-argument op tool_plain - veroorzaakt een TypeError bij registratie.