bnbagent
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBNBAgent SDK
BNBAgent SDK
Python SDK (, Python 3.10+) for on-chain AI agents on BNB Chain. Two independent capabilities:
pip install bnbagent- ERC-8004 (identity) — register an agent on-chain as an ERC-721 identity token with a discoverable profile URI. Gas-free on BSC Testnet via MegaFuel paymaster.
- ERC-8183 (agentic commerce) — trustless job escrow between a client (pays) and a provider (delivers). Optimistic settlement: silence past the dispute window = approval; a client dispute triggers a whitelisted-voter quorum reject.
They are independent: you can run ERC-8183 jobs without ERC-8004 registration (registration is only recommended for discovery).
Active development — breaking changes possible. Tested with; verify install withbnbagent==0.4.0. Optional extra:python -c "import bnbagent; print(bnbagent.__version__)"for IPFS/Pinata deliverable storage.pip install "bnbagent[ipfs]"
面向BNB Chain链上AI Agent的Python SDK(,要求Python 3.10+),具备两项独立功能:
pip install bnbagent- ERC-8004(身份协议) — 将Agent作为带有可发现配置文件URI的ERC-721身份代币在链上注册。在BSC测试网可通过MegaFuel支付方实现免Gas费。
- ERC-8183(Agent商业协议) — 实现客户(付费方)与服务提供者(交付方)之间的无信任任务托管。采用乐观结算机制:争议窗口期过后无异议即视为批准;客户发起争议则触发白名单投票者的多数否决机制。
两项功能相互独立:无需完成ERC-8004注册即可运行ERC-8183任务(仅推荐用于Agent发现场景时进行注册)。
项目处于活跃开发阶段——可能存在破坏性变更。已基于测试;可通过bnbagent==0.4.0验证安装版本。可选扩展:执行python -c "import bnbagent; print(bnbagent.__version__)"以支持IPFS/Pinata交付物存储。pip install "bnbagent[ipfs]"
⚠️ Mainnet economics — read BEFORE any mainnet commerce
⚠️ 主网经济规则 — 开展主网交易前必读
- The payment token is U (United Stables) — not BNB, not USDT/USDC. There is no faucet for it: acquire U on PancakeSwap (a WBNB–U pair exists). The client must hold U before calling
0xcE24439F2D9C6a2289F741120FE202248B666666. Fetch decimals at runtime viafund()— don't assume.erc8183.token_decimals() - ERC-8183 writes on mainnet are never gas-sponsored. Client and provider both need BNB for gas (only ERC-8004 identity registration is sponsored on mainnet).
- The mainnet dispute window is 604800s (7 days). A happy path cannot reach in one session — silence-approval only kicks in after the window. Plan a partial E2E (through
COMPLETED) and settle later via a cron/operator script (SUBMITTED).examples/auto_settle.pyreverting withsettleduring this week is expected, not an error.policy pending
- 支付代币为U(United Stables) — 并非BNB、USDT或USDC。目前没有该代币的水龙头:需在PancakeSwap上获取U(存在WBNB-U交易对)。客户在调用
0xcE24439F2D9C6a2289F741120FE202248B666666前必须持有U。请通过fund()在运行时获取小数位数——不要自行假设。erc8183.token_decimals() - ERC-8183主网写入操作永远不提供Gas赞助。客户和服务提供者都需要BNB支付Gas费(仅ERC-8004身份注册在主网提供赞助)。
- 主网争议窗口期为604800秒(7天)。正常流程无法在一次会话中达到状态——只有窗口期过后无异议才会触发批准。建议规划部分端到端流程(执行到
COMPLETED状态),之后通过定时任务/操作员脚本(SUBMITTED)完成结算。在此周内examples/auto_settle.py返回settle属于预期情况,并非错误。policy pending
Preflight balance checklist (mainnet)
主网预飞行余额检查清单
| Party | Needs | Why |
|---|---|---|
| Client | BNB | gas for |
| Client | U | the job budget escrowed by |
| Provider | BNB | gas for |
| Settler (anyone) | BNB | gas for |
| 角色 | 所需资产 | 原因 |
|---|---|---|
| 客户 | BNB | 支付 |
| 客户 | U | |
| 服务提供者 | BNB | 支付 |
| 结算者(任意角色) | BNB | 窗口期过后支付 |
Decide what you're doing
确定你的使用场景
| Goal | Use | Reference |
|---|---|---|
| Register agent identity on-chain | | quick start below |
| Earn: accept + deliver funded jobs | | quick start below, |
| Pay: create/fund/settle jobs | | quick start below, |
| Vote on disputes (whitelisted voter) | | |
| Pay HTTP 402 challenges (x402) | | |
| Understand internals / extend | — | |
| Wallet backends (EVM keystore vs twak) | | |
| 目标 | 使用组件 | 参考资源 |
|---|---|---|
| 在链上注册Agent身份 | | 下方快速开始指南 |
| 赚取报酬:接受并交付已资助任务 | | 下方快速开始指南、 |
| 支付费用:创建/资助/结算任务 | | 下方快速开始指南、 |
| 对争议进行投票(白名单投票者) | | |
| 支付HTTP 402挑战(x402) | | |
| 理解内部机制/扩展功能 | — | |
| 钱包后端(EVM密钥库 vs twak) | | |
Quick start: register an agent (ERC-8004)
快速开始:注册Agent(ERC-8004)
One-time setup. Needs a private key (auto-generated if omitted) and .
WALLET_PASSWORDpython
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)一次性设置。需要私钥(若省略则自动生成)和。
WALLET_PASSWORDpython
import os
from bnbagent import ERC8004Agent, AgentEndpoint, EVMWalletProvider
wallet = EVMWalletProvider(
password=os.getenv("WALLET_PASSWORD"),
private_key=os.getenv("PRIVATE_KEY"), # 仅首次运行需要;密钥库将持久化到~/.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(发现文档URL)
AgentEndpoint.mcp("https://my-agent.example.com/mcp", version="2025-06-18"), # 若提供MCP服务则其次设置
],
)
result = sdk.register_agent(agent_uri=agent_uri)result["agentId"], result["transactionHash"]
result["agentId"], result["transactionHash"]
undefinedundefinedQuick start: provider (earn loop, headless)
快速开始:服务提供者(赚取报酬循环,无头模式)
No server needed. Watch for funded jobs, do the work, submit:
python
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))- handles verification (FUNDED status, assignment, expiry, budget ≥ service_price), deliverable upload, manifest hashing, and the
submit_resulttx.submit - The watcher never submits or settles by itself. Settlement is a separate step — run an operator script calling after the dispute window elapses (
ERC8183Client.settle(job_id),examples/auto_settle.py).examples/agent-server/scripts/settle.py - dict fields:
job,jobId,description,budget,client,provider,evaluator(alwaysstatus),FUNDED,expiredAt.hook - Serving surface (A2A/MCP/HTTP) is your choice — copy-and-own references in (recommended) and
examples/a2a-agent/(FastAPI).examples/agent-server/ - Deliverable storage: placeholder URLs like (as in
https://example.invalid/manifest.json) are chain-only demos — voters cannot verify the deliverable. For anything a client might dispute, use real storage (examples/client/happy.pybehind a publicLocalStorageProvider, orERC8183_AGENT_URL).IPFSStorageProvider
无需服务器。监听已资助任务,完成工作并提交成果:
python
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, # 最低可接受预算,原始单位(此处为18位小数)
agent_url="http://localhost:8003/erc8183", # 公共URL;重写file://交付物URL时必需
)
async def on_funded(job: dict) -> None:
deliverable = f"Processed: {job['description']}" # 你的业务逻辑
await ops.submit_result(job["jobId"], deliverable)
asyncio.run(funded_job_watcher(ops, on_funded, interval=30))- 会处理验证(FUNDED状态、任务分配、过期时间、预算≥service_price)、交付物上传、清单哈希计算以及
submit_result交易。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/(FastAPI)中的参考实现。examples/agent-server/ - 交付物存储:这类占位符URL(如
https://example.invalid/manifest.json中所示)仅为链上演示——投票者无法验证交付物。对于客户可能发起争议的场景,请使用真实存储(公共examples/client/happy.py后端的ERC8183_AGENT_URL,或LocalStorageProvider)。IPFSStorageProvider
Quick start: client (create and pay for a job)
快速开始:客户(创建并支付任务)
python
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 floorpython
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()) # 演示规模(1个完整代币)。主网请使用小额预算,例如(10 ** dec) // 100表示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) # 绑定默认策略(OptimisticPolicy)
erc8183.set_budget(job_id, budget)
erc8183.fund(job_id, budget) # 托管资金;自动以100代币为下限批准支付代币... provider submits ... dispute window elapses ...
... 服务提供者提交成果 ... 争议窗口期结束 ...
erc8183.settle(job_id) # permissionless — anyone can call
assert erc8183.get_job_status(job_id) == JobStatus.COMPLETED
Disputes and escape hatch:
```python
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 hatchfund(job_id, amount, approve_floor=None)max(amount, 100 * 10**decimals)approve_floor=0amounterc8183.settle(job_id) # 无权限限制——任意角色均可调用
assert erc8183.get_job_status(job_id) == JobStatus.COMPLETED
争议处理与应急方案:
```python
erc8183.dispute(job_id) # 仅客户可在提交后争议窗口期内调用
erc8183.vote_reject(job_id) # 仅白名单投票者可在争议发起后调用;多数票会将裁决结果改为REJECT
erc8183.claim_refund(job_id) # 任意角色均可在expiredAt过后且未结算时调用——不可暂停的应急方案fund(job_id, amount, approve_floor=None)max(amount, 100 * 10**decimals)approve_floor=0amountJob lifecycle
任务生命周期
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 ──► REJECTEDOPEN ──► FUNDED ──► SUBMITTED ──┬─ 窗口期过后无异议 ──► COMPLETED(服务提供者获得报酬,扣除平台手续费)
│ │ ├─ 发起争议 + 多数票否决 ──► REJECTED(客户获得退款)
│ │ └─ 无裁决结果 + 超过expiredAt ──► EXPIRED(客户可claimRefund)
│ └─ 超过expiredAt ──► EXPIRED(可claimRefund)
└─ 客户在资助前调用reject() ──► REJECTEDGas sponsorship matrix
Gas赞助矩阵
| Protocol / write | BSC Testnet | BSC Mainnet |
|---|---|---|
ERC-8004 | ✅ sponsored (MegaFuel) | ✅ sponsored (MegaFuel) — works with a zero-BNB wallet |
| ERC-8183 create/fund/submit/settle | 🟡 per-call: MegaFuel decides ( | ❌ never sponsored — all writes self-pay BNB |
ERC-20 | ❌ always self-pays — fresh testnet buyer needs a little tBNB | ❌ self-pays |
| twak wallet ops | ❌ twak self-pays (twak-internal, SDK has no control) | ✅ twak auto-sponsors — see |
| 协议 / 写入操作 | BSC测试网 | BSC主网 |
|---|---|---|
ERC-8004 | ✅ 赞助(MegaFuel) | ✅ 赞助(MegaFuel)——零BNB钱包也可使用 |
| ERC-8183 create/fund/submit/settle | 🟡 按调用决定:MegaFuel当前赞助 | ❌ 从不赞助——所有写入操作需自行支付BNB |
ERC-20支付代币 | ❌ 始终需自行支付——新的测试网用户需要少量tBNB | ❌ 需自行支付 |
| twak钱包操作 | ❌ twak自行支付(twak内部流程,SDK无法控制) | ✅ twak自动赞助——详见 |
Networks & contracts
网络与合约
| Contract | Address |
|---|---|
| Identity Registry (ERC-8004) | |
| AgenticCommerce | |
| EvaluatorRouter | |
| OptimisticPolicy | |
BSC Mainnet (chain 56)
| Contract | Address |
|---|---|
| Identity Registry (ERC-8004) | |
| AgenticCommerce | |
| EvaluatorRouter | |
| OptimisticPolicy | |
The payment token address is NOT configurable — it is read from the Commerce kernel at runtime (). On mainnet it resolves to U (United Stables) (see the mainnet economics section at the top).
ERC8183Client.payment_token0xcE24…6666Notes:
- The SDK constructor defaults to — always pass
network="bsc-testnet"explicitly (ornetwork="bsc-mainnet") for mainnet work, and printNETWORK=bsc-mainnet(notbscscan.com) explorer links; some example scripts hardcode testnet URLs.testnet.bscscan.com - Discovery/indexer lag: the registry index may show a generic name (e.g. ) even when your URI carries the real name. The on-chain URI is the source of truth; indexer names can lag or stay generic.
Agent #198565
| 合约 | 地址 |
|---|---|
| 身份注册表(ERC-8004) | |
| AgenticCommerce | |
| EvaluatorRouter | |
| OptimisticPolicy | |
BSC主网(链ID 56)
| 合约 | 地址 |
|---|---|
| 身份注册表(ERC-8004) | |
| AgenticCommerce | |
| EvaluatorRouter | |
| OptimisticPolicy | |
支付代币地址不可配置——会在运行时从商业核心合约读取()。主网支付代币为U(United Stables) (详见顶部主网经济规则部分)。
ERC8183Client.payment_token0xcE24…6666注意事项:
- SDK构造函数默认——主网工作时请显式传递
network="bsc-testnet"(或设置network="bsc-mainnet"),并打印NETWORK=bsc-mainnet(而非bscscan.com)浏览器链接;部分示例脚本硬编码了测试网URL。testnet.bscscan.com - 发现/索引器延迟:即使你的URI包含真实名称,注册表索引可能仍显示通用名称(例如)。链上URI为可信数据源;索引器名称可能存在延迟或保持通用。
Agent #198565
Environment variables
环境变量
Full annotated reference: . The essentials:
references/env.example| Variable | Required | Notes |
|---|---|---|
| Yes | Encrypts/decrypts the keystore at |
| First run only | Imported and encrypted, then removable. Auto-generates a wallet if absent. |
| No | Pick a keystore when several exist. |
| No ( | Or |
| No | Custom RPC endpoint. |
| No ( | Provider's minimum budget, raw units. |
| If LocalStorageProvider | Public base URL incl. |
| If IPFSStorageProvider | Pinata-compatible JWT. |
| No ( | Local deliverable dir. |
Storage backend is chosen in code (pass ), not by env var.
storage_provider=完整带注释的参考:。核心变量:
references/env.example| 变量 | 是否必填 | 说明 |
|---|---|---|
| 是 | 加密/解密 |
| 仅首次运行 | 导入并加密后即可移除。若未提供则自动生成钱包。 |
| 否 | 存在多个钱包时指定使用的密钥库。 |
| 否(默认 | 可选 |
| 否 | 自定义RPC端点。 |
| 否(默认 | 服务提供者的最低预算,原始单位。 |
| 使用LocalStorageProvider时必填 | 包含 |
| 使用IPFSStorageProvider时必填 | 兼容Pinata的JWT。 |
| 否(默认 | 本地交付物存储目录。 |
存储后端通过代码指定(传递参数),而非环境变量。
storage_provider=Security rules (important for agent flows)
安全规则(Agent流程关键注意事项)
- EIP-712 signing is policy-gated by default. only accepts EIP-3009
EVMWalletProvider.sign_typed_data/TransferWithAuthorizationagainst U-token on BSC 56/97. EIP-2612ReceiveWithAuthorizationand Permit2Permit/PermitSingleare denylisted unconditionally (they grant unbounded allowances — a malicious 402 server could drain the wallet). Never try to bypass this in agent-reachable code;PermitBatchandSigningPolicy.permissive()are tests-only._DANGEROUS_sign_typed_data_no_policy() - Never hand tool functions a raw . Give them a scoped
WalletProviderand always passX402Signer(wallet, max_value_per_call={token: ...}, session_budget={token: ...})from config/on-chain registry — never from the 402 challenge body.expected_to - Custom tokens/types: — the Permit denylist still wins.
SigningPolicy.strict_default().extend(domain_allowlist={(chain_id, contract)}, primary_type_allowlist={"MyType"}) - is non-pausable and non-hookable: funds are always recoverable past
claimRefund.expiredAt - Throwaway/demo keys: use so one-off keys never touch disk, and never reuse demo keys in production. Never paste production private keys into chat/logs — prefer the keystore +
EVMWalletProvider(persist=False)flow.WALLET_PASSWORD
Full rationale, decision tree, and examples: (Security section) and .
references/sdk-readme.mdexamples/security/e2e.py- EIP-712签名默认受策略限制。仅接受BSC 56/97链上U代币的EIP-3009
EVMWalletProvider.sign_typed_data/TransferWithAuthorization签名。EIP-2612ReceiveWithAuthorization和Permit2Permit/PermitSingle被无条件列入黑名单(它们授予无限制额度——恶意402服务器可能掏空钱包)。切勿在Agent可访问的代码中尝试绕过此限制;PermitBatch和SigningPolicy.permissive()仅用于测试。_DANGEROUS_sign_typed_data_no_policy() - 切勿向工具函数传递原始。应提供限定范围的
WalletProvider,且始终从配置/链上注册表传递X402Signer(wallet, max_value_per_call={token: ...}, session_budget={token: ...})——绝不要从402挑战体中获取。expected_to - 自定义代币/类型:——Permit黑名单仍优先生效。
SigningPolicy.strict_default().extend(domain_allowlist={(chain_id, contract)}, primary_type_allowlist={"MyType"}) - 不可暂停且无钩子:超过
claimRefund后资金始终可追回。expiredAt - 一次性/演示密钥:使用,使一次性密钥永不写入磁盘,且切勿在生产环境中复用演示密钥。切勿将生产环境私钥粘贴到聊天/日志中——优先使用密钥库+
EVMWalletProvider(persist=False)流程。WALLET_PASSWORD
完整原理、决策树及示例:(安全章节)和。
references/sdk-readme.mdexamples/security/e2e.pyWallet backends
钱包后端
- (default) — Keystore V3 (MetaMask/Geth compatible), persistent at
EVMWalletProvideror in-memory with~/.bnbagent/wallets/.persist=False - (Trust Wallet Agent Kit) — self-custody, self-broadcasting; no raw-tx or generic EIP-712 signing; BSC only; x402 via delegated payer
TWAKProvider. Readmake_x402_payer()before using — unsupported calls raisereferences/twak.md. Swap:UnsupportedWalletOperationorTWAKProvider(chain="bsc").WALLET_KIND=twak - Custom (HSM, MPC, KMS): subclass . Details:
WalletProvider.references/wallets.md
- (默认)——Keystore V3(兼容MetaMask/Geth),持久化存储在
EVMWalletProvider,或通过~/.bnbagent/wallets/实现内存存储。persist=False - (Trust Wallet Agent Kit)——自托管、自广播;不支持原始交易或通用EIP-712签名;仅支持BSC链;通过委托支付方
TWAKProvider实现x402。使用前请阅读make_x402_payer()——不支持的调用会抛出references/twak.md。切换方式:UnsupportedWalletOperation或设置TWAKProvider(chain="bsc")。WALLET_KIND=twak - 自定义后端(HSM、MPC、KMS):继承类。详情:
WalletProvider。references/wallets.md
AA / self-broadcast wallets (Privy, ZeroDev, etc.) — known integration tax
AA / 自广播钱包(Privy、ZeroDev等)——已知集成限制
Account-abstraction wallets that submit Intents/UserOperations instead of raw signed transactions are not first-class in the SDK yet (field-tested on BSC mainnet with a Privy AA client, ). What to expect and the workarounds that worked:
bnbagent==0.4.0- ERC-20 fails:
approvegoes throughapprove_payment_token→ raw_send_tx, which AA wallets don't implement (sign_transaction). Workaround: do thesign.transaction: wallet does not implement raw-transaction signingon the payment token manually through your AA stack, then callapprove(commerce, amount)withfund.fund_bundles_approval=True/create_job/set_budgetthemselves work through a custom Intent executor (subclass the executor /fund).WalletProvider - comes back
jobIdafterNone: AA wallets return acreate_job, not a tx hash, anduser_operation_hashonly parsescreate_jobfrom receipt logs. Workaround: wait for inclusion, then scanjobIdbackwards (or index recent jobs byjobCounter+client+provider) to find your job.description - For a documented self-broadcasting wallet, use (
TWAKProvider); Privy-style adapters are currently build-your-own.references/twak.md
提交Intents/UserOperations而非原始签名交易的账户抽象钱包目前并非SDK一等公民(已在BSC主网使用Privy AA客户端、进行实地测试)。预期问题及可行解决方案:
bnbagent==0.4.0- ERC-20 失败:
approve通过approve_payment_token调用原始_send_tx,而AA钱包未实现该方法(报错sign_transaction)。解决方案:通过你的AA栈手动对支付代币执行sign.transaction: wallet does not implement raw-transaction signing,然后调用approve(commerce, amount)并设置fund。fund_bundles_approval=True/create_job/set_budget本身可通过自定义Intent执行器(继承执行器/fund)实现。WalletProvider - 后
create_job返回jobId:AA钱包返回None而非交易哈希,而user_operation_hash仅从收据日志解析create_job。解决方案:等待交易上链,然后反向扫描jobId(或按jobCounter+client+provider索引近期任务)找到你的任务。description - 如需文档化的自广播钱包,请使用(
TWAKProvider);Privy风格的适配器目前需自行构建。references/twak.md
Troubleshooting
故障排除
| Error | Cause → Fix |
|---|---|
| New wallet auto-generated, or set |
| Set |
| Job assigned to a different provider — check |
| Job already submitted/settled. |
| Past |
| Client must fund ≥ |
| Dispute window not elapsed and no dispute — wait, then retry. On mainnet the window is 7 days. |
| Caller not whitelisted or no dispute — use |
Revert selector | Job already bound to a policy — re-registering reverts by design. Treat as success if |
| AA/self-broadcast wallet hit the raw-tx |
| AA wallet returned a user-op hash, no receipt to parse — scan |
Allowance stays 0 after | The bundled |
| 错误 | 原因 → 修复方案 |
|---|---|
| 自动生成了新钱包,或设置 |
| 设置 |
| 任务分配给了其他服务提供者——检查 |
| 任务已提交/结算。 |
| 已超过 |
| 客户必须资助≥ |
| 争议窗口期未结束且无争议——等待后重试。主网窗口期为7天。 |
| 调用者不在白名单中或无争议——使用 |
| 任务已绑定策略——重新注册会按设计回滚。若 |
| AA/自广播钱包触发了原始交易 |
| AA钱包返回用户操作哈希,无收据可解析——反向扫描 |
| 绑定的 |
Files in this skill
本技能包含的文件
- — full upstream SDK README (deep detail on everything above)
references/sdk-readme.md - — code map, layering, invariants
references/architecture.md - — TWAK wallet support matrix and boundaries
references/twak.md - — wallet provider deep dive
references/wallets.md - — annotated env var reference
references/env.example - — copy-and-own scripts:
examples/(5 canonical job flows),client/,a2a-agent/,agent-server/,voter/,twak/,x402/,security/auto_settle.py
- — 完整的上游SDK README(包含上述所有内容的详细说明)
references/sdk-readme.md - — 代码映射、分层结构、不变量
references/architecture.md - — TWAK钱包支持矩阵及边界
references/twak.md - — 钱包提供者深度解析
references/wallets.md - — 带注释的环境变量参考
references/env.example - — 可复制使用的脚本:
examples/(5种标准任务流程)、client/、a2a-agent/、agent-server/、voter/、twak/、x402/、security/auto_settle.py