mcpField
B
bnbagent

bnbagent

github.com/starchild-ai-agentエージェントワークフロー3060 回インストール6 日前に更新
リポジトリ

bnbagent について

BNB Chain 上でオンチェーン AI エージェントを構築する Python SDK です。ERC-8004 のエージェント ID と ERC-8183 のエスクロー型ジョブを個別に扱い、複数のウォレットとストレージ方式を利用できます。

主な機能

  1. 01ERC-8004 エージェント ID の登録
  2. 02ERC-8183 ジョブの作成と管理
  3. 03入金済みジョブの監視と成果物の提出
  4. 04異議申し立てへの投票と返金
  5. 05EVM と TWAK のウォレットバックエンド

活用シーン

  1. 01BSC でのエージェント ID 登録
  2. 02入金済みジョブの受注と納品
  3. 03提供者向けジョブの作成と入金
  4. 04異議のあるジョブへの投票

MCP 対応

MCP を含むサービスインターフェースの選択は実装者に委ねられています。サンプルには、MCP を選択可能なインターフェースとして扱うエージェントサーバーがあります。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/starchild-ai-agent/official-skills --skill bnbagent

インストール後、Claude Code で/bnbagentを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

examples/
auto_settle.py
README.md
examples/a2a-agent/
.env.example
pyproject.toml
README.md
examples/a2a-agent/scripts/
buyer.py
register.py
examples/a2a-agent/src/
server.py
examples/agent-server/
.env.example
pyproject.toml
README.md
examples/agent-server/scripts/
register.py
run_agent_mount.py
run_agent.py
settle.py
examples/agent-server/src/
erc8183_server.py
service_mount.py
service.py
examples/client/
_helpers.py
.env.example
cancel_open.py
create_and_verify.py
dispute_reject.py
gen_job_report.py
happy.py
never_submit.py
README.md
stalemate_expire.py
examples/security/
e2e.py
examples/twak/
.env.example

詳細

BNBAgent SDK

BNB Chain 上のオンチェーン AI エージェント向けの Python SDK(pip install bnbagent、Python 3.10+)です。互いに独立した 2 つの機能があります:

  • ERC-8004(アイデンティティ) — エージェントを、検出可能なプロフィール URI を持つ ERC-721 アイデンティティトークンとしてオンチェーンに登録します。BSC Testnet では MegaFuel paymaster によりガス代が無料です。
  • ERC-8183(エージェント型コマース) — クライアント(支払う側)とプロバイダー(納品する側)の間のトラストレスなジョブエスクローです。楽観的決済: 異議申立て期間を過ぎても沈黙していれば承認とみなされ、クライアントが異議を申し立てるとホワイトリスト登録された投票者の定足数による却下が引き起こされます。

これらは独立しています: ERC-8004 への登録なしで ERC-8183 のジョブを実行できます(登録は検出のためにのみ推奨されます)。

活発に開発中 — 破壊的な変更が発生する可能性があります。bnbagent==0.4.0 でテスト済みです。インストールは python -c "import bnbagent; print(bnbagent.__version__)" で確認してください。オプションの追加機能: IPFS/Pinata への成果物保存には pip install "bnbagent[ipfs]"。

⚠️ メインネットの経済性 — メインネットでのコマースの前に必ずお読みください

  • 支払いトークンは U(United Stables) 0xcE24439F2D9C6a2289F741120FE202248B666666 です — BNB でも USDT/USDC でもありません。これ用のフォーセットはありません: PancakeSwap で U を入手してください(WBNB–U ペアが存在します)。クライアントは fund() を呼び出す前に U を保有している必要があります。decimals は実行時に erc8183.token_decimals() で取得してください — 決め打ちしないでください。
  • メインネットでの ERC-8183 の書き込みは決してガス代がスポンサードされません。 クライアントとプロバイダーの両方がガス代用の BNB を必要とします(メインネットでスポンサードされるのは ERC-8004 のアイデンティティ登録のみです)。
  • メインネットの異議申立て期間は 604800 秒(7 日間)です。 正常系の経路では 1 回のセッションで COMPLETED に到達できません — 沈黙による承認は期間が過ぎてから初めて有効になります。部分的な E2E(SUBMITTED まで)を計画し、後で cron/オペレータースクリプト(examples/auto_settle.py)で決済してください。この 1 週間の間に settle が policy pending でリバートするのは想定どおりであり、エラーではありません。
