@bnbagent/studio-cli 0.0.6-alpha.4 → 0.0.6-alpha.6
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/README.md +26 -0
- package/dist/{_twak-5XQMOFUC.js → _twak-4XF4H5PL.js} +1 -1
- package/dist/bag.js +1450 -1116
- package/dist/{chunk-7RAKL4AS.js → chunk-RO726HJG.js} +12 -9
- package/dist/{chunk-A7NAGZHR.js → chunk-VEOOFDSF.js} +76 -17
- package/dist/{deployCli-264UE6KB.js → deployCli-EEK75T67.js} +4 -2
- package/package.json +4 -3
- package/recipes/agent/recipe.toml +1 -1
- package/recipes/runtimes/agentcore/recipe.toml +1 -1
- package/recipes/runtimes/azure-foundry/recipe.toml +1 -1
- package/recipes/x402-buyer/recipe.toml +1 -1
- package/skills/references/bnbagent-studio-buying-via-8183.md +13 -5
- package/skills/references/bnbagent-studio-extending-signing.md +4 -1
- package/skills/references/bnbagent-studio-operating.md +3 -2
- package/skills/references/bnbagent-studio-scaffolding-agent.md +16 -12
- package/skills/references/bnbagent-studio-selling-via-b402.md +94 -54
- package/skills/references/bnbagent-studio-use-aws-agentcore.md +5 -2
- package/skills/references/bnbagent-studio-using-altana-wallet.md +1 -1
- package/skills/references/bnbagent-studio-using-twak-wallet.md +18 -12
|
@@ -115,12 +115,13 @@ function twakDoubledHomeHint(walletFile) {
|
|
|
115
115
|
return `hint: the resolved wallet path ${walletFile} nests .twak/.twak \u2014 [wallet].twak_home in studio.toml likely points at the .twak directory itself. Set it to the PARENT directory (the runtime appends .twak/wallet.json) and re-run.`;
|
|
116
116
|
}
|
|
117
117
|
function twakCreateGuidance(fields) {
|
|
118
|
-
return `error: wallet.kind = "twak" \u2014 \`bag wallet new\`
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
(you choose the password; pick a strong one).
|
|
118
|
+
return `error: wallet.kind = "twak" \u2014 \`bag wallet new\` only adopts an existing
|
|
119
|
+
twak wallet's address. Create the wallet ONCE (you choose the password; pick a
|
|
120
|
+
strong one).
|
|
122
121
|
|
|
123
|
-
RECOMMENDED \u2014 let studio drive the create step
|
|
122
|
+
RECOMMENDED \u2014 let studio drive the create step so you never type the password
|
|
123
|
+
on a command line (twak requires --password on its own argv, so the value does
|
|
124
|
+
reach that short-lived child process):
|
|
124
125
|
|
|
125
126
|
bag wallet twak-init --password-stdin # CI: printf %s "$PW" | bag wallet twak-init --password-stdin
|
|
126
127
|
bag wallet twak-init --password-file <f> # file must be chmod 600
|
|
@@ -136,13 +137,15 @@ secret, then run \`twak setup\` (without them \`twak wallet create\` fails with
|
|
|
136
137
|
|
|
137
138
|
${fields.setupCmd}
|
|
138
139
|
|
|
139
|
-
then create the wallet \u2014 interactive (password on
|
|
140
|
-
and it lands in your shell history \u2014 acceptable for a throwaway hot
|
|
140
|
+
then create the wallet \u2014 interactive (you type the password on argv yourself;
|
|
141
|
+
twak warns, and it lands in your shell history \u2014 acceptable for a throwaway hot
|
|
142
|
+
wallet):
|
|
141
143
|
|
|
142
144
|
${fields.createCmd}
|
|
143
145
|
|
|
144
|
-
\u2014 or, to keep the password
|
|
145
|
-
environment and let \`twak setup\` create the wallet
|
|
146
|
+
\u2014 or, to keep the password out of your shell history (CI / scripts), pass it
|
|
147
|
+
via the environment and let \`twak setup\` create the wallet
|
|
148
|
+
non-interactively:
|
|
146
149
|
|
|
147
150
|
TWAK_NONINTERACTIVE=1 TWAK_SETUP_WALLET=create TWAK_WALLET_PASSWORD=<pw> ${fields.setupCmd}
|
|
148
151
|
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
runCaptureOut,
|
|
6
6
|
runStream,
|
|
7
7
|
whichTwak
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-RO726HJG.js";
|
|
9
9
|
|
|
10
10
|
// src/cli/_deploy/deployCli.ts
|
|
11
11
|
import * as fs4 from "fs";
|
|
@@ -296,6 +296,8 @@ function mb(n) {
|
|
|
296
296
|
// src/cli/_x402SellerConfig.ts
|
|
297
297
|
var DEFAULT_B402_PRICE_USD = "0.01";
|
|
298
298
|
var DEFAULT_B402_TESTNET_BASE_URL = "https://qacb.sdtaop.com";
|
|
299
|
+
var B402_DEVELOPER_ACCOUNT_URL = "https://developers.binance.com/en/docs/products/onchainpay-x402/basics/6.apply-developer-account";
|
|
300
|
+
var B402_PAID_ONBOARDING_GUIDANCE = `Create the agent wallet first, then apply for a separate B402 merchant for that exact wallet and environment; never reuse merchant credentials across wallets. Apply: ${B402_DEVELOPER_ACCOUNT_URL}`;
|
|
299
301
|
var PRICE_USD_RE = /^(?:0|[1-9]\d*)(?:\.\d+)?$/;
|
|
300
302
|
var ZERO_PRICE_USD_RE = /^0(?:\.0+)?$/;
|
|
301
303
|
function x402SellerPricingState(seller) {
|
|
@@ -687,7 +689,7 @@ function x402DeploySummary(root, destination, publicUrl) {
|
|
|
687
689
|
const seller = table3(table3(cfg.payments).x402_seller);
|
|
688
690
|
const pricing = x402SellerPricingState(seller);
|
|
689
691
|
const credentials = b402Credentials(agentRoot);
|
|
690
|
-
const activation =
|
|
692
|
+
const activation = `${B402_PAID_ONBOARDING_GUIDANCE} Then run the bnbagent-studio-selling-via-b402 skill, fill the four B402_* variables in .studio/.env.local, and redeploy.`;
|
|
691
693
|
const runtime = String(table3(cfg.stack).runtime ?? "agentcore");
|
|
692
694
|
if (destination !== "platform" && runtime !== "agentcore") {
|
|
693
695
|
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.`;
|
|
@@ -701,7 +703,9 @@ function x402DeploySummary(root, destination, publicUrl) {
|
|
|
701
703
|
"x402 rail is ACTIVE in FREE mode (self-hosted AgentCore).",
|
|
702
704
|
"B402 verify/settle is bypassed; no credentials, token payment, or settlement audit is used.",
|
|
703
705
|
"This target has no anonymous public URL; expose /x402 with your own HTTP front.",
|
|
704
|
-
'The front
|
|
706
|
+
'The front wraps each request as envelope-v1 JSON, {"v":1,"method":"POST","path":"/x402","headers":{...},"body":"<base64>"}, inside an authenticated AgentCore invocation. The default Bag self-deploy uses Cognito OAuth over HTTPS; IAM runtimes may use SDK/SigV4. Limits: 1 MiB request, 5 MiB response, no streaming.',
|
|
707
|
+
"You may invoke AgentCore with envelope-v1 directly, but that is not a standard public x402 HTTP endpoint.",
|
|
708
|
+
"Gateway example: https://github.com/bnb-chain/bnbagent-studio/blob/main/docs/guides/self-hosted-x402-gateway.md"
|
|
705
709
|
].join("\n");
|
|
706
710
|
}
|
|
707
711
|
const url2 = publicUrl ?? "<available after the platform agentId is assigned>";
|
|
@@ -715,16 +719,18 @@ function x402DeploySummary(root, destination, publicUrl) {
|
|
|
715
719
|
return `x402 rail is DORMANT. To activate: ${activation}`;
|
|
716
720
|
}
|
|
717
721
|
const settlement = [
|
|
718
|
-
"B402 settlement
|
|
719
|
-
"Settlement happens before work. If work later fails, the payment is retained and is not refunded automatically."
|
|
722
|
+
"B402 settlement can add significant latency; buyer timeout must be at least 120 s.",
|
|
723
|
+
"Settlement happens before work. If work later fails, the payment is retained and is not refunded automatically.",
|
|
724
|
+
"Compatibility note: current @bnb-chain/b402@0.1.0 makes one settle call and classifies an asynchronous pending response as outcome unknown; reconcile it and do not replay the paid request."
|
|
720
725
|
];
|
|
721
726
|
if (destination !== "platform") {
|
|
722
727
|
return [
|
|
723
728
|
"x402 rail is ACTIVE (self-hosted AgentCore).",
|
|
724
729
|
"This target has no anonymous public URL; expose /x402 with your own HTTP front.",
|
|
725
|
-
'The front
|
|
726
|
-
"
|
|
727
|
-
|
|
730
|
+
'The front wraps each request as envelope-v1 JSON, {"v":1,"method":"POST","path":"/x402","headers":{...},"body":"<base64>"}, inside an authenticated AgentCore invocation. The default Bag self-deploy uses Cognito OAuth over HTTPS; IAM runtimes may use SDK/SigV4. Limits: 1 MiB request, 5 MiB response, no streaming.',
|
|
731
|
+
"You may invoke AgentCore with envelope-v1 directly, but the caller must unpack the inner HTTP response and the result is not a standard public x402 endpoint.",
|
|
732
|
+
"PAID also needs fixed facilitator egress. Operate a restricted B402 Relay on a fixed-IP host such as a user-managed VPS, or use AgentCore VPC mode with a private subnet, NAT Gateway, and Elastic IP.",
|
|
733
|
+
"Gateway and Relay examples: https://github.com/bnb-chain/bnbagent-studio/blob/main/docs/guides/self-hosted-x402-gateway.md",
|
|
728
734
|
...settlement
|
|
729
735
|
].join("\n");
|
|
730
736
|
}
|
|
@@ -732,6 +738,8 @@ function x402DeploySummary(root, destination, publicUrl) {
|
|
|
732
738
|
return [
|
|
733
739
|
"x402 rail is ACTIVE.",
|
|
734
740
|
`Anonymous paid URL: ${url}`,
|
|
741
|
+
"The managed platform supplies the x402 HTTP Gateway and the fixed-egress B402 Relay; no user-managed gateway, proxy, or VPC is required.",
|
|
742
|
+
"Payment policy and RSA signing remain inside the AgentCore seller. The B402 Relay only forwards the signed request to its fixed facilitator upstream.",
|
|
735
743
|
...settlement
|
|
736
744
|
].join("\n");
|
|
737
745
|
}
|
|
@@ -996,28 +1004,76 @@ async function ensureRunnable(environment = process.env) {
|
|
|
996
1004
|
}
|
|
997
1005
|
return true;
|
|
998
1006
|
}
|
|
1007
|
+
var MODULE_MISSING_MARKER = "Cannot find module";
|
|
1008
|
+
var BUNX_TREE_HINT = [
|
|
1009
|
+
`error: ${DEPLOY_CLI_PACKAGE} could not load its own dependencies \u2014 its `,
|
|
1010
|
+
"bunx install directory is incomplete. Remove it and retry:\n",
|
|
1011
|
+
' rm -rf "${TMPDIR:-/tmp}"/bunx-*-@bnbagent\n',
|
|
1012
|
+
"If it persists, clear Bun's package cache (`bun pm cache rm`), or point ",
|
|
1013
|
+
"BNBAGENT_DEPLOY_COMMAND at a local checkout."
|
|
1014
|
+
].join("");
|
|
1015
|
+
function bunxInstallDir(environment = process.env) {
|
|
1016
|
+
if (deployCommand(environment)[0] !== "bunx") {
|
|
1017
|
+
return null;
|
|
1018
|
+
}
|
|
1019
|
+
const uid = typeof process.getuid === "function" ? process.getuid() : null;
|
|
1020
|
+
return uid === null ? null : path5.join(os.tmpdir(), `bunx-${uid}-${DEPLOY_CLI_PACKAGE}`);
|
|
1021
|
+
}
|
|
1022
|
+
async function bunxTreeIsIncomplete() {
|
|
1023
|
+
const [bin, ...prefix] = deployCommand();
|
|
1024
|
+
const probe = await runCapture(bin, [...prefix, "--help"], {
|
|
1025
|
+
timeoutMs: 12e4
|
|
1026
|
+
});
|
|
1027
|
+
return probe.code !== 0 && `${probe.stderr}
|
|
1028
|
+
${probe.stdout}`.includes(MODULE_MISSING_MARKER);
|
|
1029
|
+
}
|
|
1030
|
+
async function withBunxSelfHeal(hasFailed, attempt) {
|
|
1031
|
+
const first = await attempt();
|
|
1032
|
+
if (!hasFailed(first)) {
|
|
1033
|
+
return first;
|
|
1034
|
+
}
|
|
1035
|
+
const dir = bunxInstallDir();
|
|
1036
|
+
if (dir === null || !await bunxTreeIsIncomplete()) {
|
|
1037
|
+
return first;
|
|
1038
|
+
}
|
|
1039
|
+
if (!fs4.existsSync(dir)) {
|
|
1040
|
+
printErr(BUNX_TREE_HINT);
|
|
1041
|
+
return first;
|
|
1042
|
+
}
|
|
1043
|
+
printErr(
|
|
1044
|
+
`note: ${DEPLOY_CLI_PACKAGE} failed to load its dependencies; clearing its incomplete bunx install and retrying once (${dir}).`
|
|
1045
|
+
);
|
|
1046
|
+
fs4.rmSync(dir, { recursive: true, force: true });
|
|
1047
|
+
const second = await attempt();
|
|
1048
|
+
if (hasFailed(second)) {
|
|
1049
|
+
printErr(BUNX_TREE_HINT);
|
|
1050
|
+
}
|
|
1051
|
+
return second;
|
|
1052
|
+
}
|
|
999
1053
|
async function runDeployCliStream(argv, opts = {}) {
|
|
1000
1054
|
if (!await ensureRunnable()) {
|
|
1001
1055
|
return 127;
|
|
1002
1056
|
}
|
|
1003
1057
|
const [bin, ...prefix] = deployCommand();
|
|
1004
|
-
return
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1058
|
+
return withBunxSelfHeal(
|
|
1059
|
+
(code) => code !== 0,
|
|
1060
|
+
() => runStream(bin, [...prefix, ...argv], {
|
|
1061
|
+
cwd: opts.cwd,
|
|
1062
|
+
env: opts.env ? { ...process.env, ...opts.env } : void 0
|
|
1063
|
+
})
|
|
1064
|
+
);
|
|
1008
1065
|
}
|
|
1009
1066
|
async function runDeployCliJson(argv, opts = {}) {
|
|
1010
1067
|
if (!await ensureRunnable()) {
|
|
1011
1068
|
return { code: 127, data: {} };
|
|
1012
1069
|
}
|
|
1013
1070
|
const [bin, ...prefix] = deployCommand();
|
|
1014
|
-
const { code, stdout } = await
|
|
1015
|
-
|
|
1016
|
-
[...prefix, ...argv, "--json"],
|
|
1017
|
-
{
|
|
1071
|
+
const { code, stdout } = await withBunxSelfHeal(
|
|
1072
|
+
(result) => result.code !== 0,
|
|
1073
|
+
() => runCaptureOut(bin, [...prefix, ...argv, "--json"], {
|
|
1018
1074
|
cwd: opts.cwd,
|
|
1019
1075
|
env: opts.env ? { ...process.env, ...opts.env } : void 0
|
|
1020
|
-
}
|
|
1076
|
+
})
|
|
1021
1077
|
);
|
|
1022
1078
|
let data = {};
|
|
1023
1079
|
const trimmed = stdout.trim();
|
|
@@ -1093,6 +1149,8 @@ export {
|
|
|
1093
1149
|
recipeModeOf,
|
|
1094
1150
|
DEFAULT_B402_PRICE_USD,
|
|
1095
1151
|
DEFAULT_B402_TESTNET_BASE_URL,
|
|
1152
|
+
B402_DEVELOPER_ACCOUNT_URL,
|
|
1153
|
+
B402_PAID_ONBOARDING_GUIDANCE,
|
|
1096
1154
|
x402SellerPricingState,
|
|
1097
1155
|
normalizeB402PriceUsd,
|
|
1098
1156
|
isB402TestnetBaseUrl,
|
|
@@ -1124,6 +1182,7 @@ export {
|
|
|
1124
1182
|
buildDeploySpec,
|
|
1125
1183
|
renderSecretEnvFile,
|
|
1126
1184
|
withDeployFiles,
|
|
1185
|
+
bunxInstallDir,
|
|
1127
1186
|
runDeployCliStream,
|
|
1128
1187
|
runDeployCliJson,
|
|
1129
1188
|
trialFromDeployCliJson,
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
bnbEnv,
|
|
9
9
|
bnbPlatformApiUrl,
|
|
10
10
|
buildDeploySpec,
|
|
11
|
+
bunxInstallDir,
|
|
11
12
|
deployCommand,
|
|
12
13
|
deployEndpointValue,
|
|
13
14
|
providerPassthrough,
|
|
@@ -17,8 +18,8 @@ import {
|
|
|
17
18
|
runPlatformAccountCommand,
|
|
18
19
|
trialFromDeployCliJson,
|
|
19
20
|
withDeployFiles
|
|
20
|
-
} from "./chunk-
|
|
21
|
-
import "./chunk-
|
|
21
|
+
} from "./chunk-VEOOFDSF.js";
|
|
22
|
+
import "./chunk-RO726HJG.js";
|
|
22
23
|
export {
|
|
23
24
|
BNB_PLATFORM_API_URL,
|
|
24
25
|
BNB_PLATFORM_API_URL_ENV,
|
|
@@ -28,6 +29,7 @@ export {
|
|
|
28
29
|
bnbEnv,
|
|
29
30
|
bnbPlatformApiUrl,
|
|
30
31
|
buildDeploySpec,
|
|
32
|
+
bunxInstallDir,
|
|
31
33
|
deployCommand,
|
|
32
34
|
deployEndpointValue,
|
|
33
35
|
providerPassthrough,
|
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.6",
|
|
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": {
|
|
@@ -19,13 +19,14 @@
|
|
|
19
19
|
"dist",
|
|
20
20
|
"skills",
|
|
21
21
|
"recipes",
|
|
22
|
+
"README.md",
|
|
22
23
|
"DISCLAIMER.md"
|
|
23
24
|
],
|
|
24
25
|
"bin": {
|
|
25
26
|
"bag": "./dist/bag.js"
|
|
26
27
|
},
|
|
27
28
|
"dependencies": {
|
|
28
|
-
"@bnbagent/sdk": "0.5.0-alpha.
|
|
29
|
+
"@bnbagent/sdk": "0.5.0-alpha.3",
|
|
29
30
|
"ai": "^7.0.29",
|
|
30
31
|
"archiver": "^8.0.0",
|
|
31
32
|
"commander": "^15.0.0",
|
|
@@ -37,7 +38,7 @@
|
|
|
37
38
|
"tar": "^7.4.0",
|
|
38
39
|
"viem": "^2.54.0",
|
|
39
40
|
"yaml": "^2.9.0",
|
|
40
|
-
"@bnbagent/studio-runtime": "0.0.6-alpha.
|
|
41
|
+
"@bnbagent/studio-runtime": "0.0.6-alpha.6"
|
|
41
42
|
},
|
|
42
43
|
"devDependencies": {
|
|
43
44
|
"@a2a-js/sdk": "^0.3.14",
|
|
@@ -11,7 +11,7 @@ node = [
|
|
|
11
11
|
# neutral. The agent project's serving deps (@a2a-js/sdk / MCP SDK / ai)
|
|
12
12
|
# come from the runtimes/<R>/ recipe selected at `bag init` time.
|
|
13
13
|
"@bnbagent/studio-runtime",
|
|
14
|
-
"@bnbagent/sdk@0.5.0-alpha.
|
|
14
|
+
"@bnbagent/sdk@0.5.0-alpha.3",
|
|
15
15
|
]
|
|
16
16
|
|
|
17
17
|
[env]
|
|
@@ -32,7 +32,7 @@ node = [
|
|
|
32
32
|
# BNBAGENT_RUNTIME_SECRET_ID is set (default secretsmanager mode + platform).
|
|
33
33
|
"@aws-sdk/client-secrets-manager@^3.600.0",
|
|
34
34
|
"@bnbagent/studio-runtime",
|
|
35
|
-
"@bnbagent/sdk@0.5.0-alpha.
|
|
35
|
+
"@bnbagent/sdk@0.5.0-alpha.3",
|
|
36
36
|
# The LLM work hook (generateText + tools) and the model factory.
|
|
37
37
|
"ai@^7.0.29",
|
|
38
38
|
# Tool input schemas (AI SDK tools + MCP registerTool).
|
|
@@ -19,7 +19,7 @@ status = "v1"
|
|
|
19
19
|
[dependencies]
|
|
20
20
|
node = [
|
|
21
21
|
"@bnbagent/studio-runtime",
|
|
22
|
-
"@bnbagent/sdk@0.5.0-alpha.
|
|
22
|
+
"@bnbagent/sdk@0.5.0-alpha.3",
|
|
23
23
|
# The LLM work hook (generateText + tools) and the model factory; the
|
|
24
24
|
# Foundry host's OpenAI-compatible client comes from @ai-sdk/openai
|
|
25
25
|
# (built from the BNBAGENT_LLM_* env the deploy injects).
|
|
@@ -59,14 +59,22 @@ flow now auto-adds dispute_window).
|
|
|
59
59
|
- For a paid job, the wallet has ≥ 0.05 tBNB (gas) and enough U for the budget
|
|
60
60
|
plus slack. On BSC testnet the
|
|
61
61
|
ERC-8183 kernel writes (`createJob` / `fund` deposit / `settle` …) are
|
|
62
|
-
gas-sponsored via the SDK's MegaFuel paymaster
|
|
62
|
+
gas-sponsored via the SDK's MegaFuel paymaster **when they target the
|
|
63
|
+
canonical contracts**, so you spend far less tBNB than
|
|
63
64
|
that — but **not zero**: `fund` sends an ERC-20 `approve` (a token call, not
|
|
64
65
|
sponsored) when the token allowance is too low — typically just the first fund,
|
|
65
66
|
since studio approves a floored cap that later jobs reuse. Keep a little tBNB for
|
|
66
|
-
it. (Mainnet is never sponsored.)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
it. (Mainnet is never sponsored.) Sponsorship is granted per target contract
|
|
68
|
+
by the paymaster policy: a custom/QA stack selected via the
|
|
69
|
+
`ERC8183_*_ADDRESS` overrides is normally **not** covered, so every write
|
|
70
|
+
self-pays gas (the SDK logs `… is not sponsorable on this network;
|
|
71
|
+
self-paying gas` and falls back automatically) — keep tBNB for the whole
|
|
72
|
+
flow, or set `BNBAGENT_USE_PAYMASTER=0` to skip the per-transaction
|
|
73
|
+
sponsorship probe and self-pay directly. For a FREE job, use `--budget-u 0`:
|
|
74
|
+
no U balance, ERC-20 approval, or token escrow is needed, but the ERC-8183
|
|
75
|
+
writes still need the selected gas/paymaster path and a zero-price-compatible
|
|
76
|
+
commerce/router/policy stack — today that means a custom stack, so expect the
|
|
77
|
+
writes to self-pay gas as above.
|
|
70
78
|
- You know the **provider's wallet address** (the seller agent's address)
|
|
71
79
|
- The seller is **reachable** (its A2A agent is deployed somewhere); discoverable
|
|
72
80
|
via the provider's `bag erc8004 resolve <agent_id>` endpoint URI
|
|
@@ -222,6 +222,9 @@ When deeper protocol details are needed:
|
|
|
222
222
|
|
|
223
223
|
- Never bypass the policy with `_DANGEROUS_*` calls in agent code. They exist for tests and incident response.
|
|
224
224
|
- Never instruct the user to widen caps / allowlists "to make it work" without explaining the security tradeoff.
|
|
225
|
-
-
|
|
225
|
+
- Persist the wallet password only in the generated, gitignored, owner-only
|
|
226
|
+
`.studio/.env.local` for local use or a managed secret channel for deploys;
|
|
227
|
+
never put it in argv, application code, logs, or chat.
|
|
228
|
+
- Never persist signed payloads outside the keystore.
|
|
226
229
|
- Always run `bag wallet policy show` after editing `[wallet.signing]` to confirm the change took effect.
|
|
227
230
|
- Always restart the process — SigningPolicy is captured at wallet construction.
|
|
@@ -64,7 +64,8 @@ For seller job-lifecycle decisions (settle / submit / dispute defense), read
|
|
|
64
64
|
```bash
|
|
65
65
|
# Configure secrets (idempotent — does NOT duplicate existing keys).
|
|
66
66
|
# These write into .studio/.env.local (the Agent's secrets):
|
|
67
|
-
|
|
67
|
+
# Edit .studio/.env.local and set WALLET_PASSWORD there; bag auto-loads it.
|
|
68
|
+
# Never put the wallet password on a command line.
|
|
68
69
|
bag env set OPENROUTER_API_KEY <your key> # or whichever provider app/agent/studio.toml [llm] uses
|
|
69
70
|
|
|
70
71
|
# From the workspace root — `bag dev` serves the selected protocol:
|
|
@@ -129,7 +130,7 @@ Returns a rich table of checks across the `app/agent/` sub-project:
|
|
|
129
130
|
| app/agent/studio.toml parseable | Missing or syntax error | `bag init` to regenerate, or hand-fix TOML |
|
|
130
131
|
| 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) |
|
|
131
132
|
| wallet keystore | No `<workspace>/.studio/wallets/*.json` | `bag wallet new` (writes to the workspace root keystore dir) |
|
|
132
|
-
| WALLET_PASSWORD env | Not in `.studio/.env.local` / not exported |
|
|
133
|
+
| WALLET_PASSWORD env | Not in `.studio/.env.local` / not exported | Edit the owner-only `.studio/.env.local`; never pass the password on argv |
|
|
133
134
|
| LLM provider key | API key env not set | Edit `.studio/.env.local` or export the right `*_API_KEY` |
|
|
134
135
|
| 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` |
|
|
135
136
|
| Wallet tBNB balance | 0 tBNB | Faucet: testnet.bnbchain.org/faucet-smart |
|
|
@@ -309,10 +309,10 @@ Step 6b when `storage=ipfs`):
|
|
|
309
309
|
- **twak** (fully supported — opt in with `--wallet-kind twak`): `bag init` writes `[wallet].twak_home =
|
|
310
310
|
"../../.studio/twak"` — a **project-dedicated** wallet isolated from your
|
|
311
311
|
main `~/.twak`, so a deploy never pushes the main wallet's key material to
|
|
312
|
-
Secrets Manager.
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
312
|
+
Secrets Manager. Setting it up is a ONE-TIME job: the user runs the
|
|
313
|
+
interactive 3-step `twak setup` wizard themselves in their own terminal,
|
|
314
|
+
then `bag wallet twak-init` creates the wallet (so the password never goes
|
|
315
|
+
into a command line). Start with the wizard:
|
|
316
316
|
```bash
|
|
317
317
|
HOME=<workspace>/.studio/twak twak setup
|
|
318
318
|
```
|
|
@@ -332,17 +332,21 @@ Step 6b when `storage=ipfs`):
|
|
|
332
332
|
WalletConnect` = your main wallet.)
|
|
333
333
|
|
|
334
334
|
```bash
|
|
335
|
-
|
|
335
|
+
cd app/agent && bag wallet twak-init # hidden prompt
|
|
336
|
+
printf %s "$PW" | bag wallet twak-init --password-stdin # CI / scripts
|
|
336
337
|
```
|
|
337
338
|
Use UPPER + lower + digit; put that same password in `.studio/.env.local`
|
|
338
|
-
as `TWAK_WALLET_PASSWORD`. `--no-keychain
|
|
339
|
-
keychain (no macOS prompt); studio unlocks via
|
|
340
|
-
macOS prompt *loops
|
|
341
|
-
then re-run with `--no-keychain`.)
|
|
339
|
+
as `TWAK_WALLET_PASSWORD`. `twak-init` passes `--no-keychain`, which keeps
|
|
340
|
+
the password out of the OS keychain (no macOS prompt); studio unlocks via
|
|
341
|
+
the env. (If a macOS prompt *loops* on a manual `twak` run, do NOT "Reset
|
|
342
|
+
Default Keychain" — `pkill -9 -f twak`, then re-run with `--no-keychain`.)
|
|
343
|
+
It also adopts the address into `studio.toml` and echoes it — confirm it's
|
|
344
|
+
the intended wallet before funding/deploy, and there is no separate
|
|
345
|
+
`bag wallet new` step. The manual equivalent is
|
|
346
|
+
`HOME=<workspace>/.studio/twak twak wallet create --password <StrongPw> --no-keychain`
|
|
347
|
+
followed by `bag wallet new`. Full detail: the
|
|
342
348
|
`bnbagent-studio-using-twak-wallet.md` reference (in the router skill's `references/` directory).
|
|
343
|
-
|
|
344
|
-
`studio.toml` (and echoes it — confirm it's the intended wallet before
|
|
345
|
-
funding/deploy). To reuse an EXISTING wallet across agents, scaffold with
|
|
349
|
+
To reuse an EXISTING wallet across agents, scaffold with
|
|
346
350
|
`bag init --twak-home <path-to-its-home>` instead. Reusing your main
|
|
347
351
|
`~/.twak` is opt-in only (`--twak-home ~`) and discouraged. Full detail:
|
|
348
352
|
the `bnbagent-studio-using-twak-wallet.md` reference (in the router skill's `references/` directory).
|