@bnbagent/studio-cli 0.0.6-alpha.1 → 0.0.6-alpha.3
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/dist/bag.js +948 -190
- package/dist/{chunk-M3ODFCA7.js → chunk-A7NAGZHR.js} +94 -15
- package/dist/{deployCli-N6TPN6XA.js → deployCli-264UE6KB.js} +1 -1
- package/package.json +3 -3
- package/recipes/agent/code/{{PKG}}/signing.ts.tmpl +12 -1
- package/recipes/runtimes/agentcore/code/{{PKG}}/dualMain.ts.tmpl +6 -3
- package/recipes/runtimes/agentcore/code/{{PKG}}/main.ts.tmpl +6 -3
- package/recipes/runtimes/agentcore/code/{{PKG}}/mcpMain.ts.tmpl +7 -5
- package/recipes/runtimes/agentcore/code/{{PKG}}/sellerCore.ts.tmpl +3 -2
- package/skills/bnbagent-studio.md +21 -14
- package/skills/references/bnbagent-studio-adding-to-project.md +17 -1
- package/skills/references/bnbagent-studio-buying-via-8183.md +19 -3
- package/skills/references/bnbagent-studio-operating.md +21 -3
- package/skills/references/bnbagent-studio-scaffolding-agent.md +18 -3
- package/skills/references/bnbagent-studio-selling-via-8183.md +20 -0
- package/skills/references/bnbagent-studio-selling-via-b402.md +42 -18
- package/skills/references/bnbagent-studio-use-aws-agentcore.md +3 -2
- package/skills/references/bnbagent-studio-use-azure-foundry.md +1 -1
- package/skills/references/bnbagent-studio-use-bnb-trial.md +2 -2
- package/skills/references/bnbagent-studio-using-altana-wallet.md +5 -4
- package/skills/references/bnbagent-studio-using-twak-wallet.md +10 -8
|
@@ -293,6 +293,53 @@ function mb(n) {
|
|
|
293
293
|
return `${(n / (1024 * 1024)).toFixed(1)}MB`;
|
|
294
294
|
}
|
|
295
295
|
|
|
296
|
+
// src/cli/_x402SellerConfig.ts
|
|
297
|
+
var DEFAULT_B402_PRICE_USD = "0.01";
|
|
298
|
+
var DEFAULT_B402_TESTNET_BASE_URL = "https://qacb.sdtaop.com";
|
|
299
|
+
var PRICE_USD_RE = /^(?:0|[1-9]\d*)(?:\.\d+)?$/;
|
|
300
|
+
var ZERO_PRICE_USD_RE = /^0(?:\.0+)?$/;
|
|
301
|
+
function x402SellerPricingState(seller) {
|
|
302
|
+
const raw = seller.price_usd;
|
|
303
|
+
const priceUsd = raw === void 0 ? DEFAULT_B402_PRICE_USD : typeof raw === "string" ? raw : "";
|
|
304
|
+
if (!PRICE_USD_RE.test(priceUsd)) {
|
|
305
|
+
return { kind: "invalid", value: String(raw ?? "") };
|
|
306
|
+
}
|
|
307
|
+
return {
|
|
308
|
+
kind: ZERO_PRICE_USD_RE.test(priceUsd) ? "free" : "paid",
|
|
309
|
+
priceUsd
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
function normalizeB402PriceUsd(value) {
|
|
313
|
+
const normalized = value.trim();
|
|
314
|
+
if (!PRICE_USD_RE.test(normalized)) {
|
|
315
|
+
throw new Error(
|
|
316
|
+
`B402 price must be a non-negative decimal USD string; got ${JSON.stringify(value)}.`
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
return normalized;
|
|
320
|
+
}
|
|
321
|
+
function isB402TestnetBaseUrl(value) {
|
|
322
|
+
try {
|
|
323
|
+
const url = new URL(value);
|
|
324
|
+
if (url.origin === DEFAULT_B402_TESTNET_BASE_URL) return true;
|
|
325
|
+
} catch {
|
|
326
|
+
}
|
|
327
|
+
return /sandbox|test/.test(value.toLowerCase());
|
|
328
|
+
}
|
|
329
|
+
function x402SellerUsesB402(cfg) {
|
|
330
|
+
const payments = table2(cfg.payments);
|
|
331
|
+
const seller = table2(payments.x402_seller);
|
|
332
|
+
return seller.enabled === true && x402SellerPricingState(seller).kind === "paid";
|
|
333
|
+
}
|
|
334
|
+
function x402SellerIsFree(cfg) {
|
|
335
|
+
const payments = table2(cfg.payments);
|
|
336
|
+
const seller = table2(payments.x402_seller);
|
|
337
|
+
return seller.enabled === true && x402SellerPricingState(seller).kind === "free";
|
|
338
|
+
}
|
|
339
|
+
function table2(value) {
|
|
340
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
341
|
+
}
|
|
342
|
+
|
|
296
343
|
// src/cli/exit.ts
|
|
297
344
|
var CliExit = class extends Error {
|
|
298
345
|
constructor(code) {
|
|
@@ -597,10 +644,10 @@ var B402_RUNTIME_KEYS = [
|
|
|
597
644
|
"B402_PRIVATE_KEY_B64"
|
|
598
645
|
];
|
|
599
646
|
function commerceRails(cfg) {
|
|
600
|
-
const payments =
|
|
647
|
+
const payments = table3(cfg.payments);
|
|
601
648
|
return {
|
|
602
649
|
erc8183: isTable(payments.erc8183),
|
|
603
|
-
x402:
|
|
650
|
+
x402: table3(payments.x402_seller).enabled === true
|
|
604
651
|
};
|
|
605
652
|
}
|
|
606
653
|
function b402Credentials(agentRoot) {
|
|
@@ -611,10 +658,14 @@ function b402Credentials(agentRoot) {
|
|
|
611
658
|
if (value) values.set(key, value);
|
|
612
659
|
}
|
|
613
660
|
const privateKey = values.has("B402_PRIVATE_KEY") || values.has("B402_PRIVATE_KEY_B64");
|
|
661
|
+
const onlyDefaultBaseUrl = values.size === 1 && values.get("B402_BASE_URL")?.replace(/\/+$/, "") === DEFAULT_B402_TESTNET_BASE_URL;
|
|
614
662
|
return {
|
|
615
663
|
presentKeys: [...values.keys()],
|
|
616
664
|
complete: values.has("B402_BASE_URL") && values.has("B402_CLIENT_ID") && values.has("B402_ACCESS_TOKEN") && privateKey,
|
|
617
|
-
|
|
665
|
+
// The testnet facilitator URL is a non-secret platform default. On its own it must not turn an
|
|
666
|
+
// otherwise dormant rail into a "partial credentials" deployment failure. Any custom URL or
|
|
667
|
+
// merchant credential still preserves the existing partial/unused checks.
|
|
668
|
+
any: values.size > 0 && !onlyDefaultBaseUrl,
|
|
618
669
|
bothPrivateKeyFormats: values.has("B402_PRIVATE_KEY") && values.has("B402_PRIVATE_KEY_B64"),
|
|
619
670
|
baseUrl: values.get("B402_BASE_URL") ?? null
|
|
620
671
|
};
|
|
@@ -633,15 +684,36 @@ function loadDeployConfig(root) {
|
|
|
633
684
|
function x402DeploySummary(root, destination, publicUrl) {
|
|
634
685
|
const { agentRoot, cfg } = loadDeployConfig(root);
|
|
635
686
|
if (!commerceRails(cfg).x402) return "";
|
|
687
|
+
const seller = table3(table3(cfg.payments).x402_seller);
|
|
688
|
+
const pricing = x402SellerPricingState(seller);
|
|
636
689
|
const credentials = b402Credentials(agentRoot);
|
|
637
690
|
const activation = "run the bnbagent-studio-selling-via-b402 skill, fill the four B402_* variables in .studio/.env.local, then redeploy.";
|
|
638
|
-
|
|
639
|
-
return `x402 rail is DORMANT. To activate: ${activation}`;
|
|
640
|
-
}
|
|
641
|
-
const runtime = String(table2(cfg.stack).runtime ?? "agentcore");
|
|
691
|
+
const runtime = String(table3(cfg.stack).runtime ?? "agentcore");
|
|
642
692
|
if (destination !== "platform" && runtime !== "agentcore") {
|
|
643
693
|
return `x402 rail is FORCED DORMANT: the ${runtime} runtime has no x402 path. Deploy to AgentCore (managed platform or self-hosted) to activate the rail.`;
|
|
644
694
|
}
|
|
695
|
+
if (pricing.kind === "invalid") {
|
|
696
|
+
return "x402 rail is DORMANT: price_usd is invalid; run `bag doctor`.";
|
|
697
|
+
}
|
|
698
|
+
if (pricing.kind === "free") {
|
|
699
|
+
if (destination !== "platform") {
|
|
700
|
+
return [
|
|
701
|
+
"x402 rail is ACTIVE in FREE mode (self-hosted AgentCore).",
|
|
702
|
+
"B402 verify/settle is bypassed; no credentials, token payment, or settlement audit is used.",
|
|
703
|
+
"This target has no anonymous public URL; expose /x402 with your own HTTP front.",
|
|
704
|
+
'The front reaches the agent by wrapping each request as envelope-v1 JSON \u2014 {"v":1,"method":"POST","path":"/x402","headers":{...},"body":"<base64>"} \u2014 inside a SigV4-signed (or JWT bearer) InvokeAgentRuntime call. Limits: 1 MiB request, 5 MiB response, no streaming.'
|
|
705
|
+
].join("\n");
|
|
706
|
+
}
|
|
707
|
+
const url2 = publicUrl ?? "<available after the platform agentId is assigned>";
|
|
708
|
+
return [
|
|
709
|
+
"x402 rail is ACTIVE in FREE mode.",
|
|
710
|
+
`Anonymous FREE URL: ${url2}`,
|
|
711
|
+
"B402 verify/settle is bypassed; no credentials, token payment, or settlement audit is used."
|
|
712
|
+
].join("\n");
|
|
713
|
+
}
|
|
714
|
+
if (!credentials.complete) {
|
|
715
|
+
return `x402 rail is DORMANT. To activate: ${activation}`;
|
|
716
|
+
}
|
|
645
717
|
const settlement = [
|
|
646
718
|
"B402 settlement runs inside every paid request and normally adds 10\u201345 s; buyer timeout must be at least 120 s.",
|
|
647
719
|
"Settlement happens before work. If work later fails, the payment is retained and is not refunded automatically."
|
|
@@ -663,7 +735,7 @@ function x402DeploySummary(root, destination, publicUrl) {
|
|
|
663
735
|
...settlement
|
|
664
736
|
].join("\n");
|
|
665
737
|
}
|
|
666
|
-
function
|
|
738
|
+
function table3(value) {
|
|
667
739
|
return isTable(value) ? value : {};
|
|
668
740
|
}
|
|
669
741
|
function isTable(value) {
|
|
@@ -735,14 +807,14 @@ function deployCommand(environment = process.env) {
|
|
|
735
807
|
}
|
|
736
808
|
return ["bunx", "--bun", DEPLOY_CLI_PACKAGE];
|
|
737
809
|
}
|
|
738
|
-
function providerPassthrough(studio,
|
|
739
|
-
const raw = tableOf(studio, "deploy")[
|
|
810
|
+
function providerPassthrough(studio, table4) {
|
|
811
|
+
const raw = tableOf(studio, "deploy")[table4];
|
|
740
812
|
if (raw === void 0 || raw === null) {
|
|
741
813
|
return {};
|
|
742
814
|
}
|
|
743
815
|
if (typeof raw !== "object" || Array.isArray(raw)) {
|
|
744
816
|
throw new Error(
|
|
745
|
-
`studio.toml [deploy.${
|
|
817
|
+
`studio.toml [deploy.${table4}] must be a TOML table of deploy-spec keys`
|
|
746
818
|
);
|
|
747
819
|
}
|
|
748
820
|
return { ...raw };
|
|
@@ -835,10 +907,10 @@ function buildDeploySpec(root, opts) {
|
|
|
835
907
|
}
|
|
836
908
|
doc.foundry = foundry;
|
|
837
909
|
} else {
|
|
838
|
-
for (const
|
|
839
|
-
if (Object.keys(providerPassthrough(studio,
|
|
910
|
+
for (const table4 of ["agentcore", "foundry"]) {
|
|
911
|
+
if (Object.keys(providerPassthrough(studio, table4)).length > 0) {
|
|
840
912
|
printErr(
|
|
841
|
-
`note: the bnb/trial platform does not allow custom provider configuration; [deploy.${
|
|
913
|
+
`note: the bnb/trial platform does not allow custom provider configuration; [deploy.${table4}] ignored`
|
|
842
914
|
);
|
|
843
915
|
}
|
|
844
916
|
}
|
|
@@ -848,7 +920,7 @@ function buildDeploySpec(root, opts) {
|
|
|
848
920
|
if (opts.inlineSecrets) {
|
|
849
921
|
Object.assign(env, opts.inlineSecrets);
|
|
850
922
|
}
|
|
851
|
-
if (opts.target === "bnb/trial" && tableOf(studio, "deploy").destination === "platform" && (!hasProtocolsArray || hasX402Face(faces)) && commerceRails(studio).x402 && b402Credentials(agentRoot).complete) {
|
|
923
|
+
if (opts.target === "bnb/trial" && tableOf(studio, "deploy").destination === "platform" && (!hasProtocolsArray || hasX402Face(faces)) && commerceRails(studio).x402 && (x402SellerIsFree(studio) || b402Credentials(agentRoot).complete)) {
|
|
852
924
|
doc.x402 = {
|
|
853
925
|
publicPaths: ["/x402"],
|
|
854
926
|
tunnel: "http-envelope-v1"
|
|
@@ -1019,6 +1091,13 @@ export {
|
|
|
1019
1091
|
entryStemOf,
|
|
1020
1092
|
devPortOf,
|
|
1021
1093
|
recipeModeOf,
|
|
1094
|
+
DEFAULT_B402_PRICE_USD,
|
|
1095
|
+
DEFAULT_B402_TESTNET_BASE_URL,
|
|
1096
|
+
x402SellerPricingState,
|
|
1097
|
+
normalizeB402PriceUsd,
|
|
1098
|
+
isB402TestnetBaseUrl,
|
|
1099
|
+
x402SellerUsesB402,
|
|
1100
|
+
x402SellerIsFree,
|
|
1022
1101
|
whichBin,
|
|
1023
1102
|
agentcoreFlavor,
|
|
1024
1103
|
checkDocker,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bnbagent/studio-cli",
|
|
3
|
-
"version": "0.0.6-alpha.
|
|
3
|
+
"version": "0.0.6-alpha.3",
|
|
4
4
|
"description": "The `bag` CLI: scaffold, run, deploy, and monetize a single seller agent on BNB Chain (ERC-8004 identity, ERC-8183 commerce, x402 payments).",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"bag": "./dist/bag.js"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@bnbagent/sdk": "0.5.0-alpha.
|
|
28
|
+
"@bnbagent/sdk": "0.5.0-alpha.2",
|
|
29
29
|
"ai": "^7.0.29",
|
|
30
30
|
"archiver": "^8.0.0",
|
|
31
31
|
"commander": "^15.0.0",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"tar": "^7.4.0",
|
|
38
38
|
"viem": "^2.54.0",
|
|
39
39
|
"yaml": "^2.9.0",
|
|
40
|
-
"@bnbagent/studio-runtime": "0.0.6-alpha.
|
|
40
|
+
"@bnbagent/studio-runtime": "0.0.6-alpha.3"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@a2a-js/sdk": "^0.3.14",
|
|
@@ -111,6 +111,17 @@ function defaultNetworkName(): string {
|
|
|
111
111
|
return String(((cfg.network ?? {}) as TomlTable).default ?? "bsc-testnet");
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Bind provider_sig to the same Commerce deployment used by the runtime
|
|
116
|
+
* client. QA/custom stacks override the canonical SDK registry via env.
|
|
117
|
+
*/
|
|
118
|
+
export function commerceVerifyingContract(
|
|
119
|
+
chainId: number,
|
|
120
|
+
): `0x${string}` {
|
|
121
|
+
const override = process.env.ERC8183_COMMERCE_ADDRESS?.trim();
|
|
122
|
+
return (override || deployedAddresses(chainId).commerceProxy) as `0x${string}`;
|
|
123
|
+
}
|
|
124
|
+
|
|
114
125
|
/**
|
|
115
126
|
* Return `[minPrice, maxPrice]` in raw wei from studio.toml.
|
|
116
127
|
*
|
|
@@ -182,7 +193,7 @@ function getHandler(): NegotiationHandlerLike {
|
|
|
182
193
|
...negotiationSignerOptions(wallet),
|
|
183
194
|
quoteTtlSeconds: ttl,
|
|
184
195
|
chainId: network.chainId,
|
|
185
|
-
verifyingContract:
|
|
196
|
+
verifyingContract: commerceVerifyingContract(network.chainId),
|
|
186
197
|
});
|
|
187
198
|
}
|
|
188
199
|
return handler;
|
|
@@ -159,8 +159,9 @@ function defaultNetwork(): string {
|
|
|
159
159
|
// the ONLY automatic signing path outside signing.ts — it is budget-gated and
|
|
160
160
|
// is NOT an LLM tool. It rides transparently into the delivery step.
|
|
161
161
|
//
|
|
162
|
-
// The LLM runs
|
|
163
|
-
//
|
|
162
|
+
// The LLM runs only in an authorized value step: verified ERC-8183 delivery
|
|
163
|
+
// or x402 work after its payment/free gate. `negotiate` is rule-based and
|
|
164
|
+
// never touches the LLM. The read-only chain tools are
|
|
164
165
|
// attached so the work can read on-chain context if it needs to — drop them
|
|
165
166
|
// from `tools.ts` if your work doesn't read chain. Signing / settle are NEVER
|
|
166
167
|
// tools — they are fixed code in signing.ts, triggered by the A2A skills,
|
|
@@ -178,7 +179,9 @@ export function buildRunWork(): RunWork {
|
|
|
178
179
|
const result = await generateText({
|
|
179
180
|
model,
|
|
180
181
|
system:
|
|
181
|
-
"You are a seller agent.
|
|
182
|
+
"You are a seller agent. The runtime has already authorized this task " +
|
|
183
|
+
"through its configured commerce rail. Complete the user's task now; " +
|
|
184
|
+
"do not ask for a job ID or additional payment. " +
|
|
182
185
|
"Be concrete and concise. Use the read-only chain tools when on-chain " +
|
|
183
186
|
"context helps. If a paid-data tool such as `buy_with_x402` is available " +
|
|
184
187
|
"to you, USE IT to fetch the data a task needs — those merchants (e.g. " +
|
|
@@ -150,8 +150,9 @@ function defaultNetwork(): string {
|
|
|
150
150
|
// the ONLY automatic signing path outside signing.ts — it is budget-gated and
|
|
151
151
|
// is NOT an LLM tool. It rides transparently into the delivery step.
|
|
152
152
|
//
|
|
153
|
-
// The LLM runs
|
|
154
|
-
//
|
|
153
|
+
// The LLM runs only in an authorized value step: verified ERC-8183 delivery
|
|
154
|
+
// or x402 work after its payment/free gate. `negotiate` is rule-based and
|
|
155
|
+
// never touches the LLM. The read-only chain tools are
|
|
155
156
|
// attached so the work can read on-chain context if it needs to — drop them
|
|
156
157
|
// from `tools.ts` if your work doesn't read chain. Signing / settle are NEVER
|
|
157
158
|
// tools — they are fixed code in signing.ts, triggered by the A2A skills,
|
|
@@ -169,7 +170,9 @@ export function buildRunWork(): RunWork {
|
|
|
169
170
|
const result = await generateText({
|
|
170
171
|
model,
|
|
171
172
|
system:
|
|
172
|
-
"You are a seller agent.
|
|
173
|
+
"You are a seller agent. The runtime has already authorized this task " +
|
|
174
|
+
"through its configured commerce rail. Complete the user's task now; " +
|
|
175
|
+
"do not ask for a job ID or additional payment. " +
|
|
173
176
|
"Be concrete and concise. Use the read-only chain tools when on-chain " +
|
|
174
177
|
"context helps. If a paid-data tool such as `buy_with_x402` is available " +
|
|
175
178
|
"to you, USE IT to fetch the data a task needs — those merchants (e.g. " +
|
|
@@ -184,10 +184,10 @@ function flatQuery(query: Record<string, unknown>): Record<string, string> {
|
|
|
184
184
|
return out;
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
// ── LLM work hook (lazy: built on first
|
|
188
|
-
// Deferred construction keeps
|
|
189
|
-
//
|
|
190
|
-
//
|
|
187
|
+
// ── LLM work hook (lazy: built on first authorized task) ─────────────────────
|
|
188
|
+
// Deferred construction keeps negotiate and unpaid x402 quote paths from
|
|
189
|
+
// building the model, and keeps this module importable without the provider
|
|
190
|
+
// env until a deliverable is actually produced.
|
|
191
191
|
type RunLlm = (prompt: string) => Promise<string>;
|
|
192
192
|
let cachedRunLlm: RunLlm | null = null;
|
|
193
193
|
|
|
@@ -200,7 +200,9 @@ async function runLlm(prompt: string): Promise<string> {
|
|
|
200
200
|
const result = await generateText({
|
|
201
201
|
model,
|
|
202
202
|
system:
|
|
203
|
-
"You are a seller agent.
|
|
203
|
+
"You are a seller agent. The runtime has already authorized this task " +
|
|
204
|
+
"through its configured commerce rail. Complete the user's task now; " +
|
|
205
|
+
"do not ask for a job ID or additional payment. " +
|
|
204
206
|
"Be concrete and concise. Use the read-only chain tools when on-chain " +
|
|
205
207
|
"context helps. If a paid-data tool such as `buy_with_x402` is " +
|
|
206
208
|
"available to you, USE IT to fetch the data a task needs — those " +
|
|
@@ -105,8 +105,9 @@ async function withTimeout<T>(
|
|
|
105
105
|
* The LLM work hook: produce the deliverable text for a prompt.
|
|
106
106
|
*
|
|
107
107
|
* Built in `main.ts` from the AI SDK (`generateText` + the read-only chain
|
|
108
|
-
* tools); called
|
|
109
|
-
*
|
|
108
|
+
* tools); called by verified ERC-8183 delivery and, through the runtime
|
|
109
|
+
* adapter, by x402 only after its commerce gate. `abortSignal` is wired to
|
|
110
|
+
* the delivery timeout so a hung LLM call is actually cancelled.
|
|
110
111
|
*/
|
|
111
112
|
export type RunWork = (
|
|
112
113
|
prompt: string,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: bnbagent-studio
|
|
3
|
-
description: The single entry point for bnbagent-studio — a TypeScript CLI (`bag`) for building a blockchain SELLER agent that earns $U on BNB Chain via ERC-8004 + ERC-8183 + x402 (Pieverse LLM inside). Load this skill whenever the user works in a bnbagent-studio / `bag` project, or wants to create/scaffold, deploy, run, debug, operate, or monetize such a seller agent (composable A2A, MCP, and X402 faces; BNB Chain trial
|
|
3
|
+
description: The single entry point for bnbagent-studio — a TypeScript CLI (`bag`) for building a blockchain SELLER agent that earns $U on BNB Chain via ERC-8004 + ERC-8183 + x402 (Pieverse LLM inside). Load this skill whenever the user works in a bnbagent-studio / `bag` project, or wants to create/scaffold, deploy, run, debug, operate, or monetize such a seller agent (composable A2A, MCP, and X402 faces; BNB Chain trial or AWS AgentCore). All detailed playbooks ship as references/ files inside this skill — route via the decision tree in the body. When invoked with arguments, treat them as the user's intent and route the same way.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# bnbagent-studio (the single entry point)
|
|
@@ -10,15 +10,13 @@ ERC-8004 / ERC-8183 / Pieverse LLM) into a TypeScript agent project, then deploy
|
|
|
10
10
|
as a **single blockchain seller runtime**. A2A, MCP, and X402 are composable
|
|
11
11
|
public faces selected with `--protocols`; A2A is the default. `bag deploy` uses
|
|
12
12
|
**scheme C**: every new deploy
|
|
13
|
-
or redeploy explicitly selects BNB
|
|
13
|
+
or redeploy explicitly selects BNB or AWS; a recorded deployment is
|
|
14
14
|
used only to offer an explicit update action, never as a silent default. BNB is
|
|
15
|
-
a 48h testnet trial and is disabled after expiry. AWS
|
|
15
|
+
a 48h testnet trial and is disabled after expiry. AWS deploys into the
|
|
16
16
|
user's own account. All cloud lifecycle calls go through the pinned
|
|
17
|
-
`@bnbagent/deploy-cli`; never require `aws
|
|
18
|
-
BNB/AWS share the agentcore scaffold
|
|
19
|
-
|
|
20
|
-
Invocations contract is not the native MCP transport). Treat an incompatible provider row as unavailable—do not
|
|
21
|
-
force through it or mutate the scaffold during deploy.
|
|
17
|
+
`@bnbagent/deploy-cli`; never require the `aws` CLI.
|
|
18
|
+
BNB/AWS share the agentcore scaffold. Treat an incompatible provider row as
|
|
19
|
+
unavailable—do not force through it or mutate the scaffold during deploy.
|
|
22
20
|
|
|
23
21
|
Invoked as `/bnbagent-studio <ask>`? Treat `<ask>` as the user's intent and
|
|
24
22
|
route it through the decision tree below, exactly like a natural-language ask.
|
|
@@ -33,8 +31,9 @@ bounded operations — **`negotiate`** (rule-based price clamp + EIP-191 sign;
|
|
|
33
31
|
**no LLM touches money**) and **`notify_funded`** (verify the funded job →
|
|
34
32
|
produce the deliverable → submit on-chain; A2A acks then delivers in the
|
|
35
33
|
background, MCP delivers synchronously in the tool call). The optional x402
|
|
36
|
-
rail adds an anonymous
|
|
37
|
-
before
|
|
34
|
+
rail adds an anonymous HTTP request at `/x402`; positive prices settle through
|
|
35
|
+
B402 before work, while explicit zero is FREE passthrough and bypasses the
|
|
36
|
+
facilitator. It does not expose a general signing tool. Read-only chain
|
|
38
37
|
tools remain available. ALL signing is fixed entrypoint code in
|
|
39
38
|
`app/agent/src/signing.ts` or the runtime's bounded x402 payment handler, never
|
|
40
39
|
an LLM-callable tool. The encrypted keystore lives at the workspace root
|
|
@@ -55,8 +54,8 @@ not answer from memory.
|
|
|
55
54
|
| Add wallet / the single seller runtime to an existing TypeScript agent | `references/bnbagent-studio-adding-to-project.md` |
|
|
56
55
|
| Run / debug / dev / doctor / RPC / balance / incident triage | `references/bnbagent-studio-operating.md` |
|
|
57
56
|
| Implement what the Agent sells, tune pricing, publish over A2A and/or MCP, defend disputes (seller flow) | `references/bnbagent-studio-selling-via-8183.md` |
|
|
58
|
-
| Sell one paid HTTP request through the B402-backed x402 rail (merchant application, RSA key, credentials, IP allowlist, activation) | `references/bnbagent-studio-selling-via-b402.md` |
|
|
59
|
-
| Deploy / redeploy / status / logs / destroy | Run `bag deploy` and explicitly choose a provider. Non-interactive deploy requires `--provider bnb\|aws
|
|
57
|
+
| Sell one paid or FREE HTTP request through the B402-backed x402 rail (pricing choice; paid merchant application, RSA key, credentials, IP allowlist, activation) | `references/bnbagent-studio-selling-via-b402.md` |
|
|
58
|
+
| Deploy / redeploy / status / logs / destroy | Run `bag deploy` and explicitly choose a provider. Non-interactive deploy requires `--provider bnb\|aws --yes` (and `--allow-multiple` when keeping another provider active). Read `references/bnbagent-studio-use-bnb-trial.md` or `references/bnbagent-studio-use-aws-agentcore.md` for the selected provider. `bag deploy status` lists every recorded provider; multi-deployment logs/verify/destroy require `--provider`. |
|
|
60
59
|
| Wire chain-read tools into the Agent's LLM (AI SDK `tool()` wrappers, or any TS agent framework) | `references/bnbagent-studio-wiring-llm-tools.md` |
|
|
61
60
|
| Buy a service from another ERC-8183 seller via CLI — incl. testing your own seller from the buyer side (v2/internal — NOT the v1 seller product flow) | `references/bnbagent-studio-buying-via-8183.md` |
|
|
62
61
|
| Give the agent a PAID x402 capability — CMC market data / Binance Bazaar (B402) merchants / any pay-per-call API (`bag x402 trust`, x402-buyer recipe, 402 buyer errors) | `references/bnbagent-studio-buying-from-bazaar.md` |
|
|
@@ -84,13 +83,21 @@ must NOT be added to the description — see docs/design/decisions.md §14. -->
|
|
|
84
83
|
|
|
85
84
|
1. **Agent project code is user-owned** — recipe-emitted files are theirs to edit; studio doesn't auto-rewrite them.
|
|
86
85
|
2. **Private keys live in a user-controlled environment, never transmitted to studio or third parties** — the encrypted keystore lives at the workspace root, outside the deploy codeLocation (no packaging path can bundle it). Altana keeps its admin keystore there and gives local runtime only a bounded session; deployment is blocked. Other supported deploy paths inject only their required wallet material into the selected runtime secret channel. (Scoped, consented exception: provider `bnb`, the 48h testnet trial — testnet-forced, throwaway wallet recommended.)
|
|
87
|
-
3. **Signing is fixed handler code, never an LLM-callable tool** — the ERC-8183 rail exposes bounded `negotiate` / `notify_funded` flows and the x402 rail exposes a bounded
|
|
86
|
+
3. **Signing is fixed handler code, never an LLM-callable tool** — the ERC-8183 rail exposes bounded `negotiate` / `notify_funded` flows and the x402 rail exposes a bounded request handler; raw/arbitrary signing is never exposed. Read-only chain queries remain read-only tools.
|
|
88
87
|
4. **SDK protocol layer stays pure** — studio's opinions don't pollute `bnbagent-sdk`.
|
|
89
88
|
5. **The user can jump ship at any point** — emitted code is theirs to edit / fork / migrate; studio depends on no closed SaaS. Emitted code imports from `@bnbagent/studio-runtime` and depends on that runtime lib (not the CLI), so uninstalling the `@bnbagent/studio-cli` package never breaks a deployed agent.
|
|
90
89
|
|
|
90
|
+
Treat ERC-8183 amounts as decimal strings at CLI/config boundaries and
|
|
91
|
+
`bigint` internally. `price = "0"` is an explicit FREE choice, not a missing
|
|
92
|
+
value; it requires all three contract-address overrides from one verified
|
|
93
|
+
zero-price-compatible stack.
|
|
94
|
+
Treat B402 `price_usd` as a decimal string too. `"0"` is explicit anonymous
|
|
95
|
+
FREE passthrough: B402 verify/settle and secret injection are skipped. Positive
|
|
96
|
+
prices retain the paid merchant flow.
|
|
97
|
+
|
|
91
98
|
## CLI groups at a glance
|
|
92
99
|
|
|
93
|
-
`init`, `scan`, `recipe`, `skills`, `wallet`, `erc8004`, `erc8183`, `x402`, `agents`, `config`, `env`, `dev`, `doctor`, `audit`, `deploy`, `platform`, `llm`, `bundle`, `budget` — see `bag --help` for details. `bag deploy [--provider bnb\|aws
|
|
100
|
+
`init`, `scan`, `recipe`, `skills`, `wallet`, `erc8004`, `erc8183`, `x402`, `agents`, `config`, `env`, `dev`, `doctor`, `audit`, `deploy`, `platform`, `llm`, `bundle`, `budget` — see `bag --help` for details. `bag deploy [--provider bnb\|aws]` is the primary deploy command; `prepare`, `verify`, `status`, `info`, `destroy`, `logs`, `fix-gitignore`, and `provision-cognito` remain lifecycle subcommands (`deploy agent` is a deprecated compatibility alias). Provider deploy/status/logs/destroy and deploy-time credential validation are delegated to pinned `@bnbagent/deploy-cli@0.4.14`.
|
|
94
101
|
|
|
95
102
|
## Tool surface
|
|
96
103
|
|
|
@@ -131,6 +131,22 @@ the configured list price, clamps it to `[min_price, max_price]`, then
|
|
|
131
131
|
from the request *before* clamping — the LLM still never sets the price. The
|
|
132
132
|
buyer anchors the signed envelope on-chain via `createJob` + `fund`.
|
|
133
133
|
|
|
134
|
+
Use `bag config set payments.erc8183.price 0` only for an explicit FREE
|
|
135
|
+
product decision. Studio stores ERC-8183 amounts as decimal strings and reports
|
|
136
|
+
FREE in `bag doctor`. Zero funding also requires commerce, router, and policy
|
|
137
|
+
from one compatible stack: set all three `ERC8183_*_ADDRESS` overrides, then
|
|
138
|
+
require `bag doctor` and `bag deploy prepare` to pass. The buyer still runs
|
|
139
|
+
`setBudget(0)` and `fund(0)`, but no ERC-20 approval or token escrow occurs.
|
|
140
|
+
|
|
141
|
+
For an X402 face, choose its request price independently. Use
|
|
142
|
+
`bag config set payments.x402_seller.price_usd 0` only when the existing agent
|
|
143
|
+
is intentionally becoming an unrestricted anonymous FREE API. This path
|
|
144
|
+
bypasses B402 verify/settle, payment, and settlement audit; it needs no merchant
|
|
145
|
+
credentials and Studio will not synchronize any configured B402 secrets.
|
|
146
|
+
Positive prices retain the paid B402 onboarding and settle-before-work flow.
|
|
147
|
+
Verify the choice with `bag x402 sell status`, `bag doctor`, and
|
|
148
|
+
`bag deploy prepare`.
|
|
149
|
+
|
|
134
150
|
## Step 4c — LLM credit continuity (automatic, NOT an LLM tool)
|
|
135
151
|
|
|
136
152
|
For Pieverse projects, the Agent's `buildModel()` factory in the emitted
|
|
@@ -155,7 +171,7 @@ refill with `bag llm topup` or enable the budget with `bag budget enable`.
|
|
|
155
171
|
|
|
156
172
|
## Step 5 — Deploy the agent
|
|
157
173
|
|
|
158
|
-
`bag deploy` always asks the operator to choose BNB
|
|
174
|
+
`bag deploy` always asks the operator to choose BNB or AWS; it never
|
|
159
175
|
silently reuses `[deploy].destination` or the last provider.
|
|
160
176
|
|
|
161
177
|
**Platform scaffold** (the bare-init default while the campaign runs) — one
|
|
@@ -56,13 +56,17 @@ flow now auto-adds dispute_window).
|
|
|
56
56
|
## Preconditions
|
|
57
57
|
|
|
58
58
|
- `bag doctor` is clean (or only warns on LLM key)
|
|
59
|
-
-
|
|
59
|
+
- For a paid job, the wallet has ≥ 0.05 tBNB (gas) and enough U for the budget
|
|
60
|
+
plus slack. On BSC testnet the
|
|
60
61
|
ERC-8183 kernel writes (`createJob` / `fund` deposit / `settle` …) are
|
|
61
62
|
gas-sponsored via the SDK's MegaFuel paymaster, so you spend far less tBNB than
|
|
62
63
|
that — but **not zero**: `fund` sends an ERC-20 `approve` (a token call, not
|
|
63
64
|
sponsored) when the token allowance is too low — typically just the first fund,
|
|
64
65
|
since studio approves a floored cap that later jobs reuse. Keep a little tBNB for
|
|
65
|
-
it. (Mainnet is never sponsored.)
|
|
66
|
+
it. (Mainnet is never sponsored.) For a FREE job, use `--budget-u 0`: no U
|
|
67
|
+
balance, ERC-20 approval, or token escrow is needed, but the ERC-8183 writes
|
|
68
|
+
still need the selected gas/paymaster path and a zero-price-compatible
|
|
69
|
+
commerce/router/policy stack.
|
|
66
70
|
- You know the **provider's wallet address** (the seller agent's address)
|
|
67
71
|
- The seller is **reachable** (its A2A agent is deployed somewhere); discoverable
|
|
68
72
|
via the provider's `bag erc8004 resolve <agent_id>` endpoint URI
|
|
@@ -110,6 +114,13 @@ bag erc8183 buy --provider <provider_addr> "<task description>" \
|
|
|
110
114
|
# `--agent-id` resolves the endpoint + negotiates first.
|
|
111
115
|
```
|
|
112
116
|
|
|
117
|
+
For a signed FREE quote:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
bag erc8183 buy --provider <provider_addr> "<task description>" \
|
|
121
|
+
--budget-u 0 --deadline-min 30 --network bsc-testnet
|
|
122
|
+
```
|
|
123
|
+
|
|
113
124
|
> **Task can be passed two ways** (both accepted): as a positional argument
|
|
114
125
|
> `bag erc8183 buy --provider <addr> "<task>"` OR via the flag
|
|
115
126
|
> `bag erc8183 buy --provider <addr> --task "<task>"`. Pass it once — supplying
|
|
@@ -120,7 +131,8 @@ The 4 on-chain steps run sequentially:
|
|
|
120
131
|
1. `createJob(provider, expiredAt, description)` → returns `job_id`
|
|
121
132
|
2. `registerJob(jobId)`
|
|
122
133
|
3. `setBudget(jobId, rawBudget)`
|
|
123
|
-
4. `fund(jobId, rawBudget, approveFloor=rawBudget)` — auto-approves U
|
|
134
|
+
4. `fund(jobId, rawBudget, approveFloor=rawBudget)` — auto-approves U only
|
|
135
|
+
when the positive budget needs allowance; budget 0 skips approval and escrow
|
|
124
136
|
|
|
125
137
|
Output prints 4 tx hashes + `job_id`. Note the `job_id` for later.
|
|
126
138
|
|
|
@@ -212,6 +224,10 @@ bag erc8183 status $JOB
|
|
|
212
224
|
bag erc8183 settle $JOB --action dispute
|
|
213
225
|
```
|
|
214
226
|
|
|
227
|
+
For the FREE regression, change the budget to `0` and confirm the compatible
|
|
228
|
+
contract job still reaches `FUNDED` and `SUBMITTED` without an ERC-20 approval
|
|
229
|
+
or balance change.
|
|
230
|
+
|
|
215
231
|
This is the exact end-to-end flow used to validate real-chain buying. See the
|
|
216
232
|
references below for the canonical picture.
|
|
217
233
|
|
|
@@ -27,11 +27,11 @@ directory (Claude Code: `~/.claude/skills/bnbagent-studio/references/`; Cursor:
|
|
|
27
27
|
the file when the topic comes up — don't answer from memory:
|
|
28
28
|
- `bnbagent-studio-use-aws-agentcore.md` — the delegated AgentCore lifecycle (`bag deploy --provider aws` / `status` / `logs` / `verify` / `destroy`, `provision-cognito`) + AWS prerequisites
|
|
29
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
30
|
- `bnbagent-studio-using-twak-wallet.md` — `[wallet].kind = "twak"` create / fund / SIWE-bind / container deploy / limitations
|
|
32
31
|
- `bnbagent-studio-extending-signing.md` — `PolicyViolation` / `X402PolicyError` diagnosis + extending the EIP-712 allowlist
|
|
33
32
|
- `bnbagent-studio-adding-to-project.md` — adding the seller runtime to an existing TypeScript project
|
|
34
33
|
- `bnbagent-studio-buying-via-8183.md` — buyer flow (find provider → buy → fetch → settle)
|
|
34
|
+
- `bnbagent-studio-selling-via-b402.md` — inbound x402 pricing mode, paid merchant setup, and B402 settlement operations
|
|
35
35
|
|
|
36
36
|
This playbook covers **generic ops**: dev / doctor / balances / RPC / incident triage.
|
|
37
37
|
For seller job-lifecycle decisions (settle / submit / dispute defense), read
|
|
@@ -49,12 +49,13 @@ For seller job-lifecycle decisions (settle / submit / dispute defense), read
|
|
|
49
49
|
| "how much have I approved 0x... for?" | ⚠️ **v0.2 backlog — `bag erc20 allowance` does not exist in v0.0.x** |
|
|
50
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
51
|
| "what's the status of job X?" | `bag erc8183 status <id>` (read-only — neutral) |
|
|
52
|
+
| "is `/x402` paid or free?" | `bag x402 sell status` (`Rail state: paid` probes B402 unless `--no-probe`; `free` skips B402) |
|
|
52
53
|
| "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
54
|
| "submit work for job X" | **seller action** — read `bnbagent-studio-selling-via-8183.md` (same directory) for the submit/dispute flow |
|
|
54
55
|
| "tx not confirming" | Read BscScan link from prior tx output + check `eth_getTransactionCount` |
|
|
55
56
|
| "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
|
|
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
|
|
57
|
+
| "is it deployed?" / "deploy status" | `bag deploy status` lists every locally recorded BNB/AWS deployment and asks `bnbagent-deploy` for live state; add `--no-probe` for record-only output |
|
|
58
|
+
| "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` in automation. Cloud calls always go through `bnbagent-deploy`. `bag platform credit` shows the BNB trial countdown. |
|
|
58
59
|
|
|
59
60
|
## Common ops procedures
|
|
60
61
|
|
|
@@ -158,6 +159,19 @@ The `--all` form is the right move when `app/agent/studio.toml`'s
|
|
|
158
159
|
testnet U pays ERC-8183 jobs, mainnet U pays the Pieverse LLM auto-renew.
|
|
159
160
|
Same wallet address on both chains.
|
|
160
161
|
|
|
162
|
+
`bag doctor` prints ERC-8183 pricing as `PAID` or `FREE`. FREE is not ready on
|
|
163
|
+
the canonical contract stack: select one zero-price-compatible custom stack
|
|
164
|
+
by setting `ERC8183_COMMERCE_ADDRESS`, `ERC8183_ROUTER_ADDRESS`, and
|
|
165
|
+
`ERC8183_POLICY_ADDRESS` together. A partial set fails because it can mix
|
|
166
|
+
incompatible commerce, router, and policy deployments.
|
|
167
|
+
|
|
168
|
+
For the inbound x402 seller rail, `bag doctor` also prints `PAID` or `FREE`.
|
|
169
|
+
PAID requires the complete B402 merchant credential set and an `evm-local` or
|
|
170
|
+
`twak` payout wallet. Explicit zero is anonymous FREE passthrough: it does not
|
|
171
|
+
read B402 credentials, call the facilitator, settle a payment, or apply the
|
|
172
|
+
paid-mode payout-wallet allowlist. Confirm the same state with
|
|
173
|
+
`bag x402 sell status`.
|
|
174
|
+
|
|
161
175
|
> ⚠️ **v0.2 backlog — not in v0.0.x.** There is **no** `bag wallet transfer`,
|
|
162
176
|
> no `bag erc20 approve/allowance` group, and no `bag wallet balance --address`
|
|
163
177
|
> / `--token` flag in v0.0.x — running any of them errors with
|
|
@@ -201,6 +215,10 @@ covered in `bnbagent-studio-selling-via-8183.md` (same directory).
|
|
|
201
215
|
| `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
216
|
| 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
217
|
| `ERC8183JobOps` has no such export from `@bnbagent/sdk` | package.json pinned an old `@bnbagent/sdk` (missing class) | Bump the dependency and reinstall |
|
|
218
|
+
| FREE price fails doctor/prepare on canonical contracts | `price = "0"` is selected without a zero-price-compatible stack | Set all three `ERC8183_*_ADDRESS` overrides from one compatible custom deployment, then rerun `bag doctor` and `bag deploy prepare` |
|
|
219
|
+
| ERC-8183 contract override is incomplete | Only one or two of commerce/router/policy were selected | Set or remove all three together; never mix stacks |
|
|
220
|
+
| `/x402` is public without a 402 challenge | `payments.x402_seller.price_usd = "0"` selected anonymous FREE passthrough | If payment is intended, set a positive decimal price, configure the complete B402 credential set, rerun `bag doctor`, and redeploy |
|
|
221
|
+
| B402 credentials are missing but x402 reports FREE | Expected: FREE bypasses B402 and does not synchronize its secrets | No credential fix is needed; change to a positive price only when the route should charge |
|
|
204
222
|
| `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
223
|
| RPC `limit exceeded` | Public RPC throttle | Retry, or set `STUDIO_BSC_TESTNET_RPC=<private rpc>` |
|
|
206
224
|
|
|
@@ -117,6 +117,8 @@ The fields (give the user all of them at once):
|
|
|
117
117
|
| 7 | **LLM model** | provider catalogue; for `pieverse-llm` the default `auto/free` runs at $0/token | `auto/free` |
|
|
118
118
|
| 8 | **Auto-topup** | `enable` / `disable` — lets the Agent auto-pay $U from the wallet when LLM credits run low | deferred (non-interactive `bag init` records no `[budget]`; enable later with `bag budget enable`) |
|
|
119
119
|
| 9 | **Scaffold destination** (`--destination`) | `self` (prepare the AgentCore scaffold for **your own** AWS account; runtime material stays under your cloud-account control) / `platform` (prepare for a 48h **testnet-only** trial on the BNB Chain managed platform — runs the *same* agent in the **operator's** AWS, so a wallet key **leaves your control**; it hard-forces `[network].default = bsc-testnet`, pins runtime=`agentcore`, packages an artifact, and auth is GitHub device flow. Use a **throwaway** `bag wallet new`, never your main wallet). This is scaffold intent only; deploy still explicitly selects `--provider`. | `platform` while the trial campaign runs (bare init falls back to `self` once it ends, or when `--network bsc-mainnet` / a non-agentcore `--runtime` is passed) |
|
|
120
|
+
| 10 | **ERC-8183 price** (`--erc8183-price`) | non-negative integer string in token base units; `0` explicitly selects FREE | `100000000000000000` (0.1 U) |
|
|
121
|
+
| 11 | **B402/x402 price** (`--b402-price`, when the b402 rail is selected) | non-negative decimal USD string; `0` explicitly selects anonymous FREE passthrough and bypasses B402 | `0.01` |
|
|
120
122
|
|
|
121
123
|
v1 is **seller-only** — there is no role to choose. `bag init` scaffolds the
|
|
122
124
|
single seller agent under `app/agent/` (serves the selected public faces,
|
|
@@ -215,7 +217,7 @@ Step 6b when `storage=ipfs`):
|
|
|
215
217
|
> keep steps 3/4/6 below. Pass `--no-onboard` to `bag init` to make this
|
|
216
218
|
> explicit and deterministic regardless of how the shell wires stdin.
|
|
217
219
|
|
|
218
|
-
1. `bag init <name> --llm-provider <p> --network <n> --storage-provider <s> --wallet-kind <k> --no-onboard`
|
|
220
|
+
1. `bag init <name> --llm-provider <p> --network <n> --storage-provider <s> --wallet-kind <k> --rails <8183|b402|both> [--erc8183-price <base-units>] [--b402-price <usd>] --no-onboard`
|
|
219
221
|
— scaffold the v0.0.1 workspace. **`<name>` must start with a letter and be
|
|
220
222
|
≤23 chars after sanitizing** — `bag init` auto-drops `-`/`_` for the
|
|
221
223
|
AgentCore name (printing what it used) but errors if the alphanumeric form
|
|
@@ -229,7 +231,16 @@ Step 6b when `storage=ipfs`):
|
|
|
229
231
|
faces (omit for A2A default; `--protocol <one>` is only a legacy alias), add
|
|
230
232
|
`--model <m>` only if the user overrode the provider default, and
|
|
231
233
|
`--enable-auto-topup` / `--no-auto-topup` only if they made an explicit
|
|
232
|
-
choice (otherwise omit — consent stays deferred).
|
|
234
|
+
choice (otherwise omit — consent stays deferred). Pass
|
|
235
|
+
`--erc8183-price 0` only when the user explicitly chose FREE; omitting the
|
|
236
|
+
flag preserves the paid 0.1 U default. FREE additionally requires all three
|
|
237
|
+
`ERC8183_COMMERCE_ADDRESS`, `ERC8183_ROUTER_ADDRESS`, and
|
|
238
|
+
`ERC8183_POLICY_ADDRESS` values from one zero-price-compatible custom
|
|
239
|
+
stack; set them with `bag env set` after scaffolding. For B402, pass
|
|
240
|
+
`--b402-price 0` only after the user explicitly accepts an unrestricted
|
|
241
|
+
anonymous FREE `/x402` endpoint. FREE bypasses B402 verify/settle and needs
|
|
242
|
+
no merchant credentials; a positive price keeps the `$0.01` default and
|
|
243
|
+
requires the paid onboarding playbook. **Destination:** while the
|
|
233
244
|
trial campaign runs, bare `bag init` (no `--destination`) defaults to
|
|
234
245
|
`platform` — so pass `--destination self` **explicitly** whenever the user
|
|
235
246
|
chose their own AWS, otherwise studio.toml silently records `platform` and the
|
|
@@ -344,7 +355,11 @@ Step 6b when `storage=ipfs`):
|
|
|
344
355
|
brand-new seller can scaffold, run `bag dev`, and deploy with an empty
|
|
345
356
|
wallet. `bag doctor` and `bag deploy` only **WARN** (never block) on zero
|
|
346
357
|
balance. Funding is needed later only for: a paid LLM model, on-chain
|
|
347
|
-
settle,
|
|
358
|
+
settle, paying positive-price ERC-8183 job buys, or buying/smoking a PAID
|
|
359
|
+
B402 request. A FREE ERC-8183 buy needs no U
|
|
360
|
+
escrow or ERC-20 approval, but still needs the ERC-8183 state-changing calls
|
|
361
|
+
and their gas/paymaster path. A FREE B402/x402 request needs neither token
|
|
362
|
+
funding nor a facilitator call. When funding is needed, the wallet uses
|
|
348
363
|
**TWO distinct U balances on TWO chains** (same wallet address, same private
|
|
349
364
|
key, different chains):
|
|
350
365
|
|