事前残高チェックリスト(メインネット)
関係者必要なもの理由
クライアントBNBcreateJob/registerJob/setBudget/approve/fund のガス代(+任意のスワップのガス代)
クライアントUfund でエスクローされるジョブ予算(+再試行用の少額の残高)
プロバイダーBNBsubmit のガス代 — メインネットではスポンサードされません
決済者(誰でも)BNB期間経過後の settle のガス代

何をするのかを決める

目的使用するものリファレンス
エージェントのアイデンティティをオンチェーンに登録するERC8004Agent下記のクイックスタート
稼ぐ: 資金提供されたジョブを承諾して納品するERC8183JobOps + funded_job_watcher下記のクイックスタート、examples/agent-server/、examples/a2a-agent/
支払う: ジョブを作成/資金提供/決済するERC8183Client下記のクイックスタート、examples/client/
異議申立てに投票する(ホワイトリスト登録された投票者)PolicyClient.vote_rejectexamples/voter/
HTTP 402 チャレンジ(x402)を支払うX402Signer / twak 委任支払者examples/x402/、references/twak.md
内部構造を理解する/拡張する—references/architecture.md
ウォレットバックエンド(EVM keystore と twak)EVMWalletProvider / TWAKProviderreferences/wallets.md、references/twak.md

クイックスタート: エージェントを登録する(ERC-8004)

1 回だけのセットアップです。秘密鍵(省略時は自動生成されます)と WALLET_PASSWORD が必要です。

import os
from bnbagent import ERC8004Agent, AgentEndpoint, EVMWalletProvider

wallet = EVMWalletProvider(
    password=os.getenv("WALLET_PASSWORD"),
    private_key=os.getenv("PRIVATE_KEY"),  # only needed on first run; keystore persists to ~/.bnbagent/wallets/
)
sdk = ERC8004Agent(network="bsc-testnet", wallet_provider=wallet)

agent_uri = sdk.generate_agent_uri(
    name="my-ai-agent",
    description="AI agent for document processing",
    endpoints=[
        AgentEndpoint.a2a("https://my-agent.example.com"),                      # A2A first (discovery doc URL)
        AgentEndpoint.mcp("https://my-agent.example.com/mcp", version="2025-06-18"),  # MCP second, if served
    ],
)
result = sdk.register_agent(agent_uri=agent_uri)
# result["agentId"], result["transactionHash"]

クイックスタート: プロバイダー(earn ループ、ヘッドレス)

サーバーは不要です。資金提供されたジョブを監視し、作業を行い、提出します:

import asyncio
from bnbagent import EVMWalletProvider
from bnbagent.erc8183 import ERC8183JobOps, funded_job_watcher
from bnbagent.storage import LocalStorageProvider

wallet = EVMWalletProvider(password="...", private_key="0x...")
ops = ERC8183JobOps(
    wallet,
    network="bsc-testnet",
    storage_provider=LocalStorageProvider(),
    service_price=1_000_000_000_000_000_000,      # min acceptable budget, raw units (18 decimals here)
    agent_url="http://localhost:8003/erc8183",    # public URL; required for file:// deliverable rewriting
)

async def on_funded(job: dict) -> None:
    deliverable = f"Processed: {job['description']}"   # your business logic
    await ops.submit_result(job["jobId"], deliverable)

asyncio.run(funded_job_watcher(ops, on_funded, interval=30))
  • submit_result は検証(FUNDED ステータス、割り当て、有効期限、budget ≥ service_price)、成果物のアップロード、マニフェストのハッシュ化、および submit トランザクションを処理します。
  • ウォッチャーが自ら提出や決済を行うことはありません。決済は別のステップです — 異議申し立て期間の経過後に、ERC8183Client.settle(job_id) を呼び出すオペレータースクリプトを実行してください(examples/auto_settle.py、examples/agent-server/scripts/settle.py)。
  • job 辞書のフィールド: jobId、description、budget、client、provider、evaluator、status(常に FUNDED)、expiredAt、hook。
  • 提供インターフェース(A2A/MCP/HTTP)は任意です — examples/a2a-agent/(推奨)と examples/agent-server/(FastAPI)のリファレンスをコピーして自ら管理してください。
  • 成果物のストレージ: https://example.invalid/manifest.json のようなプレースホルダー URL(examples/client/happy.py と同様)は、チェーン上のみのデモであり、投票者は成果物を検証できません。クライアントが異議を申し立てる可能性があるものについては、実際のストレージ(公開された ERC8183_AGENT_URL の背後にある LocalStorageProvider、または IPFSStorageProvider)を使用してください。

