Pydantic AI ödeme entegrasyonu.
Pydantic AI paketi yoktur ve buna ihtiyacınız yoktur. @agent.tool_plain ile tipli bir işlev kaydedin, gerçek blockchain0x istemcisini çağırın ve ajansınız Base üzerinde USDC taşıyabilir.
Pydantic AI'ye özel bir paket yok ve buna ihtiyacınız da yok. Pydantic AI, ile bir fonksiyonu doğrulanmış bir araca dönüştürür, bu yüzden gerçek Python istemcisini tipli bir fonksiyon içinde sarar ve agent USDC gönderebilir, faturaları kapatabilir ve cüzdanları okuyabilir. OpenAI, Anthropic, Google, Mistral, Groq ve Pydantic AI sağlayıcılarının geri kalanında çalışır, çünkü araç modele değil HTTP API'ye çağrı yapar. Ödemeler Base üzerinde sonuçlanır.
Pydantic AI'nin tipleri kazanır. Ödemeler için de kullanın.
Pydantic AI'nın temel amacı güçlü tiplemektir: ajan girdileri tiplenmiştir, çıktılar tiplenmiştir, bağımlılıklar tiplenmiştir, tekrar denemeler tiplenmiştir. Çerçeve, hatalı verileri sınırda reddeder, LLM çağrısı boyunca yayılmasına izin vermez. Cüzdan aracınız tam olarak buna dayanır - argümanları tiplerle tanımlayın ve Pydantic AI, modelin çağırılmasına izin verilmeden önce imza ve belge dizisinden doğrulanmış bir şema oluşturur.
Pratik fayda: model, send_usdc'yi bir temel birim dizisi yerine bir float ile çağırmaya çalışırsa, hata, bize yapılan herhangi bir HTTP çağrısından önce Pydantic'in doğrulama katmanında gerçekleşir. Gizemli alan yolları ile API'den gelen 422 yerine yararlı bir mesajla birlikte net bir ValidationError görürsünüz. Bu, burada istemciyi kendiniz sarmanın tam nedenidir, genel bir adaptöre ulaşmak yerine - yazımın kabloya kadar devam etmesini sağlarsınız.
Pydantic AI'yi ve çekirdek SDK'yı kurun. İki anahtar.
Ekleyecek bir blockchain0x Pydantic AI paketi yoktur. Pydantic AI'yi (Python 3.10+) ve gerçek blockchain0x çekirdek SDK'sını kurarsınız, ardından aşağıdaki işlevi yazarsınız. Bu, tüm bağımlılık listesidir.
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 (veya kullandığınız sağlayıcı için eşdeğeri). BLOCKCHAIN0X_API_KEY, dashboard'unuzdan alınan bir sk_test_ testnet veya sk_live_ mainnet anahtarıdır; client bunu environment'tan okur. Agent'iniz para da alıyorsa, webhook handler ayrıca BLOCKCHAIN0X_WEBHOOK_SECRET gerektirir.
Ödeme yapan, bir araç olarak kaydedilmiş bir yazılı işlev.
Aşağıda, tüm entegrasyon bulunmaktadır. send_usdc, gerçek blockchain0x istemcisini çağırır; @agent.tool_plain, tür ipuçları ve dokümantasyadan oluşturulan bir şemayla kaydeder. Çalıştırın ve ajan Base'de USDC'yi taşır, argümanlar çağrıdan önce doğrulanır.
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.
İmzalı bir webhook ile gelen ödemeleri onaylayın.
Eğer ajanınız da USDC alıyorsa, bunu polling ile değil, webhook ile doğrulayın. Doğrulama yardımcı programı Node SDK ile birlikte gelir; bir Python hizmetinde belgelenmiş HMAC ile elle doğrulama yaparsınız. Eğer tipli olaylar istiyorsanız, kendi Pydantic modelinizi tanımlayın ve imza kontrol edildikten sonra ham gövdeyi model_validate_json ile doğrulayın - tipleri eklemek sizin elinizde. Aşağıda FastAPI örneği.
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}
Algoritma, t.rawBody dizesi üzerinde HMAC-SHA256, sabit zamanlı karşılaştırma ve 300 saniyelik bir tekrar penceresi ile çalışır. Ham veriyi await request.body() aracılığıyla okuyun, asla request.json() ile yeniden serileştirmeyin, çünkü bu imzanın kapsadığı baytları değiştirir. Gönderilen olaylar payment.received, payment.sent, wallet.deployed ve webhook.test'tir; dallanmak için X-Blockchain0x-Event-Type başlığına daraltın.
Sarmaladığınız istemci açıktır. Okuyun.
Klonlanacak bir Pydantic AI starter package yok - yukarıdaki recipe entegrasyonun kendisidir. blockchain0x SDK'leri GitHub'da open source'dur; bu recipe Python SDK'yı (blockchain0x-python) sarar ve tam method surface dokümanlarda yer alır. Function body'leri için bir referans olarak okuyun.
github.com/tosh-labs/blockchain0x-pythonTam SDK method surface ve scope'lar the docs içinde belgelenmiştir. Base Sepolia üzerinde bir sk_test_ anahtarıyla başlayın, ardından function beklediğiniz gibi çalıştığında sk_live_ anahtarına geçin.
Beş Pydantic AI'ya özgü kaçınılması gereken tuzak.
Pydantic AI'nin güçlü tipleri, çoğu entegrasyon hatasını sınırda yakalar; bunlar kayıp olan birkaçıdır.
Pydantic AI paketi yoktur - bir aracı kaydedersiniz.
Blockchain0x, LangChain ve CrewAI için adaptörler ve MCP sunucusu gönderir; özel bir Pydantic AI paketi yoktur. Yukarıdaki tarif, gerçek blockchain0x istemcisini çağıran @agent.tool_plain ile süslenmiş basit bir tipli işlevdir. Pydantic AI, doğrulanmış bir araç şemasını oluşturmak için imzayı ve belge dizesini okur, bu da Pydantic AI'ya gelmenizin tam olarak sağladığı yazım kazancıdır.
Miktarı bir dize olarak tutun; Pydantic'in hatları korumasına izin verin.
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, erken bir 503 dönebilir.
payments.create varsayılan olarak yeniden deneme yapmaz ve chain adapter ağınız için bağlanana kadar 503 döndürebilir. Ajanın döngüye girmesine izin vermek yerine hatayı aracınız içinde yakalayın ve modelin işlem yapabileceği net bir mesaj döndürün. Otomatik oluşturulan idempotency key sayesinde manuel yeniden deneme çift ödeme oluşturmaz.
Sağlayıcı ön ekli model dizeleri
Pydantic AI, sağlayıcı ön ekli model dizelerini kullanır: 'openai:gpt-4o', 'anthropic:claude-3-5-sonnet-latest', 'google-gla:gemini-1.5-pro'. Ön eki atlamak, gizemli bir 'bilinmeyen model' hatası verir. Araçınız sağlayıcıdan bağımsızdır çünkü HTTP API'yi çağırır, modeli değil - ön eki serbestçe değiştirin ve cüzdan işlevi değişmez.
tool_plain ve tool (RunContext)
@agent.tool_plain'i, işlevin yukarıda belirtildiği gibi çalışmadan hiçbir şeye ihtiyaç duymadığında kullanın. Eğer ajanın bağımlılıklarını araç içinde (bir isteğe bağlı istemci kimliği, bir harcama limiti) istiyorsanız, @agent.tool kullanın ve ilk argümanı ctx: RunContext[Deps] olarak tanımlayın, böylece ctx.deps'i okuyabilirsiniz. İkisini karıştırmak - tool_plain üzerinde bir ctx argümanı tanımlamak - kayıt sırasında bir TypeError oluşturur.