@bnbagent/studio-cli 0.0.6-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DISCLAIMER.md +48 -0
- package/LICENSE +201 -0
- package/dist/_agentcoreName-DZDWEYD3.js +7 -0
- package/dist/_twak-5XQMOFUC.js +25 -0
- package/dist/bag.js +19358 -0
- package/dist/chunk-7RAKL4AS.js +172 -0
- package/dist/chunk-M3ODFCA7.js +1053 -0
- package/dist/chunk-U7IDQ3K5.js +14 -0
- package/dist/deployCli-N6TPN6XA.js +40 -0
- package/package.json +64 -0
- package/recipes/agent/code/{{PKG}}/signing.ts.tmpl +287 -0
- package/recipes/agent/recipe.toml +35 -0
- package/recipes/providers/pieverse-llm/recipe.toml +16 -0
- package/recipes/providers/pieverse-llm/skills/funding-pieverse-llm.md +203 -0
- package/recipes/runtimes/agentcore/code/{{PKG}}/.dockerignore.tmpl +8 -0
- package/recipes/runtimes/agentcore/code/{{PKG}}/Dockerfile.tmpl +50 -0
- package/recipes/runtimes/agentcore/code/{{PKG}}/agentCard.ts.tmpl +135 -0
- package/recipes/runtimes/agentcore/code/{{PKG}}/dualMain.ts.tmpl +402 -0
- package/recipes/runtimes/agentcore/code/{{PKG}}/executor.ts.tmpl +147 -0
- package/recipes/runtimes/agentcore/code/{{PKG}}/main.ts.tmpl +344 -0
- package/recipes/runtimes/agentcore/code/{{PKG}}/mcpMain.ts.tmpl +677 -0
- package/recipes/runtimes/agentcore/code/{{PKG}}/model.ts.tmpl +117 -0
- package/recipes/runtimes/agentcore/code/{{PKG}}/sellerCore.ts.tmpl +503 -0
- package/recipes/runtimes/agentcore/code/{{PKG}}/tools.ts.tmpl +157 -0
- package/recipes/runtimes/agentcore/recipe.toml +97 -0
- package/recipes/runtimes/azure-foundry/code/{{PKG}}/.dockerignore.tmpl +8 -0
- package/recipes/runtimes/azure-foundry/code/{{PKG}}/Dockerfile.tmpl +47 -0
- package/recipes/runtimes/azure-foundry/code/{{PKG}}/agentCard.ts.tmpl +131 -0
- package/recipes/runtimes/azure-foundry/code/{{PKG}}/executor.ts.tmpl +504 -0
- package/recipes/runtimes/azure-foundry/code/{{PKG}}/foundryMain.ts.tmpl +300 -0
- package/recipes/runtimes/azure-foundry/code/{{PKG}}/main.ts.tmpl +196 -0
- package/recipes/runtimes/azure-foundry/code/{{PKG}}/mcpMain.ts.tmpl +562 -0
- package/recipes/runtimes/azure-foundry/code/{{PKG}}/model.ts.tmpl +117 -0
- package/recipes/runtimes/azure-foundry/code/{{PKG}}/tools.ts.tmpl +157 -0
- package/recipes/runtimes/azure-foundry/recipe.toml +88 -0
- package/recipes/tools-chain/code/{{PKG}}/chainTools.ts.tmpl +166 -0
- package/recipes/tools-chain/recipe.toml +11 -0
- package/recipes/wallet/recipe.toml +20 -0
- package/recipes/x402-buyer/code/{{PKG}}/x402Buyer.ts.tmpl +175 -0
- package/recipes/x402-buyer/recipe.toml +15 -0
- package/skills/bnbagent-studio.md +107 -0
- package/skills/references/bnbagent-studio-adding-to-project.md +241 -0
- package/skills/references/bnbagent-studio-buying-from-bazaar.md +169 -0
- package/skills/references/bnbagent-studio-buying-via-8183.md +222 -0
- package/skills/references/bnbagent-studio-extending-signing.md +227 -0
- package/skills/references/bnbagent-studio-operating.md +211 -0
- package/skills/references/bnbagent-studio-scaffolding-agent.md +536 -0
- package/skills/references/bnbagent-studio-selling-via-8183.md +271 -0
- package/skills/references/bnbagent-studio-selling-via-b402.md +194 -0
- package/skills/references/bnbagent-studio-use-aws-agentcore.md +208 -0
- package/skills/references/bnbagent-studio-use-azure-foundry.md +164 -0
- package/skills/references/bnbagent-studio-use-bnb-trial.md +92 -0
- package/skills/references/bnbagent-studio-using-altana-wallet.md +68 -0
- package/skills/references/bnbagent-studio-using-twak-wallet.md +260 -0
- package/skills/references/bnbagent-studio-wiring-llm-tools.md +338 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bnbagent-studio-buying-via-8183
|
|
3
|
+
description: When the user is acting as ERC-8183 buyer — finding a provider, getting a quote, buying a service, fetching the deliverable, and deciding to approve / dispute / reject the work. Owns the buyer-side decision tree for the entire job lifecycle including settle-window timing (24h dispute window), dispute governance flow, and `Submission deadline has passed` recovery.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
> **Reference file** of the `bnbagent-studio` router skill — installed at `bnbagent-studio/references/` and loaded on demand (not a standalone skill). Route here via the router's decision tree.
|
|
7
|
+
|
|
8
|
+
# bnbagent-studio-buying-via-8183
|
|
9
|
+
|
|
10
|
+
> **v1 scope note:** v1 is **seller-only** — buyer flows are **NOT**
|
|
11
|
+
> the main v1 payment path. The x402 buyer kernel survives only as the Agent's
|
|
12
|
+
> *automatic* LLM top-up (`@bnbagent/studio-runtime/x402`, budget-gated, not an LLM tool),
|
|
13
|
+
> and the erc8183 `buyWorkflow` survives as an **underlying capability** still
|
|
14
|
+
> reachable via the `bag erc8183 buy/status/fetch/settle` CLI. Full buyer-side
|
|
15
|
+
> *product* flows (a buyer agent, buyer-side negotiation wrapping) are deferred
|
|
16
|
+
> to v2. The CLI procedure below still works for manual / testing use.
|
|
17
|
+
|
|
18
|
+
Procedure for **buyer-side flow**: have your agent (or you directly via CLI)
|
|
19
|
+
purchase a service from another ERC-8183 seller, verify the deliverable, and
|
|
20
|
+
close out the job with the right `settle` action.
|
|
21
|
+
|
|
22
|
+
Audience: Claude Code in a v0.0.x workspace with a funded wallet (tBNB + U).
|
|
23
|
+
The buying CLI (`bag erc8183 buy/status/fetch/settle`) targets the **Agent
|
|
24
|
+
sub-project's** wallet — these commands resolve to `<workspace>/app/agent/`
|
|
25
|
+
automatically when run from the workspace root.
|
|
26
|
+
|
|
27
|
+
> **Protocol facts** (independent of the local filesystem layout): 24h dispute
|
|
28
|
+
> window, `0x17be5b7b` revert, `expired_at` arithmetic.
|
|
29
|
+
|
|
30
|
+
**Different from**:
|
|
31
|
+
- `bnbagent-studio-operating.md` (same directory) — generic ops (dev / doctor / balance / RPC); jumps here for buyer-specific decisions
|
|
32
|
+
- `bnbagent-studio-adding-to-project` — covers wiring a buyer tool set into an existing project (the static setup, not the runtime decisions)
|
|
33
|
+
- `bnbagent-studio-selling-via-8183.md` (same directory) — the mirror playbook for the seller side (`on_job`, dispute defense)
|
|
34
|
+
|
|
35
|
+
This skill owns: **buy → fetch → approve/dispute/reject loop**, whether
|
|
36
|
+
driven via CLI or the agent's LLM calling `erc8183_buyer_set` tools.
|
|
37
|
+
|
|
38
|
+
## Buyer settle decision tree (load this skill when the user hits any of these)
|
|
39
|
+
|
|
40
|
+
`SUBMITTED` job → buyer has three options, **time-gated by the on-chain dispute window**:
|
|
41
|
+
|
|
42
|
+
| Action | Allowed | What happens |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| `bag erc8183 settle <id> --action approve` | **After 24h dispute_window has passed** (chain enforces; reverts with `0x17be5b7b` if early) | Job → `COMPLETED`; seller receives U |
|
|
45
|
+
| `bag erc8183 settle <id> --action dispute` | **Within dispute_window** | Opens governance flow; quorum vote decides; refund possible |
|
|
46
|
+
| `bag erc8183 settle <id> --action reject` | **Only if you're a quorum voter, not the buyer** | Job → `REJECTED` via governance |
|
|
47
|
+
|
|
48
|
+
If the buyer agent (or LLM) is about to call `settle --action approve` and it's
|
|
49
|
+
been <24h since SUBMITTED, **wait** or use `dispute`. Don't try to retry
|
|
50
|
+
through the revert — read the error and pick the right action.
|
|
51
|
+
|
|
52
|
+
Common error: `Submission deadline has passed` → buyer set `expiredAt` too
|
|
53
|
+
short (< dispute_window). Fix: re-buy with `--deadline-min ≥ 1` (the buy
|
|
54
|
+
flow now auto-adds dispute_window).
|
|
55
|
+
|
|
56
|
+
## Preconditions
|
|
57
|
+
|
|
58
|
+
- `bag doctor` is clean (or only warns on LLM key)
|
|
59
|
+
- Wallet has ≥ 0.05 tBNB (gas) and ≥ 0.2 U (token + slack). On BSC testnet the
|
|
60
|
+
ERC-8183 kernel writes (`createJob` / `fund` deposit / `settle` …) are
|
|
61
|
+
gas-sponsored via the SDK's MegaFuel paymaster, so you spend far less tBNB than
|
|
62
|
+
that — but **not zero**: `fund` sends an ERC-20 `approve` (a token call, not
|
|
63
|
+
sponsored) when the token allowance is too low — typically just the first fund,
|
|
64
|
+
since studio approves a floored cap that later jobs reuse. Keep a little tBNB for
|
|
65
|
+
it. (Mainnet is never sponsored.)
|
|
66
|
+
- You know the **provider's wallet address** (the seller agent's address)
|
|
67
|
+
- The seller is **reachable** (its A2A agent is deployed somewhere); discoverable
|
|
68
|
+
via the provider's `bag erc8004 resolve <agent_id>` endpoint URI
|
|
69
|
+
|
|
70
|
+
## Stage 1 — Pre-flight checks
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# 1. Confirm wallet + balances
|
|
74
|
+
bag wallet show
|
|
75
|
+
bag doctor # tBNB + U checks should be PASS
|
|
76
|
+
|
|
77
|
+
# 2. Confirm the provider's 8004 record (optional but recommended)
|
|
78
|
+
bag erc8004 resolve <provider_agent_id>
|
|
79
|
+
# → returns the agent_uri; decode it (base64 data: URI) to verify the endpoint URL
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
If the provider's endpoint URL points somewhere reachable (e.g. an `https://`
|
|
83
|
+
AgentCore runtime URL), proceed. If it's `http://localhost:...`, that means you
|
|
84
|
+
must be on the same host.
|
|
85
|
+
|
|
86
|
+
## Stage 2 — (Optional) Negotiate price
|
|
87
|
+
|
|
88
|
+
**v0.0.x**: `@bnbagent/studio-runtime` *does* wrap the buyer-side negotiation
|
|
89
|
+
handshake (`@bnbagent/studio-runtime/erc8183` `negotiateWithSeller`, wired into
|
|
90
|
+
the buy workflow). It fires automatically when you buy by `--agent-id` (resolves
|
|
91
|
+
the seller's endpoint from its ERC-8004 record, then POSTs `/negotiate`); pass
|
|
92
|
+
`--no-negotiate` to skip it. When you buy by `--provider <addr>` you supply the
|
|
93
|
+
budget directly and assume the price was agreed off-chain.
|
|
94
|
+
|
|
95
|
+
If you want to talk to the seller manually, the seller now exposes its
|
|
96
|
+
`negotiate` skill over **A2A** (the seller's ERC-8004 endpoint URI is an A2A base
|
|
97
|
+
URL): send an A2A `message/send` JSON-RPC call carrying a `DataPart`
|
|
98
|
+
`{"skill": "negotiate", "task_description": "...", "terms": {...}}` (+ the seller's
|
|
99
|
+
OAuth2 Bearer when deployed). The reply data part is the signed `NegotiationResult`
|
|
100
|
+
quote. But you don't need this for v0.0.x — go straight to buy.
|
|
101
|
+
|
|
102
|
+
## Stage 3 — Buy
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
bag erc8183 buy --provider <provider_addr> "<task description>" \
|
|
106
|
+
--budget-u <amount> \ # capped by policy.budget_cap_u
|
|
107
|
+
--deadline-min <minutes> \ # default 30; this is the seller's submission window
|
|
108
|
+
--network bsc-testnet
|
|
109
|
+
# provider is a REQUIRED flag (--provider <addr> OR --agent-id <id>), not a positional;
|
|
110
|
+
# `--agent-id` resolves the endpoint + negotiates first.
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
> **Task can be passed two ways** (both accepted): as a positional argument
|
|
114
|
+
> `bag erc8183 buy --provider <addr> "<task>"` OR via the flag
|
|
115
|
+
> `bag erc8183 buy --provider <addr> --task "<task>"`. Pass it once — supplying
|
|
116
|
+
> both at the same time is an error.
|
|
117
|
+
|
|
118
|
+
The 4 on-chain steps run sequentially:
|
|
119
|
+
|
|
120
|
+
1. `createJob(provider, expiredAt, description)` → returns `job_id`
|
|
121
|
+
2. `registerJob(jobId)`
|
|
122
|
+
3. `setBudget(jobId, rawBudget)`
|
|
123
|
+
4. `fund(jobId, rawBudget, approveFloor=rawBudget)` — auto-approves U
|
|
124
|
+
|
|
125
|
+
Output prints 4 tx hashes + `job_id`. Note the `job_id` for later.
|
|
126
|
+
|
|
127
|
+
**Gotcha**: `expired_at = now + deadline_minutes*60 + dispute_window` (24h). This
|
|
128
|
+
is intentional — the chain enforces that submission must happen before
|
|
129
|
+
`expired_at - dispute_window`. If you set `deadline_minutes=30`, the seller has
|
|
130
|
+
30 min to submit (then a 24h dispute window starts).
|
|
131
|
+
|
|
132
|
+
## Stage 4 — Wait for SUBMITTED
|
|
133
|
+
|
|
134
|
+
The single seller runtime has **no standalone poller** — after funding, send a
|
|
135
|
+
`notify_funded` A2A message to the seller ("I funded job X, please deliver"). The
|
|
136
|
+
seller **acks `accepted` immediately and delivers in the background**, so you do
|
|
137
|
+
**not** get the deliverable in the A2A reply — you poll the chain for it. The
|
|
138
|
+
seller also sweeps other funded jobs on each `notify_funded` (in the background,
|
|
139
|
+
deduped). Check status:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
bag erc8183 status <job_id>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Statuses:
|
|
146
|
+
|
|
147
|
+
- `OPEN` → not yet funded (shouldn't see this after Step 3)
|
|
148
|
+
- `FUNDED` → waiting for seller to pick up + submit
|
|
149
|
+
- `SUBMITTED` → ready to fetch + settle
|
|
150
|
+
- `EXPIRED` → seller missed the deadline; use `bag erc8183 settle --action ...` or
|
|
151
|
+
the SDK's `mark_expired` / `claim_refund`
|
|
152
|
+
|
|
153
|
+
Delivery is no longer instant: because the seller works in the background, the
|
|
154
|
+
wait is however long its work takes (seconds to minutes). Poll until `SUBMITTED`,
|
|
155
|
+
then read `deliverable_url` (Stage 5). If it stays `FUNDED`, either no one sent
|
|
156
|
+
`notify_funded` (and the sweep hasn't run — the seller may be scaled to zero), or
|
|
157
|
+
the seller's background work failed or hasn't finished yet — re-send
|
|
158
|
+
`notify_funded` to nudge it while the runtime is warm. (Also possible: a config
|
|
159
|
+
mismatch, most often `expired_at` too soon — but the workflow auto-fixes this now.)
|
|
160
|
+
|
|
161
|
+
## Stage 5 — Fetch the deliverable
|
|
162
|
+
|
|
163
|
+
The single seller runtime serves **no** job-query endpoint — the deliverable is read
|
|
164
|
+
back from the on-chain submission (the `submit` tx carries the `deliverable_url`,
|
|
165
|
+
typically `ipfs://...`) and the IPFS object. Get the URL via CLI:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
bag erc8183 fetch <job_id>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Prints the `deliverable_url`. Fetch it yourself (e.g. via an IPFS gateway) to read
|
|
172
|
+
the `DeliverableManifest`: `{"chain_id", "contracts", "job_id", "response": {"content": ..., "content_type": ...}, "metadata": {...}}`.
|
|
173
|
+
|
|
174
|
+
## Stage 6 — Settle
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
# Happy path: accept the deliverable. NOTE: must wait 24h dispute_window first.
|
|
178
|
+
bag erc8183 settle <job_id> --action approve
|
|
179
|
+
|
|
180
|
+
# Bad deliverable: dispute (within dispute_window, no wait needed)
|
|
181
|
+
bag erc8183 settle <job_id> --action dispute
|
|
182
|
+
|
|
183
|
+
# (rare) you're a quorum voter and want to reject:
|
|
184
|
+
bag erc8183 settle <job_id> --action reject
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Returns a tx hash. Verify on BscScan.
|
|
188
|
+
|
|
189
|
+
**On `--action approve` revert with `0x17be5b7b`**: chain refuses because
|
|
190
|
+
`submitted_at + dispute_window > now`. Either wait the remaining time or
|
|
191
|
+
use `--action dispute` for immediate effect.
|
|
192
|
+
|
|
193
|
+
## Stage 7 — Verify on-chain settlement
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
bag erc8183 status <job_id>
|
|
197
|
+
# Expect: status COMPLETED (after approve) or unchanged SUBMITTED (after dispute, until voters resolve)
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Check seller's U balance increased (minus platform fee — see `CommerceClient.platform_fee_bp()`).
|
|
201
|
+
|
|
202
|
+
## End-to-end smoke (one-shot, for testing your setup)
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
# Buyer side (this assumes the seller's A2A agent is already deployed somewhere)
|
|
206
|
+
PROVIDER=<seller_address>
|
|
207
|
+
JOB=$(bag erc8183 buy --provider $PROVIDER "test task" --budget-u 0.5 | awk -F': *' '/job_id:/{print $2; exit}')
|
|
208
|
+
# send a `notify_funded` A2A message to the seller for that JOB (buyer-push),
|
|
209
|
+
# then poll the chain (the seller acks at once and delivers in the background):
|
|
210
|
+
sleep 60
|
|
211
|
+
bag erc8183 status $JOB
|
|
212
|
+
bag erc8183 settle $JOB --action dispute
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
This is the exact end-to-end flow used to validate real-chain buying. See the
|
|
216
|
+
references below for the canonical picture.
|
|
217
|
+
|
|
218
|
+
## Reference
|
|
219
|
+
|
|
220
|
+
- `docs/design/erc8183-reference.md` (SDK surface map / negotiation envelope)
|
|
221
|
+
- `docs/design/single-seller-agent.md` + `docs/design/erc8183-buyer-push.md` (the v1 single-agent model + buyer-push flow)
|
|
222
|
+
- `docs/guides/verification.md` (manual on-chain verification)
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bnbagent-studio-extending-signing
|
|
3
|
+
description: When the user wants the agent's wallet to sign EIP-712 typed data for anything beyond BSC U-token transfers — e.g. integrate a new x402 service, custom commerce contract, or any TypedData primary type beyond TransferWithAuthorization/ReceiveWithAuthorization. Also covers diagnosing `PolicyViolation` / `X402PolicyError` at runtime and how to safely extend `[wallet.signing]` extra_domains / extra_primary_types in studio.toml.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
> **Reference file** of the `bnbagent-studio` router skill — installed at `bnbagent-studio/references/` and loaded on demand (not a standalone skill). Route here via the router's decision tree.
|
|
7
|
+
|
|
8
|
+
# bnbagent-studio-extending-signing
|
|
9
|
+
|
|
10
|
+
Procedure for **extending the EIP-712 signing allowlist** in a bnbagent-studio project.
|
|
11
|
+
Audience: Claude Code helping a user who hit `PolicyViolation` or wants to integrate a non-default x402 service / custom contract.
|
|
12
|
+
|
|
13
|
+
> **v0.0.1 path note**: signing is an **Agent-only** concern. `signing.ts` lives
|
|
14
|
+
> at `<workspace>/app/agent/src/signing.ts` and is called by the
|
|
15
|
+
> `SellerAgentExecutor` skills (`negotiate` / `notify_funded`) — it is **never** an
|
|
16
|
+
> LLM-callable tool. The `[wallet.signing]` config lives in
|
|
17
|
+
> `<workspace>/app/agent/studio.toml`. The workspace is a thin root plus the one
|
|
18
|
+
> `app/agent/` sub-project; every command and edit below targets `app/agent/`.
|
|
19
|
+
|
|
20
|
+
**Different from**:
|
|
21
|
+
- `-operating` — general ops & doctor / balance / job status
|
|
22
|
+
- `funding-pieverse-llm` — Pieverse LLM credit lifecycle (the money)
|
|
23
|
+
- `-adding-to-project` — adds capabilities (`bnbagent-sdk` modules)
|
|
24
|
+
|
|
25
|
+
This skill is specifically the **signing-permission** axis. Funding is "do I have the money"; signing policy is "is the wallet allowed to sign this".
|
|
26
|
+
|
|
27
|
+
## Mental model (defense in depth)
|
|
28
|
+
|
|
29
|
+
Every EIP-712 signature goes through SDK `SigningPolicy.strictDefault()`. By default the wallet only signs:
|
|
30
|
+
|
|
31
|
+
| Allowed | Domain | Primary types |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| U-token mainnet | chain `56`, `0xcE24439F2D9C6a2289F741120FE202248B666666` | `TransferWithAuthorization`, `ReceiveWithAuthorization` |
|
|
34
|
+
| U-token testnet | chain `97`, `0xc70B8741B8B07A6d61E54fd4B20f22Fa648E5565` | (same) |
|
|
35
|
+
|
|
36
|
+
Everything else (`Permit`, `PermitSingle`, `PermitBatch`, foreign contracts, foreign chains, custom primary types) is **refused with `PolicyViolation`** at sign-time.
|
|
37
|
+
|
|
38
|
+
Two layers wrap this:
|
|
39
|
+
|
|
40
|
+
| Layer | What it gates | Where configured | Can agent change at runtime? |
|
|
41
|
+
|---|---|---|---|
|
|
42
|
+
| L2 — HTTP host | which servers the x402 buyer is allowed to fetch from | `[payments.x402].allowed_hosts` in `app/agent/studio.toml` | ⚠️ Only by editing toml + restart |
|
|
43
|
+
| L3 — SigningPolicy | which `(chain_id, contract)` + primary type the wallet will sign | `[wallet.signing]` in `app/agent/studio.toml` (additive over SDK strictDefault) | ⚠️ Only by editing toml + restart |
|
|
44
|
+
|
|
45
|
+
**Both layers must permit a request** for it to succeed. Adding only one half won't work — see Section A.
|
|
46
|
+
|
|
47
|
+
EIP-191 SIWE (the `pieverse_usage` MCP tool / `bag llm activate`) uses a **separate** hardcoded allowlist `{"llm.pieverse.io"}` and is not configurable.
|
|
48
|
+
|
|
49
|
+
## Quick triage decision tree
|
|
50
|
+
|
|
51
|
+
| User said... | Section |
|
|
52
|
+
|---|---|
|
|
53
|
+
| "buy X service via x402" (X is not Pieverse) | A — new x402 service |
|
|
54
|
+
| "sign for custom commerce contract / order / quote" | B — custom primary type |
|
|
55
|
+
| `PolicyViolation` / `X402PolicyError` at runtime | C — diagnosing the rejection |
|
|
56
|
+
| "agent needs to approve unlimited USDC" / Permit / Permit2 | D — refuse the request |
|
|
57
|
+
| "expand the 600s validity window" | E — validity overrides |
|
|
58
|
+
|
|
59
|
+
## A. Integrate a new x402 service
|
|
60
|
+
|
|
61
|
+
The user wants the agent to pay e.g. `api.example.com` via x402.
|
|
62
|
+
|
|
63
|
+
**Pre-flight checks (must be true in v0.0.1 — refuse and explain if not):**
|
|
64
|
+
|
|
65
|
+
1. The service accepts payment on **BSC chain 56 or 97**. v0.0.1 wallets are BSC-only; a service on Base/Ethereum/Polygon won't work until v0.2 multi-chain support lands.
|
|
66
|
+
2. The service uses **EIP-3009 `TransferWithAuthorization`** (or `ReceiveWithAuthorization`). If it uses Permit2 or a custom primary type → goes to Section B.
|
|
67
|
+
3. The token contract address on BSC is known and the user can confirm it. Don't guess from a token symbol — look up the deployed address.
|
|
68
|
+
|
|
69
|
+
If any of (1)–(3) fail, **stop and tell the user**. v0.0.1 cannot integrate cross-chain services or non-EIP-3009 payment rails. Don't try to work around it; the SigningPolicy will refuse and the failure will be confusing.
|
|
70
|
+
|
|
71
|
+
**Steps when (1)–(3) all pass:**
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# 1. Edit app/agent/studio.toml — both gates. `bag config` resolves the app/agent/
|
|
75
|
+
# sub-project automatically from the workspace root
|
|
76
|
+
# (there is NO --side flag); pass --project-root app/agent to be explicit.
|
|
77
|
+
bag config set payments.x402.allowed_hosts '["llm.pieverse.io", "api.example.com"]'
|
|
78
|
+
|
|
79
|
+
# 2. Add the EIP-712 domain to wallet.signing (additive)
|
|
80
|
+
# bag config does not yet handle nested array-of-arrays elegantly; edit the
|
|
81
|
+
# toml directly with this snippet (targets app/agent/studio.toml only):
|
|
82
|
+
cat >> app/agent/studio.toml <<'EOF'
|
|
83
|
+
|
|
84
|
+
[wallet.signing]
|
|
85
|
+
extra_domains = [
|
|
86
|
+
[56, "0xAbcdef0123456789abcdef0123456789abcdef01"], # api.example.com token on mainnet
|
|
87
|
+
[97, "0x1234567890abcdef1234567890abcdef12345678"], # same on testnet
|
|
88
|
+
]
|
|
89
|
+
EOF
|
|
90
|
+
|
|
91
|
+
# 3. Verify the policy reflects both allowlists
|
|
92
|
+
bag wallet policy show
|
|
93
|
+
# expect 3 entries in domain_allowlist: U mainnet, U testnet, your new contract
|
|
94
|
+
|
|
95
|
+
# 4. Restart the agent process for the new policy to take effect.
|
|
96
|
+
# SigningPolicy is read at wallet construction; running `bag dev` again
|
|
97
|
+
# is enough.
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Hard rules**:
|
|
101
|
+
- Do not add a contract to `extra_domains` without verifying its address on a block explorer. The SigningPolicy treats `(chain_id, contract)` as a unit; the wrong address = signing into a phishing contract.
|
|
102
|
+
- Do not silently widen `daily_cap_usd` or `max_per_request_usd` to make the new service "fit". The caps are budget guardrails; surface the proposed values to the user before editing.
|
|
103
|
+
|
|
104
|
+
## B. Custom typed-data primary type
|
|
105
|
+
|
|
106
|
+
If the new service or contract requires the wallet to sign a non-standard primary type (e.g. `"MyOrder"`, `"BondQuote"`, `"NegotiateAgreement"`), edit `<workspace>/app/agent/studio.toml`:
|
|
107
|
+
|
|
108
|
+
```toml
|
|
109
|
+
# app/agent/studio.toml
|
|
110
|
+
[wallet.signing]
|
|
111
|
+
extra_domains = [
|
|
112
|
+
[56, "0xContractAddress..."],
|
|
113
|
+
]
|
|
114
|
+
extra_primary_types = ["MyOrder", "BondQuote"]
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Both must be added** — adding a primary type without the matching domain is useless (the contract still gets rejected) and adding the domain without the type still rejects the signature (primary_type allowlist).
|
|
118
|
+
|
|
119
|
+
**Hard rules**:
|
|
120
|
+
- The SDK denylist (`Permit`, `PermitSingle`, `PermitBatch`) **always wins** over `extra_primary_types`. Listing them does not enable them.
|
|
121
|
+
- Custom primary types bypass studio's known semantic checks. Be extra careful that the typed data structure matches what the contract expects; an attacker controlling the contract or the LLM input can construct unfavorable messages.
|
|
122
|
+
|
|
123
|
+
## C. Diagnosing PolicyViolation / X402PolicyError at runtime
|
|
124
|
+
|
|
125
|
+
User reports an error from `bag dev` / agent runtime. Map the message → fix:
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
PolicyViolation: unknown (chain_id, verifyingContract): (56, 0xAbc...)
|
|
129
|
+
→ L3 SigningPolicy rejection
|
|
130
|
+
→ Section A or B: add to [wallet.signing].extra_domains, then restart
|
|
131
|
+
|
|
132
|
+
PolicyViolation: primary type 'Permit' is denylisted
|
|
133
|
+
→ Section D: refuse — do not work around
|
|
134
|
+
|
|
135
|
+
PolicyViolation: primary type 'MyOrder' not in allowlist
|
|
136
|
+
→ Section B: add to extra_primary_types
|
|
137
|
+
|
|
138
|
+
PolicyViolation: validity window 7200s exceeds max 600
|
|
139
|
+
→ Section E: max_validity_window_seconds in [wallet.signing]
|
|
140
|
+
|
|
141
|
+
X402HostNotAllowedError: x402 buyer refusing 'api.example.com' — not in allowed_hosts
|
|
142
|
+
→ L2 HTTP gate (exact hosts only — wildcard entries are not supported)
|
|
143
|
+
→ bag config set payments.x402.allowed_hosts '[..., "api.example.com"]'
|
|
144
|
+
→ (L3 may also need updating per Section A)
|
|
145
|
+
|
|
146
|
+
X402BudgetExhaustedError: x402 402 demands $1.50 > max_usd=$1.00
|
|
147
|
+
→ Budget cap; user must explicitly raise via studio.toml.
|
|
148
|
+
→ DON'T silently widen — tell the user.
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Confirm the current state before editing:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
bag wallet policy show # L3 SigningPolicy (reads app/agent/studio.toml)
|
|
155
|
+
bag config get payments.x402 # L2 allowed_hosts + caps (auto-resolves app/agent/)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## D. Refuse: Permit / Permit2 unbounded allowance
|
|
159
|
+
|
|
160
|
+
If the user (or, more dangerously, the LLM) asks the agent to sign `Permit`, `PermitSingle`, or `PermitBatch`:
|
|
161
|
+
|
|
162
|
+
**Stop. Refuse. Explain why.**
|
|
163
|
+
|
|
164
|
+
These primary types grant unbounded ERC-20 spend authority to a third party. The denylist exists exactly to prevent LLMs being talked into signing one. Even if the user insists, the SDK will refuse with `PolicyViolation` and the message is correct — do not bypass via `_DANGEROUS_signTypedDataNoPolicy`.
|
|
165
|
+
|
|
166
|
+
Acceptable alternatives:
|
|
167
|
+
- For paying a known service: use EIP-3009 `TransferWithAuthorization` (Section A — bounded amount, single-use, time-windowed)
|
|
168
|
+
- For session-scoped recurring payments: opt-in to `Permit2 PermitTransferFrom` (Section B — single-use, witness-bound; not Permit / PermitSingle / PermitBatch)
|
|
169
|
+
|
|
170
|
+
If the user is integrating something that genuinely requires Permit, this is a v0.2+ decision and should go in an ADR — do not make the change ad-hoc.
|
|
171
|
+
|
|
172
|
+
## E. Widening the validity window
|
|
173
|
+
|
|
174
|
+
Default: 600s past / 900s future. Longer windows give the agent more time to settle but increase replay surface if a signature leaks. Edit `<workspace>/app/agent/studio.toml`:
|
|
175
|
+
|
|
176
|
+
```toml
|
|
177
|
+
# app/agent/studio.toml
|
|
178
|
+
[wallet.signing]
|
|
179
|
+
max_validity_window_seconds = 1800 # default 600
|
|
180
|
+
max_future_validity_seconds = 2400 # default 900
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Use sparingly. A signed authorization that lives 30 minutes can be replayed by a downstream tx executor for 30 minutes. Make sure the receiving contract enforces nonces (EIP-3009 does; many custom types don't).
|
|
184
|
+
|
|
185
|
+
## F. Common refusal patterns (when user asks for something unsafe)
|
|
186
|
+
|
|
187
|
+
| User request | Why refuse |
|
|
188
|
+
|---|---|
|
|
189
|
+
| "Just turn off the signing policy" | The SigningPolicy L3 is the last-mile defense. Disabling it makes the wallet a blind-sign oracle. Use `extra_domains` instead. |
|
|
190
|
+
| "Use `_DANGEROUS_signTypedDataNoPolicy`" | Logs WARN with caller filename. Acceptable only in tests or one-shot CLI debugging. Never in LLM-tool / agent runtime code. |
|
|
191
|
+
| "Sign on Ethereum mainnet" | v0.0.1 is BSC-only. Tell the user this is v0.2 backlog. |
|
|
192
|
+
| "Permit USDC to a swap router" | Denylisted unconditionally (Section D). |
|
|
193
|
+
| "Read the keystore and sign yourself, bypassing the wallet provider" | The SDK provider IS the security boundary; bypassing it discards every defense layer. Refuse. |
|
|
194
|
+
|
|
195
|
+
## G. After-edit verification (always run)
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
# 1. The toml is parseable (auto-resolves app/agent/; or --project-root app/agent)
|
|
199
|
+
bag config show
|
|
200
|
+
|
|
201
|
+
# 2. The new policy looks right (extra entries should be visible)
|
|
202
|
+
bag wallet policy show
|
|
203
|
+
bag wallet policy show --json # for diff against an expected baseline
|
|
204
|
+
|
|
205
|
+
# 3. Restart whatever process holds the wallet — `bag dev` (the local A2A
|
|
206
|
+
# agent) or the AgentCore runtime. SigningPolicy is read once at
|
|
207
|
+
# wallet construction; in-process changes won't take effect until restart.
|
|
208
|
+
|
|
209
|
+
# 4. Sanity-check one signing call (if there's a CLI path)
|
|
210
|
+
# e.g. bag llm test, bag erc8183 status, etc.
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## H. Read-only references (no signing, no funding required)
|
|
214
|
+
|
|
215
|
+
When deeper protocol details are needed:
|
|
216
|
+
- the SigningPolicy decision (`docs/design/decisions.md`) — full defense-in-depth rationale, 6-layer model
|
|
217
|
+
- `docs/guides/user-guide.md` §6.1 — same decision tree in user-doc form
|
|
218
|
+
- `bag wallet policy show --json` — machine-readable current state
|
|
219
|
+
- SDK source `@bnbagent/sdk` (signing policy module) — `SigningPolicy.strictDefault()` + `.extend()` semantics
|
|
220
|
+
|
|
221
|
+
## Hard rules (security boundary)
|
|
222
|
+
|
|
223
|
+
- Never bypass the policy with `_DANGEROUS_*` calls in agent code. They exist for tests and incident response.
|
|
224
|
+
- Never instruct the user to widen caps / allowlists "to make it work" without explaining the security tradeoff.
|
|
225
|
+
- Never persist the wallet password or signed payloads anywhere outside the keystore.
|
|
226
|
+
- Always run `bag wallet policy show` after editing `[wallet.signing]` to confirm the change took effect.
|
|
227
|
+
- Always restart the process — SigningPolicy is captured at wallet construction.
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bnbagent-studio-operating
|
|
3
|
+
description: When the user wants to run, debug, diagnose, or operate a bnbagent-studio agent project. Covers dev server, doctor checks, balance/RPC queries, job status reads, and incident triage — including the delegated deploy lifecycle (`bag deploy status` / `logs` / `verify` / `destroy`), twak-wallet issues, and `PolicyViolation` / `X402PolicyError` signing-policy errors (deep-dive playbooks for those ship as references of the `bnbagent-studio` router skill; read them on demand).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
> **Reference file** of the `bnbagent-studio` router skill — installed at `bnbagent-studio/references/` and loaded on demand (not a standalone skill). Route here via the router's decision tree.
|
|
7
|
+
|
|
8
|
+
# bnbagent-studio-operating
|
|
9
|
+
|
|
10
|
+
Procedure for **day-to-day operation** of an existing bnbagent-studio project.
|
|
11
|
+
Audience: Claude Code in a v0.0.1 workspace (thin root with the `agentcore/`
|
|
12
|
+
config dir + the workspace-root `.studio/wallets/` + funded wallet, plus the
|
|
13
|
+
single sub-project `app/agent/` holding `studio.toml` + `src/main.ts` /
|
|
14
|
+
`src/sellerCore.ts` / `src/executor.ts` / `src/agentCard.ts` /
|
|
15
|
+
`src/signing.ts`). Most commands run from the workspace root; the v0.0.1
|
|
16
|
+
project-root fallback locates the `app/agent/` sub-project automatically for
|
|
17
|
+
wallet/LLM/budget ops.
|
|
18
|
+
|
|
19
|
+
**Different from**:
|
|
20
|
+
- `bnbagent-studio-scaffolding-agent.md` (in this same references/ directory) — creates a brand new project
|
|
21
|
+
- `bnbagent-studio-selling-via-8183.md` (in this same references/ directory) — seller flow (`runWork` value, rule-based quote pricing, dispute defense)
|
|
22
|
+
- `funding-pieverse-llm` (project-scope skill, Pieverse projects only) — Pieverse credit lifecycle / topup decisions
|
|
23
|
+
|
|
24
|
+
**Deep-dive references** — plain markdown files in this SAME references/
|
|
25
|
+
directory (Claude Code: `~/.claude/skills/bnbagent-studio/references/`; Cursor:
|
|
26
|
+
`bnbagent-studio/references/` beside the `.mdc` rules). READ
|
|
27
|
+
the file when the topic comes up — don't answer from memory:
|
|
28
|
+
- `bnbagent-studio-use-aws-agentcore.md` — the delegated AgentCore lifecycle (`bag deploy --provider aws` / `status` / `logs` / `verify` / `destroy`, `provision-cognito`) + AWS prerequisites
|
|
29
|
+
- `bnbagent-studio-use-bnb-trial.md` — GitHub device login, 48h eligibility, staging verification, and the delegated BNB trial lifecycle
|
|
30
|
+
- `bnbagent-studio-use-azure-foundry.md` — the delegated Azure Foundry lifecycle (`bag deploy --provider azure`; no `az`/`azd` CLI)
|
|
31
|
+
- `bnbagent-studio-using-twak-wallet.md` — `[wallet].kind = "twak"` create / fund / SIWE-bind / container deploy / limitations
|
|
32
|
+
- `bnbagent-studio-extending-signing.md` — `PolicyViolation` / `X402PolicyError` diagnosis + extending the EIP-712 allowlist
|
|
33
|
+
- `bnbagent-studio-adding-to-project.md` — adding the seller runtime to an existing TypeScript project
|
|
34
|
+
- `bnbagent-studio-buying-via-8183.md` — buyer flow (find provider → buy → fetch → settle)
|
|
35
|
+
|
|
36
|
+
This playbook covers **generic ops**: dev / doctor / balances / RPC / incident triage.
|
|
37
|
+
For seller job-lifecycle decisions (settle / submit / dispute defense), read
|
|
38
|
+
`bnbagent-studio-selling-via-8183.md` (same directory); for the buyer side, read the buying reference.
|
|
39
|
+
|
|
40
|
+
## Quick triage decision tree
|
|
41
|
+
|
|
42
|
+
| User said... | Run first |
|
|
43
|
+
|---|---|
|
|
44
|
+
| "is it healthy?" / "doctor" | `bag doctor` (scans the `app/agent/` sub-project from the workspace root) |
|
|
45
|
+
| "run locally" / "start it" / "dev" | `bag dev` (serves the selected protocol: A2A on `:9000`, MCP on `:8000/mcp` — same for any destination) |
|
|
46
|
+
| "what's my balance?" / "how much U?" | `bag wallet balance` (native + U; `--network X` / `--all` available. `--address X` is **v0.2 backlog — not in v0.0.x**) |
|
|
47
|
+
| "send X tBNB / U to another address" | ⚠️ **v0.2 backlog — `bag wallet transfer` does not exist in v0.0.x.** No transfer CLI yet; move funds with an external wallet |
|
|
48
|
+
| "approve commerce contract to spend U" | ⚠️ **v0.2 backlog — `bag erc20` group does not exist in v0.0.x** (funding flows auto-approve U; no manual approve CLI) |
|
|
49
|
+
| "how much have I approved 0x... for?" | ⚠️ **v0.2 backlog — `bag erc20 allowance` does not exist in v0.0.x** |
|
|
50
|
+
| "is my agent registered?" | `bag erc8004 show` (note: registration is normally automatic at `bag deploy verify` — manual `bag erc8004 register` only if you need an identity before deploy) |
|
|
51
|
+
| "what's the status of job X?" | `bag erc8183 status <id>` (read-only — neutral) |
|
|
52
|
+
| "settle job X" | `bag erc8183 settle <id> --action approve\|reject\|dispute` (default `approve`) — **seller's manual step** after the dispute window; deeper context in `bnbagent-studio-selling-via-8183.md` (same directory) |
|
|
53
|
+
| "submit work for job X" | **seller action** — read `bnbagent-studio-selling-via-8183.md` (same directory) for the submit/dispute flow |
|
|
54
|
+
| "tx not confirming" | Read BscScan link from prior tx output + check `eth_getTransactionCount` |
|
|
55
|
+
| "wallet balance is wrong" | Check both tBNB (gas) and U (token); see balance section |
|
|
56
|
+
| "is it deployed?" / "deploy status" | `bag deploy status` lists every locally recorded BNB/AWS/Azure deployment and asks `bnbagent-deploy` for live state; add `--no-probe` for record-only output |
|
|
57
|
+
| "deploy logs" / "verify" / "tear it down" | With one recorded deployment, `bag deploy {logs,verify,destroy}` selects it automatically. With multiple, choose interactively or pass `--provider bnb\|aws\|azure` in automation. Cloud calls always go through `bnbagent-deploy`. `bag platform credit` shows the BNB trial countdown. |
|
|
58
|
+
|
|
59
|
+
## Common ops procedures
|
|
60
|
+
|
|
61
|
+
### A. Run the agent locally (the default)
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Configure secrets (idempotent — does NOT duplicate existing keys).
|
|
65
|
+
# These write into .studio/.env.local (the Agent's secrets):
|
|
66
|
+
bag env set WALLET_PASSWORD <your password>
|
|
67
|
+
bag env set OPENROUTER_API_KEY <your key> # or whichever provider app/agent/studio.toml [llm] uses
|
|
68
|
+
|
|
69
|
+
# From the workspace root — `bag dev` serves the selected protocol:
|
|
70
|
+
bag dev # A2A agent on :9000, MCP on :8000/mcp (same for any destination)
|
|
71
|
+
bag dev --port 9100 # override the port
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`bag dev` sets `STORAGE_LOCAL_PATH=~/.bag/deliverables/<workspace-name>/` for the
|
|
75
|
+
agent subprocess and runs it **without** Cognito env, so the local endpoint is
|
|
76
|
+
reachable without a token (Cognito is mandatory only on the deployed AgentCore
|
|
77
|
+
runtime). For A2A projects, the agent
|
|
78
|
+
(`app/agent/src/main.ts`) exposes `/.well-known/agent-card.json` +
|
|
79
|
+
JSON-RPC `message/send` + `GET /ping` on `:9000`. Smoke-test the card with curl:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
curl http://localhost:9000/.well-known/agent-card.json
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Expect the agent card with its two skills (`negotiate`, `notify_funded`).
|
|
86
|
+
For MCP projects, connect an MCP client to `http://localhost:8000/mcp`.
|
|
87
|
+
|
|
88
|
+
> ⚠️ **The AgentCore inspector chat box cannot test a seller agent.** A seller's
|
|
89
|
+
> skills are structured A2A `DataPart`s (`message/send`), but the inspector chat
|
|
90
|
+
> box can only send plain text — it can never construct a `{"skill":"negotiate", …}`
|
|
91
|
+
> part, so it can't reach the agent's real product surface (and its streaming view
|
|
92
|
+
> expects Task events, not the `message` reply the agent emits). **Test locally
|
|
93
|
+
> with curl or an A2A client sending a `DataPart`**, not the chat box.
|
|
94
|
+
|
|
95
|
+
Drive a sale by sending the skills directly (`negotiate` `terms` MUST include
|
|
96
|
+
`deliverables` + `quality_standards`, else the quote is rejected `reason_code 0x04`):
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# negotiate → signed quote envelope
|
|
100
|
+
curl -s -X POST http://localhost:9000/ -H "Content-Type: application/json" -d '{
|
|
101
|
+
"jsonrpc":"2.0","id":1,"method":"message/send",
|
|
102
|
+
"params":{"message":{"role":"user","parts":[{"kind":"data","data":{
|
|
103
|
+
"skill":"negotiate",
|
|
104
|
+
"task_description":"...",
|
|
105
|
+
"terms":{"deliverables":"...","quality_standards":"..."}
|
|
106
|
+
}}],"messageId":"nego-1"}}}'
|
|
107
|
+
|
|
108
|
+
# notify_funded → ack (then background delivery; poll the chain for the result)
|
|
109
|
+
curl -s -X POST http://localhost:9000/ -H "Content-Type: application/json" -d '{
|
|
110
|
+
"jsonrpc":"2.0","id":2,"method":"message/send",
|
|
111
|
+
"params":{"message":{"role":"user","parts":[{"kind":"data","data":{
|
|
112
|
+
"skill":"notify_funded","job_id":<int>
|
|
113
|
+
}}],"messageId":"notify-1"}}}'
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
See `erc8183-buyer-push.md` for the full line protocol. Ctrl-C to stop.
|
|
117
|
+
|
|
118
|
+
### B. Doctor — full project health
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
bag doctor
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Returns a rich table of checks across the `app/agent/` sub-project:
|
|
125
|
+
|
|
126
|
+
| Check | What FAIL means | Fix |
|
|
127
|
+
|---|---|---|
|
|
128
|
+
| app/agent/studio.toml parseable | Missing or syntax error | `bag init` to regenerate, or hand-fix TOML |
|
|
129
|
+
| Agent entrypoint imports | Protocol entrypoint raises on load (`src/main.ts` for A2A, `src/mcpMain.ts` for MCP) | Fix the error printed by the check (often a missing env var or a broken import) |
|
|
130
|
+
| wallet keystore | No `<workspace>/.studio/wallets/*.json` | `bag wallet new` (writes to the workspace root keystore dir) |
|
|
131
|
+
| WALLET_PASSWORD env | Not in `.studio/.env.local` / not exported | `bag env set WALLET_PASSWORD ...` (targets .studio/.env.local) |
|
|
132
|
+
| LLM provider key | API key env not set | Edit `.studio/.env.local` or export the right `*_API_KEY` |
|
|
133
|
+
| Network reachable | RPC down/wrong URL | Override via `STUDIO_BSC_TESTNET_RPC=...` (testnet) / `STUDIO_BSC_RPC=...` (mainnet) — per-network env vars read by `@bnbagent/studio-runtime/networks` `getNetwork` |
|
|
134
|
+
| Wallet tBNB balance | 0 tBNB | Faucet: testnet.bnbchain.org/faucet-smart |
|
|
135
|
+
| Wallet U balance | 0 U | Transfer from holder, or ask for sponsor U |
|
|
136
|
+
| 8004 registered | Not registered | Normally registered automatically at `bag deploy verify`. Manual: `bag erc8004 register --endpoint <url>` (only if you need an on-chain identity before deploy). WARN-only in `bag doctor` — it doesn't block local dev. |
|
|
137
|
+
| Cognito authorizer (W9) | External-buyer readiness: `agentcore.json` carries no `authorizerConfiguration` / protocol metadata has placeholder `OAUTH_*` values | WARN-only (does NOT block) — needed to serve **external** buyers, not to deploy. With no authorizer the runtime is IAM/SigV4 owner-only (never anonymous). To open it to buyers: `bag deploy provision-cognito` → `cdk deploy --outputs-file cdk-outputs.json` → `bag deploy provision-cognito --wire`. |
|
|
138
|
+
|
|
139
|
+
WARN-only items don't block; FAIL items do (exit 1).
|
|
140
|
+
|
|
141
|
+
### C. Balance / wallet inspection
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
bag wallet show # local view: address + keystore path (workspace root .studio/wallets/)
|
|
145
|
+
bag wallet list # all keystores in <workspace>/.studio/wallets/
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
For on-chain balance of the configured wallet (BNB + U):
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
bag wallet balance # [network].default — BNB + U
|
|
152
|
+
bag wallet balance --network bsc-mainnet # override to a specific network
|
|
153
|
+
bag wallet balance --all # both [network].default AND [llm.pieverse].network
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The `--all` form is the right move when `app/agent/studio.toml`'s
|
|
157
|
+
`[network].default = bsc-testnet` and `[llm].provider = pieverse-llm`:
|
|
158
|
+
testnet U pays ERC-8183 jobs, mainnet U pays the Pieverse LLM auto-renew.
|
|
159
|
+
Same wallet address on both chains.
|
|
160
|
+
|
|
161
|
+
> ⚠️ **v0.2 backlog — not in v0.0.x.** There is **no** `bag wallet transfer`,
|
|
162
|
+
> no `bag erc20 approve/allowance` group, and no `bag wallet balance --address`
|
|
163
|
+
> / `--token` flag in v0.0.x — running any of them errors with
|
|
164
|
+
> `invalid choice` / `unrecognized arguments`. To move funds or set allowances
|
|
165
|
+
> today, use an external wallet; ERC-8183 funding auto-approves U as part of the
|
|
166
|
+
> buy flow. These CLIs are planned for v0.2.
|
|
167
|
+
|
|
168
|
+
For programmatic access from inside an agent's code, the MCP tools (when wired
|
|
169
|
+
into Claude Code) provide `balance_u` / `balance_native` as well — but the CLI
|
|
170
|
+
is the fastest path during dev.
|
|
171
|
+
|
|
172
|
+
### D. Job state inspection (8183)
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
bag erc8183 list --mine # all jobs where I'm the client
|
|
176
|
+
bag erc8183 list --provider 0xPROV # jobs I could serve as seller
|
|
177
|
+
bag erc8183 status <job_id> # one job's full record
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
JobStatus enum: `OPEN` (0) → `FUNDED` (1) → `SUBMITTED` (2) → `COMPLETED` (3) /
|
|
181
|
+
`REJECTED` (4) / `EXPIRED` (5).
|
|
182
|
+
|
|
183
|
+
`FUNDED` jobs are what the deployed agent delivers — either when the buyer sends a
|
|
184
|
+
`notify_funded` A2A message (the agent acks then delivers in the **background**;
|
|
185
|
+
read the result from the chain) or via the deduped background sweep on the next
|
|
186
|
+
notify (see `erc8183-buyer-push.md`). While background work is in flight the
|
|
187
|
+
runtime stays warm via `/ping` `HEALTHY_BUSY`; a scaled-to-zero idle agent won't
|
|
188
|
+
deliver until the next notify (a v2 Lambda poller closes that cold window).
|
|
189
|
+
`SUBMITTED` jobs trigger the **buyer decision
|
|
190
|
+
tree** (approve / dispute / reject within the dispute window) — full flow in the
|
|
191
|
+
`bnbagent-studio-buying-via-8183.md` reference (see the Deep-dive references
|
|
192
|
+
list above). From the seller side, defending a dispute is
|
|
193
|
+
covered in `bnbagent-studio-selling-via-8183.md` (same directory).
|
|
194
|
+
|
|
195
|
+
### E. Common errors + remediation
|
|
196
|
+
|
|
197
|
+
| Error pattern | Cause | Fix |
|
|
198
|
+
|---|---|---|
|
|
199
|
+
| `Submission deadline has passed` | Buyer set `expiredAt` too soon (< dispute_window) | Use `--deadline-min` ≥ 1 (workflow auto-adds dispute_window now) |
|
|
200
|
+
| `Transaction would revert: ('0x17be5b7b', ...)` | Trying to `settle approve` before dispute_window | Wait 24h or use `--action dispute` |
|
|
201
|
+
| `notify_funded` replies `{"status":"rejected","reason":...}` | `verifySignedJob` failed synchronously in the ack — a **permanent** failure | `reason` names it: not our signature / tampered terms / underfunded / expired (or `error` for a malformed `job_id`). The job is refused outright; re-fund/re-notify with a correct, fully-funded job |
|
|
202
|
+
| Job stays `FUNDED`, never reaches `SUBMITTED` after an `accepted` ack | Background delivery failed (`runWork` / `submitResult` raised) — **not** visible in the A2A reply | The ack only confirms verify passed; delivery runs in the background. Observe the failure via the chain (job never leaves `FUNDED`) + CloudWatch logs; a later `notify_funded` re-attempts it via the sweep |
|
|
203
|
+
| `ERC8183JobOps` has no such export from `@bnbagent/sdk` | package.json pinned an old `@bnbagent/sdk` (missing class) | Bump the dependency and reinstall |
|
|
204
|
+
| `OPENROUTER_API_KEY env var is required` | Loading the entrypoint triggers the emitted `buildModel()` factory | Set the env var even for `bag dev --help` smoke |
|
|
205
|
+
| RPC `limit exceeded` | Public RPC throttle | Retry, or set `STUDIO_BSC_TESTNET_RPC=<private rpc>` |
|
|
206
|
+
|
|
207
|
+
## Reference
|
|
208
|
+
|
|
209
|
+
- `docs/design/single-seller-agent.md` (the A2A deploy model and history)
|
|
210
|
+
- `docs/design/erc8183-buyer-push.md` (how a buyer drives an A2A sale)
|
|
211
|
+
- `docs/design/architecture.md §2.5` (the single seller runtime — as-built truth)
|