クイックスタート: クライアント(ジョブの作成と支払い)

import time
from bnbagent.erc8183 import ERC8183Client, JobStatus
from bnbagent.wallets import EVMWalletProvider

wallet = EVMWalletProvider(password="...", private_key="0x...")
erc8183 = ERC8183Client(wallet, network="bsc-testnet")

budget = 1 * (10 ** erc8183.token_decimals())   # DEMO-SCALE (1 full token). On MAINNET use tiny
                                                # budgets, e.g. (10 ** dec) // 100 for 0.01 U.
expired_at = int(time.time()) + 65 * 60

job_id = erc8183.create_job(provider=provider_addr, expired_at=expired_at, description="task")["jobId"]
erc8183.register_job(job_id)          # bind default policy (OptimisticPolicy)
erc8183.set_budget(job_id, budget)
erc8183.fund(job_id, budget)          # escrows; auto-approves payment token with 100-token floor

# ... provider submits ... dispute window elapses ...
erc8183.settle(job_id)                # permissionless — anyone can call
assert erc8183.get_job_status(job_id) == JobStatus.COMPLETED

異議申し立てとエスケープハッチ:

erc8183.dispute(job_id)        # client only, within dispute window after submit
erc8183.vote_reject(job_id)    # whitelisted voters only, after dispute; quorum flips verdict to REJECT
erc8183.claim_refund(job_id)   # anyone, after expiredAt if never settled — non-pausable escape hatch

fund(job_id, amount, approve_floor=None): デフォルトでは、ジョブストリーム間で再承認を避けるために max(amount, 100 * 10**decimals) を承認します。approve_floor=0 は正確に amount を承認します。allowance がすでにそれをカバーしている場合は、承認は送信されません。

ジョブのライフサイクル

OPEN ──► FUNDED ──► SUBMITTED ──┬─ silence past window ──► COMPLETED (provider paid, minus platform fee)
  │         │                   ├─ dispute + quorum reject ──► REJECTED (client refunded)
  │         │                   └─ no verdict + past expiredAt ──► EXPIRED (client claimRefund)
  │         └─ past expiredAt ──► EXPIRED (claimRefund)
  └─ client reject() before funding ──► REJECTED

ガススポンサーシップのマトリクス

プロトコル / 書き込みBSC TestnetBSC Mainnet
ERC-8004 register_agent✅ スポンサーあり (MegaFuel)✅ スポンサーあり (MegaFuel) — BNB 残高ゼロのウォレットでも動作します
ERC-8183 create/fund/submit/settle🟡 呼び出しごと: MegaFuel が判断(現在 fund/settle はスポンサーあり)。拒否された呼び出しは自己負担❌ スポンサーなし — すべての書き込みは BNB の自己負担
支払いトークンの ERC-20 approve(allowance 不足時に fund 内で送信される)❌ 常に自己負担 — 新しいテストネット購入者には少しの tBNB が必要❌ 自己負担
twak ウォレット操作❌ twak が自己負担(twak 内部、SDK に制御なし)✅ twak が自動スポンサー — references/twak.md を参照

ネットワークとコントラクト

BSC Testnet (chain 97) — フォーセット: tBNB、U tokens

コントラクトアドレス
Identity Registry (ERC-8004)0x8004A818BFB912233c491871b3d84c89A494BD9e
AgenticCommerce0xa206c0517b6371c6638cd9e4a42cc9f02a33b0de
EvaluatorRouter0xd7d36d66d2f1b608a0f943f722d27e3744f66f25
OptimisticPolicy0x4f4678d4439fec812ac7674bb3efb4c8f5fb78a6

BSC Mainnet (chain 56)

コントラクトアドレス
Identity Registry (ERC-8004)0x8004A169FB4a3325136EB29fA0ceB6D2e539a432
AgenticCommerce0xea4daa3100a767e86fded867729ae7446476eba6
EvaluatorRouter0x51895229e12f9876011789b04f8698af06ccd6da
OptimisticPolicy0x9c01845705b3078aa2e8cff7520a6376fd766de5

