Как добавить платежи к вашему AI-агенту.
Создайте агента с помощью createClient из @blockchain0x/node (или Python клиента), отправьте платеж USDC с помощью payments.create и подтвердите подписанный webhook с помощью webhooks.verify. Контроль расходов устанавливается в панели управления и доступен только для чтения через API. Агент никогда не касается приватных ключей напрямую. Менее десяти минут от регистрации до вашего первого платежа USDC на Base, на TypeScript или Python.
Перед тем как начать.
- Учетная запись Blockchain0x (бесплатная регистрация).
- Ключ API из панели управления (используйте
sk_test_ключ для этого руководства; позже вы переключитесь наsk_live_). - Node.js 20+ или Python 3.11+ в вашем среде выполнения агента.
- Агент, построенный на любом фреймворке - LangChain, CrewAI, AutoGen, LlamaIndex, OpenAI Agents SDK, MCP или обычном коде SDK. Инструкции не зависят от фреймворка.
- HTTPS конечная точка, доступная из публичного интернета для получения вебхуков (ngrok или предварительный просмотр развертывания подходит для разработки).
Создайте профиль агента.
Профиль агента - это адресуемая идентичность за каждым платежом, который ваш агент отправляет или получает. Он содержит адрес кошелька, публичную страницу, значки проверки и (позже) политику расходов. Создайте один для каждого логического агента.
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 transferОбработайте вебхук.
Вебхуки - это способ узнать, что платеж завершен. В Node webhooks.verify из @blockchain0x/node выполняет проверку HMAC и возвращает дискриминированный союз; в других языках вычислите тот же HMAC над сырым телом. Разветвляйтесь по типу события (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, где вы пополняете кошелек из публичного крана, и формы ответов совпадают с живыми. Префикс ключа выбирает сеть, поэтому тестовый ключ не может перемещать средства основной сети.
Протестируйте три сценария: платеж по счастливому пути, который вызывает payment.received, пропущенная доставка (укажите webhook на недоступный URL, затем согласуйте, получив транзакцию с помощью transactions.get) и повторная попытка webhook (верните 500 в первый раз, 200 во второй, и подтвердите, что ваш обработчик идемпотентен). Когда все три пройдут тест, поменяйте ключ и отправляйте.
Пять ошибок, которые стоят командам недели.
Пропуск проверки подписи вебхука
Если вы принимаете любой POST на /webhooks/payment как авторитетный, злоумышленник может создать поддельные события платежа и обмануть вашего агента, заставив его выполнять работу бесплатно. Всегда проверяйте HMAC с секретом вебхука, используя сравнение с постоянным временем. Первое нарушение почти всегда связано с отсутствием проверки.
Предполагая отдельное событие подтверждения
Отгруженные события - payment.received, payment.sent, wallet.deployed и webhook.test - нет отдельного события подтверждения. payment.received срабатывает, когда перевод находится в блоке. Для большинства работ это ваш сигнал для доставки. Для чего-то дорогого или необратимого опрашивайте транзакцию с помощью transactions.get и применяйте свой собственный порог подтверждения перед действием; не ждите события, которого не существует.
Нет идемпотентности на обработчиках вебхуков
Вебхуки повторяют попытки при ответах, отличных от 2xx, и одно и то же событие будет приходить несколько раз под нагрузкой. Ваш обработчик должен быть идемпотентным: храните небольшую таблицу идентификаторов событий, которые вы уже обработали, и пропускайте дубликаты. В противном случае временный сбой доставит одну и ту же работу дважды, и вы потратите часы на отладку двойных выполнений.
Смешивание тестовых и рабочих ключей API
Тестовые ключи (sk_test_) попадают в песочницу и используют Base Sepolia; живые ключи (sk_live_) попадают в продакшн и используют Base mainnet. Смешивание их в конфигурациях окружения является причиной большинства билетов 'работает в dev, не работает в prod'. Жесткое завершение при запуске, если ваша среда выполнения и префикс ключа не совпадают.
Рассмотрение отсутствующего вебхука как неудачного платежа.
Нет события сбоя, и вебхук может быть пропущен (ваш конечный пункт был недоступен, доставка была потеряна). Не оставляйте агента застрявшим в цикле 'ожидания средств'. Согласуйте: получите транзакцию с помощью transactions.get, чтобы узнать реальное состояние, и установите тайм-аут для любого ожидающего потока, чтобы заброшенный платеж освободил удерживаемые ресурсы, а не завис навсегда.
Как только вы получите свой первый платеж.
С работой основных платежей наиболее полезные последующие действия - это контроль расходов (чтобы агент не мог сбежать с бюджетом), надежность вебхуков (чтобы платежи не терялись под нагрузкой) и верификация личности (чтобы контрагенты доверяли публичной странице агента).
Настройте контроль расходов агента, который переживет инъекцию подсказок
Шаблоны вебхуков, о которых разработчики спрашивают чаще всего
Заработайте значки проверки GitHub и домена
Полная справка по API находится на docs.blockchain0x.com. Продуктовая поверхность для тех же API: Payment API.