AIエージェントに支払いを追加する方法。
createClientを使用して@blockchain0x/node(またはPythonクライアント)からエージェントを作成し、payments.createでUSDC支払いを送信し、webhooks.verifyで署名されたウェブフックを確認します。支出制御はダッシュボードで設定され、API経由で読み取り専用です。エージェントはプライベートキーに直接触れることはありません。サインアップからBaseでの最初のUSDC支払いまで10分以内、TypeScriptまたはPythonで。
始める前に。
- Blockchain0xアカウント (無料サインアップ)。
- ダッシュボードからのAPIキー(このガイドには
sk_test_キーを使用してください; 後でsk_live_に切り替えます)。 - エージェントランタイムでNode.js 20+またはPython 3.11+を使用してください。
- 任意のフレームワークで構築されたエージェント - LangChain、CrewAI、AutoGen、LlamaIndex、OpenAI Agents SDK、MCP、またはプレーンSDKコード。指示はフレームワークに依存しません。
- Webhookを受信するために公共インターネットから到達可能なHTTPSエンドポイント(ngrokまたはデプロイプレビューは開発に適しています)。
エージェントプロフィールを作成します。
エージェントプロフィールは、あなたのエージェントが送信または受信するすべての支払いの背後にあるアドレス指定可能なアイデンティティです。ウォレットアドレス、公開ページ、検証バッジ、そして(後に)支出ポリシーを持っています。論理的なエージェントごとに1つ作成してください。
import { createClient } from "@blockchain0x/node";
const client = createClient({ apiKey: process.env.BLOCKCHAIN0X_API_KEY! }); // sk_test_ / sk_live_
const agent = await client.agents.create({ name: "research-bot" });
console.log(agent.id); // "agt_..."
// Public page: https://wallet.blockchain0x.com/a/{slug}from blockchain0x import Client
client = Client() # reads BLOCKCHAIN0X_API_KEY from the environment
agent = client.agents.create(body={"name": "research-bot"})
print(agent["id"]) # "agt_..."
# Public page: https://wallet.blockchain0x.com/a/{slug}After this call, the agent has a public page at https://wallet.blockchain0x.com/a/<slug> that any counterparty (human or agent) can hover for verification info. See the agent payment identity glossary entry for what that page exposes.
支払いを送信します。
payments.create sends USDC from the agent wallet. amountWei is base units (USDC has 6 decimals), so 0.01 USDC is the string "10000". The SDK auto-stamps an Idempotency-Key, and the call can return 503 until the chain adapter is wired for your network. To RECEIVE instead, settle an invoice you created in the dashboard with paymentRequests.settle - see the payment API page.
// Send a USDC payment from the agent wallet. amountWei is base units
// (USDC has 6 decimals): "10000" is 0.01 USDC. payments.create auto-stamps an
// Idempotency-Key and can return 503 until the chain adapter is wired.
const tx = await client.payments.create({
agentId: agent.id,
to: "0xRecipient",
amountWei: "10000",
});
console.log(tx); // the submitted transfer# amountWei is USDC base units (6 decimals): "10000" is 0.01 USDC.
tx = client.payments.create(body={
"agentId": agent["id"],
"to": "0xRecipient",
"amountWei": "10000",
})
print(tx) # the submitted transferWebhookを処理します。
Webhooksは、支払いが決済されたことを知る方法です。Nodeでは、@blockchain0x/nodeからのwebhooks.verifyがHMACチェックを行い、識別されたユニオンを返します。他の言語では、RAWボディに対して同じHMACを計算します。イベントタイプ(inbound用のpayment.received)に基づいて分岐し、迅速に2xxで応答し、2xxの後ろに重いものをキューに入れて、配信がタイムアウトしないようにします。
import express from "express";
import { webhooks } from "@blockchain0x/node";
const app = express();
// Capture the RAW body. The HMAC is over the exact bytes on the wire.
app.use(express.raw({ type: "application/json" }));
app.post("/webhooks/payment", (req, res) => {
const result = webhooks.verify({
headers: req.headers,
rawBody: req.body, // Buffer, raw bytes
secret: process.env.BLOCKCHAIN0X_WEBHOOK_SECRET!,
});
if (!result.ok) return res.status(400).json({ code: result.code });
if (result.eventType === "payment.received") {
// USDC landed - deliver the work, fulfil the order, etc.
void deliver(result.eventId);
}
res.status(200).send("ok");
});import hmac, hashlib, os, time
from flask import Flask, request, abort
app = Flask(__name__)
SECRET = os.environ["BLOCKCHAIN0X_WEBHOOK_SECRET"].encode()
@app.post("/webhooks/payment")
def webhook():
raw = request.get_data() # 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:
abort(401)
if request.headers.get("X-Blockchain0x-Event-Type") == "payment.received":
deliver(request.get_json()) # USDC landed
return ("ok", 200)ダッシュボードで支出制御を設定します。
もしあなたのエージェントが受け取るだけであれば、これをスキップできます。もし支払いも行う場合は、ダッシュボードで支出許可を設定します - 期間ごとの手当とトランザクションごとの上限です。これはすべての支払いでバックエンドによって強制されるため、エージェント側のルールでは決してできない方法でプロンプトインジェクションに耐えます。権限を変更するAPIやSDK呼び出しはありません(エージェント自身のキーはその制限を広げることはできません);APIは読み取り専用であるため、あなたのコードは現在の値を取得して表示または計画することができます。
curl https://api.blockchain0x.com/v1/agents/agt_123/spend-permissions \
-H "Authorization: Bearer $BLOCKCHAIN0X_API_KEY"{
"allowance_wei": "5000000",
"per_tx_wei": "1000000",
"period_seconds": 86400,
"revoked_at": null
}Base Sepolia で全体のフローをテストしてください。
sk_live_キーに切り替える前に、sk_test_でエンドツーエンドのフルパスを実行します。テストキーはすべてをBase Sepoliaに保ち、公共のファウセットからウォレットに資金を提供し、レスポンスの形状がライブと一致します。キーのプレフィックスがネットワークを選択するため、テストキーはメインネットの資金を移動できません。
3つのシナリオを実行します:payment.receivedを発火させるハッピーパス支払い、見逃した配信(ウェブフックを無効なURLに向け、その後transactions.getでトランザクションを取得して調整)、およびウェブフック再試行(最初は500を返し、2回目は200を返し、ハンドラが冪等であることを確認します)。すべて3つがテストに合格したら、キーを交換して出荷します。
チームに1週間の損失をもたらす5つのミス。
Webhook署名検証をスキップ
もしあなたが /webhooks/payment への任意のPOSTを権威あるものとして受け入れるなら、攻撃者は偽の支払いイベントを生成し、あなたのエージェントを騙して無料で作業を提供させることができます。常にWebhookシークレットでHMAC検証を行い、定数時間比較を使用します。最初の妥協はほぼ常に検証の欠如です。
別の確認イベントを想定しています
出荷されたイベントはpayment.received、payment.sent、wallet.deployed、およびwebhook.testです - 別の確認イベントはありません。payment.receivedは転送がブロック内にあるときに発火します。ほとんどの作業において、それは配信のためのシグナルです。高額または不可逆的なものについては、transactions.getでトランザクションをポーリングし、行動する前に自分の確認しきい値を適用してください; 存在しないイベントを待たないでください。
Webhookハンドラーにアイデンポテンスなし
ウェブフックは非2xx応答で再試行し、同じイベントが負荷の下で複数回到着します。ハンドラは冪等である必要があります:すでに処理したイベントIDの小さなテーブルを保持し、重複をスキップします。そうでないと、一時的なブリップが同じ作業を二度配信し、二重実行のデバッグに数時間を費やすことになります。
テストと本番のAPIキーの混合
テストキー(sk_test_)はサンドボックスにヒットし、Base Sepoliaを使用します; ライブキー(sk_live_)は本番環境にヒットし、Baseメインネットを使用します。環境設定で混同することは、ほとんどの「開発では動作するが、本番では失敗する」チケットの原因です。ランタイム環境とキーのプレフィックスが一致しない場合は、起動時にハードフェイルします。
欠落したWebhookを失敗した支払いとして扱う
失敗イベントはなく、Webhookが見逃される可能性があります(エンドポイントがダウンしていた、配信が失敗した)。エージェントを「資金を待機中」のループにスタックさせないでください。調整を行います:transactions.getを使用してトランザクションを取得し、実際の状態を確認し、待機フローにタイムアウトを設定して、放棄された支払いが保持されたリソースを解放するようにします。
最初の支払いを受け取ると。
基本的な支払いが機能するようになると、最も効果的なフォローアップは支出管理(エージェントが予算を持ち逃げできないようにするため)、Webhookの堅牢性(支払いが負荷の下で静かに失われないようにするため)、および身元確認(取引先がエージェントの公開ページを信頼できるようにするため)です。
docs.blockchain0x.comに完全なAPIリファレンスがあります。同じAPIの製品サーフェス: Payment API。