支払いトークンのアドレスは設定可能ではありません — 実行時に Commerce カーネルから読み取られます(ERC8183Client.payment_token)。メインネットでは U (United Stables) 0xcE24…6666 に解決されます(冒頭のメインネット経済セクションを参照)。

注意:

  • SDK コンストラクターはデフォルトで network="bsc-testnet" です — メインネット作業では常に network="bsc-mainnet"(または NETWORK=bsc-mainnet)を明示的に渡し、bscscan.com(testnet.bscscan.com ではなく)のエクスプローラーリンクを出力してください。一部のサンプルスクリプトはテストネット URL をハードコードしています。
  • ディスカバリ/インデクサーの遅延: URI に実際の名前が含まれていても、レジストリインデックスに汎用的な名前(例: Agent #198565)が表示されることがあります。オンチェーン URI が信頼できる情報源です。インデクサーの名前は遅延したり、汎用的なままになることがあります。

環境変数

注釈付きの完全なリファレンス: references/env.example。必須のものは以下のとおりです:

変数必須備考
WALLET_PASSWORDはい~/.bnbagent/wallets/ のキーストアを暗号化/復号します。
PRIVATE_KEY初回実行時のみインポートされて暗号化され、その後削除可能です。存在しない場合はウォレットを自動生成します。
WALLET_ADDRESSいいえ複数のキーストアが存在する場合に 1 つを選択します。
NETWORKいいえ (bsc-testnet)または bsc-mainnet。
RPC_URLいいえカスタム RPC エンドポイント。
ERC8183_SERVICE_PRICEいいえ (1e18)プロバイダーの最低予算、生の単位。
ERC8183_AGENT_URLLocalStorageProvider の場合/erc8183 を含む公開ベース URL。file:// の成果物 URL はこれに書き換えられます。
STORAGE_API_KEYIPFSStorageProvider の場合Pinata 互換の JWT。
STORAGE_LOCAL_PATHいいえ (.agent-data)ローカルの成果物ディレクトリ。

ストレージバックエンドは環境変数ではなくコード内で選択します (storage_provider= を渡します)。

セキュリティルール (エージェントのフローで重要)

  • EIP-712 署名はデフォルトでポリシーによって制御されます。 EVMWalletProvider.sign_typed_data は、BSC 56/97 上の U-token に対する EIP-3009 の TransferWithAuthorization/ReceiveWithAuthorization のみを受け付けます。EIP-2612 の Permit および Permit2 の PermitSingle/PermitBatch は無条件で拒否リストに登録されています (無制限のアローワンスを付与するため、悪意のある 402 サーバーがウォレットを流出させる可能性があります)。エージェントから到達可能なコードでこれを回避しようとしないでください。SigningPolicy.permissive() と _DANGEROUS_sign_typed_data_no_policy() はテスト専用です。
  • ツール関数に生の WalletProvider を絶対に渡さないでください。 スコープ付きの X402Signer(wallet, max_value_per_call={token: ...}, session_budget={token: ...}) を渡し、expected_to は常に設定またはオンチェーンレジストリから渡してください — 402 チャレンジのボディからは決して渡さないでください。
  • カスタムトークン/型: SigningPolicy.strict_default().extend(domain_allowlist={(chain_id, contract)}, primary_type_allowlist={"MyType"}) — Permit の拒否リストは依然として優先されます。
  • claimRefund は一時停止不可かつフック不可です。資金は expiredAt を過ぎても常に回収可能です。
  • 使い捨て/デモ用キー: EVMWalletProvider(persist=False) を使用して、一度限りのキーがディスクに一切触れないようにし、デモ用キーを本番環境で再利用しないでください。本番用の秘密鍵をチャットやログに貼り付けないでください — キーストア + WALLET_PASSWORD のフローを優先してください。

完全な根拠、デシジョンツリー、例: references/sdk-readme.md (セキュリティのセクション) および examples/security/e2e.py。

ウォレットバックエンド

  • EVMWalletProvider (デフォルト) — Keystore V3 (MetaMask/Geth 互換)、~/.bnbagent/wallets/ に永続化、または persist=False でメモリ内に保持。
  • TWAKProvider (Trust Wallet Agent Kit) — セルフカストディ、セルフブロードキャスト。生のトランザクションや汎用の EIP-712 署名はなし。BSC のみ。x402 は委任ペイヤー make_x402_payer() 経由。使用前に references/twak.md をお読みください — サポートされていない呼び出しは UnsupportedWalletOperation を発生させます。切り替え: TWAKProvider(chain="bsc") または WALLET_KIND=twak。
  • カスタム (HSM、MPC、KMS): WalletProvider をサブクラス化します。詳細: references/wallets.md。
AA / セルフブロードキャストウォレット(Privy、ZeroDev など) — 既知の統合コスト

生の署名済みトランザクションの代わりに Intent/UserOperation を送信するアカウント抽象化ウォレットは、SDK ではまだファーストクラスではありません(BSC メインネットで Privy AA クライアント、bnbagent==0.4.0 を使って現場検証済み)。想定されることと、うまくいった回避策は次のとおりです。

  • ERC-20 の approve が失敗する: approve_payment_token は _send_tx → 生の sign_transaction を経由しますが、AA ウォレットはこれを実装していません(sign.transaction: wallet does not implement raw-transaction signing)。回避策: 支払いトークンに対して approve(commerce, amount) を AA スタック経由で手動実行し、その後 fund_bundles_approval=True で fund を呼び出します。create_job/set_budget/fund 自体はカスタム Intent エグゼキューター(エグゼキューター / WalletProvider をサブクラス化)を通じて動作します。
  • create_job 後に jobId が None で返る: AA ウォレットは tx ハッシュではなく user_operation_hash を返し、create_job はレシートログから jobId しか解析しません。回避策: 取り込みを待ってから jobCounter を逆方向にスキャンする(または client + provider + description で最近のジョブをインデックス化する)ことで自分のジョブを見つけます。
  • ドキュメント化されたセルフブロードキャストウォレットには TWAKProvider(references/twak.md)を使用してください。Privy スタイルのアダプターは現状、自作する必要があります。

トラブルシューティング

エラー原因 → 修正
No PRIVATE_KEY and no keystore found新しいウォレットが自動生成された、またはインポートするために PRIVATE_KEY を設定してください。
Multiple wallets foundWALLET_ADDRESS=0x... を設定してください。
403 Provider mismatchジョブが別のプロバイダーに割り当てられています — job.provider を確認してください。
409 Not FUNDEDジョブはすでに送信済み/決済済みです。
408 Job expiredexpiredAt を過ぎています。クライアントは claimRefund を実行し、新しいジョブを作成できます。
402 Budget below service priceクライアントは ERC8183_SERVICE_PRICE 以上を入金する必要があります。
settle が policy pending でリバート異議申立て期間が経過しておらず、異議もありません — 待ってから再試行してください。メインネットでは期間は7 日間です。
voteReject が not voter/not disputed でリバート呼び出し元がホワイトリストに登録されていない、または異議がありません — examples/voter/vote_reject.py を使用してください。
register_job でリバートセレクター 0xcdbc1d27ジョブはすでにポリシーにバインドされています — 再登録は設計上リバートします。job_policy(job_id) がすでに設定されていれば成功として扱ってください。
sign.transaction: wallet does not implement raw-transaction signingAA/セルフブロードキャストウォレットが生の tx の approve パスに到達しました — 上記の AA ウォレットのセクションを参照してください。
create_job 後に jobId が NoneAA ウォレットが user-op ハッシュを返し、解析するレシートがありません — jobCounter を逆方向にスキャンして自分のジョブを探してください。
fund 試行後もアローワンスが 0 のままバンドルされた approve がまったく着地していません(誤ったウォレットパス) — 手動で approve(commerce, amount) を実行し、その後 fund を実行してください。

このスキルに含まれるファイル

  • references/sdk-readme.md — 上流 SDK の完全な README(上記すべてについての詳細な説明)
  • references/architecture.md — コードマップ、レイヤリング、不変条件
  • references/twak.md — TWAK ウォレットのサポートマトリックスと境界
  • references/wallets.md — ウォレットプロバイダーの詳細解説
  • references/env.example — 注釈付きの環境変数リファレンス
  • examples/ — コピーして自分のものにできるスクリプト: client/(5 つの標準的なジョブフロー)、a2a-agent/、agent-server/、voter/、twak/、x402/、security/、auto_settle.py

コメント