@bnbagent/studio-cli 0.0.12-alpha.6 → 0.0.12

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 CHANGED
@@ -52,7 +52,7 @@ import {
52
52
  x402SellerIsFree,
53
53
  x402SellerPricingState,
54
54
  x402SellerUsesB402
55
- } from "./chunk-JONVYGUR.js";
55
+ } from "./chunk-RNWAADXU.js";
56
56
  import {
57
57
  TWAK_CLI_MIN_VERSION,
58
58
  TWAK_CLI_VERSION,
@@ -230,7 +230,7 @@ import {
230
230
  var CAMPAIGN_DOC_URL = "https://www.bnbchain.org/en/blog/bnb-agent-studio-is-live-on-bnb-chain-ai-agents-from-one-prompt";
231
231
  var CAMPAIGN_CHECK_TIMEOUT_MS = 6e3;
232
232
  async function fetchCampaignActive() {
233
- const { bnbPlatformApiUrl: bnbPlatformApiUrl2 } = await import("./deployCli-6T6OMOIZ.js");
233
+ const { bnbPlatformApiUrl: bnbPlatformApiUrl2 } = await import("./deployCli-RWRR6XWO.js");
234
234
  const controller = new AbortController();
235
235
  const timer = setTimeout(() => controller.abort(), CAMPAIGN_CHECK_TIMEOUT_MS);
236
236
  try {
@@ -2823,19 +2823,6 @@ var ERC20_BALANCE_ABI = [
2823
2823
  outputs: [{ name: "", type: "uint256" }]
2824
2824
  }
2825
2825
  ];
2826
- var ERC20_ALLOWANCE_ABI = [
2827
- {
2828
- type: "function",
2829
- name: "allowance",
2830
- stateMutability: "view",
2831
- inputs: [
2832
- { name: "owner", type: "address" },
2833
- { name: "spender", type: "address" }
2834
- ],
2835
- outputs: [{ name: "", type: "uint256" }]
2836
- }
2837
- ];
2838
- var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
2839
2826
  function client(networkName) {
2840
2827
  const net2 = getNetwork(networkName);
2841
2828
  return createPublicClient({ transport: http(net2.rpcUrl) });
@@ -2864,20 +2851,6 @@ async function readUBalanceRaw(address, networkName) {
2864
2851
  });
2865
2852
  return raw;
2866
2853
  }
2867
- async function readUAllowanceRaw(owner, spender, networkName) {
2868
- const net2 = getNetwork(networkName);
2869
- const uToken = net2.tokens.U;
2870
- if (uToken === void 0) {
2871
- return null;
2872
- }
2873
- const raw = await client(networkName).readContract({
2874
- address: getAddress(uToken.address),
2875
- abi: ERC20_ALLOWANCE_ABI,
2876
- functionName: "allowance",
2877
- args: [getAddress(owner), getAddress(spender)]
2878
- });
2879
- return raw;
2880
- }
2881
2854
  async function readTransactionSeen(txHash, networkName) {
2882
2855
  try {
2883
2856
  await client(networkName).getTransaction({
@@ -2964,7 +2937,7 @@ function canBuildWallet(root, data) {
2964
2937
  const cfg = data ?? loadAgentToml(root);
2965
2938
  const walletCfg = tableOf2(cfg, "wallet");
2966
2939
  const kind = walletCfg.kind;
2967
- if (kind === "twak" || kind === "altana" || kind === "turnkey") {
2940
+ if (kind === "twak" || kind === "altana") {
2968
2941
  return false;
2969
2942
  }
2970
2943
  if (!process.env.WALLET_PASSWORD) {
@@ -2982,7 +2955,7 @@ function canBuildWallet(root, data) {
2982
2955
  function walletAddressForChecks(root, data) {
2983
2956
  const cfg = data ?? loadAgentToml(root);
2984
2957
  const walletCfg = tableOf2(cfg, "wallet");
2985
- if (walletCfg.kind === "twak" || walletCfg.kind === "altana" || walletCfg.kind === "turnkey") {
2958
+ if (walletCfg.kind === "twak" || walletCfg.kind === "altana") {
2986
2959
  const addr = String(walletCfg.address ?? "").trim();
2987
2960
  return addr || null;
2988
2961
  }
@@ -3756,7 +3729,7 @@ function checkAltanaSdkResolvable(root, _target) {
3756
3729
  level: Level.CRITICAL,
3757
3730
  name: "altana_sdk_resolvable",
3758
3731
  message: `@altananetwork/sdk is not resolvable from the agent project${failure ? ` (${failure})` : ""} \u2014 the deployed runtime cannot build the Altana session wallet at cold start.`,
3759
- fixCmd: "pnpm add @altananetwork/sdk@0.7.1",
3732
+ fixCmd: "pnpm add @altananetwork/sdk@0.5.1",
3760
3733
  details: failure ? { error: failure } : {}
3761
3734
  }
3762
3735
  ];
@@ -4735,28 +4708,6 @@ var managedAzureFoundryChecks = [
4735
4708
  checkAltanaSessionNotInsideAgent
4736
4709
  ];
4737
4710
 
4738
- // src/cli/_turnkeyGuidance.ts
4739
- function turnkeySetupGuidance() {
4740
- return `
4741
- Turnkey setup (official CLI: https://docs.turnkey.com/sdks/cli):
4742
- 1. In the dashboard's top-right user menu, copy the Organization ID into
4743
- TURNKEY_ORG_ID.
4744
- 2. Generate a P-256 API key locally, then register its public key under
4745
- User Details -> Create API keys:
4746
- turnkey generate api-key --organization "$TURNKEY_ORG_ID" --key-name bnbagent-studio
4747
- Set TURNKEY_API_PUBLIC_KEY to the generated public key and
4748
- TURNKEY_API_PRIVATE_KEY to its locally generated private key. Keep the
4749
- private key out of argv, logs, and source control.
4750
- 3. Create a wallet and an Ethereum account:
4751
- turnkey wallets create --name bnbagent-studio --key-name bnbagent-studio
4752
- turnkey wallets accounts create --wallet bnbagent-studio --address-format ADDRESS_FORMAT_ETHEREUM --key-name bnbagent-studio
4753
- 4. Set TURNKEY_SIGN_WITH to the returned 0x Ethereum account address. It is
4754
- not a Turnkey wallet id (UUID).
4755
- 5. Store all four TURNKEY_* values in the owner-only .studio/.env.local,
4756
- then run \`(cd app/agent && bag wallet new)\` to validate and anchor the
4757
- address. No signing key is created or downloaded by bag.`;
4758
- }
4759
-
4760
4711
  // src/cli/llm.ts
4761
4712
  import * as fs18 from "fs";
4762
4713
  import * as path17 from "path";
@@ -6636,7 +6587,6 @@ import {
6636
6587
  } from "@bnbagent/studio-runtime/config";
6637
6588
  import { tbnbFaucetHint as tbnbFaucetHint2 } from "@bnbagent/studio-runtime/networks";
6638
6589
  import { buildPolicy, buildWallet } from "@bnbagent/studio-runtime/wallet";
6639
- import { getAddress as toChecksumAddress } from "viem";
6640
6590
 
6641
6591
  // src/cli/walletSession.ts
6642
6592
  import * as fs21 from "fs";
@@ -7368,9 +7318,6 @@ async function cmdNew(opts) {
7368
7318
  if (kind === "twak") {
7369
7319
  return cmdNewTwak(projectRoot, walletCfg);
7370
7320
  }
7371
- if (kind === "turnkey") {
7372
- return cmdNewTurnkey(projectRoot);
7373
- }
7374
7321
  const privateKey = await resolvePrivateKeyArg(opts.privateKey);
7375
7322
  const password = requireDurablePassword(projectRoot);
7376
7323
  const keystoreDir = resolveKeystoreDir2(
@@ -7434,28 +7381,6 @@ Install it (Node >=22): npm install -g @trustwallet/cli@${TWAK_CLI_VERSION}`
7434
7381
  printNextAfterNew(projectRoot, address);
7435
7382
  return 0;
7436
7383
  }
7437
- function cmdNewTurnkey(projectRoot) {
7438
- const signWith = String(process.env.TURNKEY_SIGN_WITH ?? "").trim();
7439
- if (signWith === "") {
7440
- printErr(
7441
- `error: TURNKEY_SIGN_WITH is not set (wallet.kind = 'turnkey').
7442
- ${turnkeySetupGuidance()}`
7443
- );
7444
- return 1;
7445
- }
7446
- let address;
7447
- try {
7448
- address = toChecksumAddress(signWith);
7449
- } catch {
7450
- printErr(
7451
- `error: TURNKEY_SIGN_WITH must be the wallet account's Ethereum address (0x + 40 hex chars), not a Turnkey wallet id \u2014 copy it from the dashboard wallet-account view. Got: '${signWith}'`
7452
- );
7453
- return 1;
7454
- }
7455
- printOut(address);
7456
- persistAddress(projectRoot, address);
7457
- return 0;
7458
- }
7459
7384
  function ensureTwakCredentials(walletFile, homeDir) {
7460
7385
  const twakDir = path21.dirname(walletFile);
7461
7386
  const target = path21.join(twakDir, "credentials.json");
@@ -7633,33 +7558,6 @@ function cmdShow5(projectRootArg2) {
7633
7558
  );
7634
7559
  return 0;
7635
7560
  }
7636
- if (kind === "turnkey") {
7637
- const anchored = String(walletCfg.address ?? "").trim();
7638
- const signWith = String(process.env.TURNKEY_SIGN_WITH ?? "").trim();
7639
- const address2 = anchored || signWith;
7640
- if (!address2) {
7641
- throw new Error(
7642
- "cannot resolve the Turnkey wallet address: no [wallet].address is anchored in studio.toml and TURNKEY_SIGN_WITH is not set \u2014 fill .studio/.env.local, then run `bag wallet new`."
7643
- );
7644
- }
7645
- const requiredEnv = [
7646
- "TURNKEY_API_PUBLIC_KEY",
7647
- "TURNKEY_API_PRIVATE_KEY",
7648
- "TURNKEY_ORG_ID",
7649
- "TURNKEY_SIGN_WITH"
7650
- ];
7651
- const present = requiredEnv.filter((key) => process.env[key]).length;
7652
- const baseUrl = process.env.TURNKEY_API_BASE_URL || "https://api.turnkey.com";
7653
- printOut(`address: ${address2}`);
7654
- printOut("source: turnkey");
7655
- printOut(
7656
- `key_location: remote:turnkey (${baseUrl}; key held in AWS Nitro enclave, never leaves)`
7657
- );
7658
- printOut(
7659
- `credentials: ${present}/${requiredEnv.length} TURNKEY_* env vars set`
7660
- );
7661
- return 0;
7662
- }
7663
7561
  const password = requirePassword2();
7664
7562
  const keystoreDir = resolveKeystoreDir2(projectRoot, null, walletCfg);
7665
7563
  const provider = new EVMWalletProvider({
@@ -7752,14 +7650,7 @@ async function cmdSign(msg, projectRootArg2) {
7752
7650
  );
7753
7651
  }
7754
7652
  let provider;
7755
- if (kind === "turnkey") {
7756
- printErr(
7757
- "note: Turnkey signatures are billed (free tier 25/month at 1 req/s; pay-as-you-go $0.10 each)."
7758
- );
7759
- provider = buildWallet(walletCfg, projectRoot, {
7760
- network: projectNetwork(projectRoot)
7761
- });
7762
- } else if (kind === "twak") {
7653
+ if (kind === "twak") {
7763
7654
  provider = twakProvider(projectRoot, walletCfg);
7764
7655
  } else {
7765
7656
  const password = requirePassword2();
@@ -7784,10 +7675,10 @@ async function cmdBalance(opts) {
7784
7675
  const walletCfg = data.wallet !== null && typeof data.wallet === "object" ? data.wallet : {};
7785
7676
  let address;
7786
7677
  const kind = walletKind(walletCfg);
7787
- if (kind === "twak" || kind === "altana" || kind === "turnkey") {
7678
+ if (kind === "twak" || kind === "altana") {
7788
7679
  address = String(walletCfg.address ?? "").trim();
7789
7680
  if (!address) {
7790
- const nextStep = kind === "twak" ? "(adopts the twak wallet's address) first." : kind === "turnkey" ? "(set TURNKEY_SIGN_WITH in .studio/.env.local first \u2014 `bag wallet new` adopts it)." : "to create the Altana admin keystore first.";
7681
+ const nextStep = kind === "twak" ? "(adopts the twak wallet's address) first." : "to create the Altana admin keystore first.";
7791
7682
  throw new Error(
7792
7683
  `no [wallet].address anchored in studio.toml \u2014 run bag wallet new ${nextStep}`
7793
7684
  );
@@ -8153,7 +8044,7 @@ function registerInit(program) {
8153
8044
  ).addOption(
8154
8045
  new Option2(
8155
8046
  "--rails <rails>",
8156
- "Commerce rail(s) to scaffold: 8183, b402, or both (default)."
8047
+ "Commerce rail(s) to scaffold: 8183, b402, or both (default; Altana defaults to 8183)."
8157
8048
  ).choices(["8183", "b402", "both"])
8158
8049
  ).option(
8159
8050
  "--erc8183-price <base-units>",
@@ -8177,8 +8068,8 @@ function registerInit(program) {
8177
8068
  ).addOption(
8178
8069
  new Option2(
8179
8070
  "--wallet-kind <kind>",
8180
- "Wallet backend for the Agent (default: evm-local = encrypted local keystore at the workspace root .studio/wallets/; CodeZip deploy). altana \u2014 encrypted local admin keystore plus a bounded runtime session; deploys ship ONLY the session (ALTANA_SESSION secret). twak \u2014 FULLY SUPPORTED, opt in: Trust Wallet Agent Kit CLI, self-custody encrypted mnemonic in a PROJECT-DEDICATED home (.studio/twak); deploys as a container image. turnkey \u2014 remote signer: the key lives in Turnkey's AWS Nitro enclave and the Agent signs via TURNKEY_* API credentials; CodeZip deploy; every successful signature is billed."
8181
- ).choices(["twak", "evm-local", "altana", "turnkey"])
8071
+ "Wallet backend for the Agent (default: evm-local = encrypted local keystore at the workspace root .studio/wallets/; CodeZip deploy). altana \u2014 encrypted local admin keystore plus a bounded runtime session; deploys ship ONLY the session (ALTANA_SESSION secret). twak \u2014 FULLY SUPPORTED, opt in: Trust Wallet Agent Kit CLI, self-custody encrypted mnemonic in a PROJECT-DEDICATED home (.studio/twak); deploys as a container image."
8072
+ ).choices(["twak", "evm-local", "altana"])
8182
8073
  ).option(
8183
8074
  "--twak-home <path>",
8184
8075
  "twak only: point this project at an EXISTING twak wallet home (the HOME-STYLE PARENT dir that contains .twak/wallet.json \u2014 NOT the .twak dir itself; a .twak path holding a wallet is auto-corrected to its parent) instead of the dedicated .studio/twak. Written to [wallet].twak_home."
@@ -8346,7 +8237,7 @@ async function cmdInitFlow(nameArg, opts) {
8346
8237
  if (llmProvider === null) {
8347
8238
  return 2;
8348
8239
  }
8349
- const inferredRails = opts.rails ?? (facesExplicit ? hasX402Face(faces) ? "both" : "8183" : void 0);
8240
+ const inferredRails = opts.rails ?? (facesExplicit ? hasX402Face(faces) ? "both" : "8183" : walletKind2 === "altana" ? "8183" : void 0);
8350
8241
  let rails = await resolveRails(inferredRails, isTty);
8351
8242
  if (!facesExplicit) {
8352
8243
  faces = normalizeProtocolFaces(
@@ -8490,10 +8381,10 @@ async function cmdInitFlow(nameArg, opts) {
8490
8381
  return 1;
8491
8382
  }
8492
8383
  const budgetFlag = opts.enableAutoTopup ? "enable" : opts.autoTopup === false ? "disable" : null;
8493
- const budgetChoice = walletKind2 === "altana" && llmProvider !== "pieverse-llm" && budgetFlag === null ? null : await resolveBudgetChoice(budgetFlag);
8494
- if ((rails === "b402" || rails === "both") && x402SellerPricingState({ price_usd: b402Price }).kind === "paid" && !["evm-local", "twak", "turnkey", "altana"].includes(walletKind2)) {
8384
+ const budgetChoice = llmProvider === "pieverse-llm" || budgetFlag !== null ? await resolveBudgetChoice(budgetFlag) : null;
8385
+ if ((rails === "b402" || rails === "both") && x402SellerPricingState({ price_usd: b402Price }).kind === "paid" && !["evm-local", "twak"].includes(walletKind2)) {
8495
8386
  printErr(
8496
- `error: the b402 seller rail supports wallet.kind evm-local, twak, turnkey or altana only; '${walletKind2}' cannot act as the b402 payout wallet. Re-run with --rails 8183 or a supported --wallet-kind.`
8387
+ `error: the b402 seller rail supports wallet.kind evm-local or twak only; '${walletKind2}' cannot act as the b402 payout wallet. Re-run with --rails 8183 or a supported --wallet-kind.`
8497
8388
  );
8498
8389
  fs23.rmSync(target, { recursive: true, force: true });
8499
8390
  return 2;
@@ -8590,8 +8481,6 @@ async function cmdInitFlow(nameArg, opts) {
8590
8481
  }
8591
8482
  } else if (walletKind2 === "altana") {
8592
8483
  printAltanaNotice();
8593
- } else if (walletKind2 === "turnkey") {
8594
- printTurnkeyNotice();
8595
8484
  } else {
8596
8485
  printEvmLocalNotice(
8597
8486
  derivePackaging(walletKind2, destination, platformArtifact2, runtime)
@@ -8828,9 +8717,6 @@ function computeAgentNodeDeps(runtime, provider, protocols = "A2A", walletKind2
8828
8717
  if (walletKind2 === "altana") {
8829
8718
  raw.push(...readRecipeNodeDeps("wallet", "altana"));
8830
8719
  }
8831
- if (walletKind2 === "turnkey") {
8832
- raw.push(...readRecipeNodeDeps("wallet", "turnkey"));
8833
- }
8834
8720
  const out = {};
8835
8721
  const core = splitDep(coreRequirement());
8836
8722
  for (const dep of raw) {
@@ -9004,18 +8890,6 @@ kind = "altana"
9004
8890
  keystore_dir = "../../.studio/wallets"
9005
8891
  session_file = "../../.studio/wallets/altana-session.json"
9006
8892
  # address = "0x..." # filled by \`bag wallet new\`; session must match it`;
9007
- }
9008
- if (walletKind2 === "turnkey") {
9009
- return `[wallet]
9010
- # Turnkey remote signer. The key is generated and held in Turnkey's AWS Nitro
9011
- # enclave \u2014 no key material ever exists in this project or its deploys. The
9012
- # Agent signs via the Turnkey API using the TURNKEY_* credentials in
9013
- # .studio/.env.local. Billing: every successful signature is billed (free
9014
- # tier: 25 signatures/month at 1 request/second; pay-as-you-go $0.10 each).
9015
- # PRODUCTION: use a NON-ROOT API user restricted by an explicit ALLOW
9016
- # policy \u2014 a root user's API key bypasses ALL Turnkey server-side policies.
9017
- kind = "turnkey"
9018
- # address = "0x..." # filled by \`bag wallet new\` (adopts TURNKEY_SIGN_WITH)`;
9019
8893
  }
9020
8894
  return `[wallet]
9021
8895
  # Local keystore signer. The Agent is the SOLE key-holder/signer.
@@ -9141,7 +9015,7 @@ agent_endpoint = ""
9141
9015
  function renderAgentStudioToml(name, o) {
9142
9016
  const model = o.model ?? PROVIDER_DEFAULT_MODEL[o.provider] ?? "";
9143
9017
  const pieverseSection = o.provider === "pieverse-llm" ? renderPieverseSections() : "";
9144
- const x402Section = o.provider === "pieverse-llm" ? renderX402Section() : "";
9018
+ const x402Section = o.provider === "pieverse-llm" && o.budgetChoice === "enable" ? renderX402Section() : "";
9145
9019
  const x402SellerSection = o.rails === "b402" || o.rails === "both" || hasX402Face(o.faces) ? renderX402SellerSection(o.b402Price) : "";
9146
9020
  const budgetSection = renderBudgetSection(o.budgetChoice);
9147
9021
  const storageSection = renderAgentStorageSection(o.storageProvider);
@@ -9214,23 +9088,6 @@ function renderAgentEnvLocal(provider, storageProvider, walletKind2, rails, b402
9214
9088
  "# TWAK_ACCESS_ID=",
9215
9089
  "# TWAK_HMAC_SECRET="
9216
9090
  );
9217
- } else if (walletKind2 === "turnkey") {
9218
- lines.push(
9219
- "",
9220
- "# Turnkey API credentials (dashboard \u2192 API keys). The P-256 API key",
9221
- "# pair authenticates this Agent to the enclave; the wallet's signing",
9222
- "# key never leaves Turnkey. Use a NON-ROOT API user + explicit ALLOW",
9223
- "# policy in production (root keys bypass all Turnkey policies).",
9224
- "TURNKEY_API_PUBLIC_KEY=",
9225
- "TURNKEY_API_PRIVATE_KEY=",
9226
- "# Organization id (dashboard \u2192 settings):",
9227
- "TURNKEY_ORG_ID=",
9228
- "# Account to sign with \u2014 MUST be the 0x Ethereum ADDRESS itself, not",
9229
- "# a Turnkey wallet id. `bag wallet new` anchors it into studio.toml.",
9230
- "TURNKEY_SIGN_WITH=",
9231
- "# Optional API host override (default https://api.turnkey.com):",
9232
- "# TURNKEY_API_BASE_URL="
9233
- );
9234
9091
  } else if (walletKind2 === "evm-local" || walletKind2 === "altana") {
9235
9092
  lines.push(
9236
9093
  "",
@@ -9345,7 +9202,7 @@ entrypoint code in \`src/signing.ts\` \u2014 never an LLM-callable tool.
9345
9202
  ${mode === "both" ? filesBoth : mode === "mcp" ? filesMcp : filesA2a}
9346
9203
  ${shared}
9347
9204
  - \`.env.local\` \u2014 Agent secrets; on deploy they are sent to the **operator's**
9348
- Secrets Manager (the scoped, consented commitment-#2 exception). ${walletKind2 === "altana" ? "Only the\n bounded session ships (as `ALTANA_SESSION`); tighten it with\n `bag wallet session grant --force` \u2014 do not create a new wallet." : walletKind2 === "turnkey" ? "No key\n material exists locally \u2014 only the TURNKEY_* API credentials ship; the\n signing key stays in Turnkey's enclave. Fund the TURNKEY_SIGN_WITH\n address with a little tBNB; every successful signature is billed." : "Use a\n THROWAWAY testnet wallet \u2014 `(cd app/agent && bag wallet new)`."}
9205
+ Secrets Manager (the scoped, consented commitment-#2 exception). ${walletKind2 === "altana" ? "Only the\n bounded session ships (as `ALTANA_SESSION`); tighten it with\n `bag wallet session grant --force` \u2014 do not create a new wallet." : "Use a\n THROWAWAY testnet wallet \u2014 `(cd app/agent && bag wallet new)`."}
9349
9206
 
9350
9207
  ## Run locally
9351
9208
 
@@ -9454,12 +9311,12 @@ function ensureCursorGitignore(gitignore) {
9454
9311
  ${addition}`);
9455
9312
  }
9456
9313
  async function resolveWalletKind(flagValue, isTty) {
9457
- if (flagValue === "evm-local" || flagValue === "twak" || flagValue === "altana" || flagValue === "turnkey") {
9314
+ if (flagValue === "evm-local" || flagValue === "twak" || flagValue === "altana") {
9458
9315
  return flagValue;
9459
9316
  }
9460
9317
  if (!isTty) {
9461
9318
  printErr(
9462
- "info: wallet backend defaulting to 'evm-local' (non-interactive). To choose explicitly, re-run with --wallet-kind evm-local or --wallet-kind twak, --wallet-kind altana or --wallet-kind turnkey."
9319
+ "info: wallet backend defaulting to 'evm-local' (non-interactive). To choose explicitly, re-run with --wallet-kind evm-local or --wallet-kind twak or --wallet-kind altana."
9463
9320
  );
9464
9321
  return "evm-local";
9465
9322
  }
@@ -9471,15 +9328,11 @@ async function resolveWalletKind(flagValue, isTty) {
9471
9328
  " 2. twak \u2014 Trust Wallet CLI wallet; forces container packaging for deploys"
9472
9329
  );
9473
9330
  printOut(
9474
- " 3. altana \u2014 bounded session signer; incompatible with pieverse-llm"
9475
- );
9476
- printOut(
9477
- " 4. turnkey \u2014 remote signer; key held in Turnkey's AWS Nitro enclave; billable signatures"
9331
+ " 3. altana \u2014 bounded session signer; incompatible with pieverse-llm and paid b402 selling"
9478
9332
  );
9479
- const answer = (await promptUser("Wallet backend [1-4, Enter = evm-local]: ")).trim().toLowerCase();
9333
+ const answer = (await promptUser("Wallet backend [1-3, Enter = evm-local]: ")).trim().toLowerCase();
9480
9334
  if (answer === "2" || answer === "twak") return "twak";
9481
9335
  if (answer === "3" || answer === "altana") return "altana";
9482
- if (answer === "4" || answer === "turnkey") return "turnkey";
9483
9336
  if (answer !== "" && answer !== "1" && answer !== "evm-local") {
9484
9337
  printErr(`hint: unknown wallet backend '${answer}' \u2014 using evm-local.`);
9485
9338
  }
@@ -9761,12 +9614,6 @@ async function runOnboarding(o) {
9761
9614
  if (o.walletKind === "twak") {
9762
9615
  return runOnboardingTwak(o);
9763
9616
  }
9764
- if (o.walletKind === "turnkey") {
9765
- printOut(
9766
- "turnkey onboarding: no local key is created. Fill the TURNKEY_* credentials in .studio/.env.local (Turnkey dashboard \u2192 API keys / settings / wallet account), then run `(cd app/agent && bag wallet new)` to adopt + anchor the signing address."
9767
- );
9768
- return false;
9769
- }
9770
9617
  const password = await promptPassword();
9771
9618
  if (password === null) {
9772
9619
  return false;
@@ -10136,33 +9983,7 @@ NOTE \u2014 wallet.kind = "altana" (bounded runtime session):
10136
9983
  \`bag wallet session grant --force\` and redeploy.`
10137
9984
  );
10138
9985
  }
10139
- function printTurnkeyNotice() {
10140
- printOut(
10141
- `
10142
- NOTE \u2014 wallet.kind = "turnkey" (remote signer, keys in Turnkey's AWS Nitro enclave):
10143
- \xB7 WALLET: no key material exists locally \u2014 the Agent signs via the TURNKEY_*
10144
- API credentials in .studio/.env.local.
10145
- ${turnkeySetupGuidance()}
10146
- \xB7 BILLING: every successful signature is billed (free tier: 25/month at
10147
- 1 request/second; pay-as-you-go $0.10 each) \u2014 budget accordingly.
10148
- \xB7 PRODUCTION: use a NON-ROOT API user restricted by an explicit ALLOW policy;
10149
- a root user's API key bypasses ALL Turnkey server-side policies.`
10150
- );
10151
- }
10152
9986
  function printPlatformWalletSuggestion(walletKind2) {
10153
- if (walletKind2 === "turnkey") {
10154
- printOut(
10155
- `
10156
- NOTE \u2014 destination = "platform" (48h TESTNET TRIAL on the BNB Chain managed platform):
10157
- \xB7 This is a sandbox, not a production seller \u2014 the runtime is auto-reclaimed at 48h.
10158
- \xB7 To sign, ONLY the TURNKEY_* API credentials are transmitted to the operator's
10159
- Secrets Manager on deploy \u2014 the signing key never leaves Turnkey's enclave.
10160
- \xB7 Want a smaller blast radius? Use a NON-ROOT API user whose ALLOW policy
10161
- covers only this Agent's operations, and revoke it from the Turnkey
10162
- dashboard when the trial ends.`
10163
- );
10164
- return;
10165
- }
10166
9987
  if (walletKind2 === "altana") {
10167
9988
  printOut(
10168
9989
  `
@@ -10393,17 +10214,6 @@ function printNextSteps(name, provider, o = {}) {
10393
10214
  printOut(
10394
10215
  " (cd app/agent && bag wallet session status) # local, secret-free summary"
10395
10216
  );
10396
- } else if (walletKind2 === "turnkey") {
10397
- printOut(
10398
- " # 1. edit .studio/.env.local and set the TURNKEY_* credentials (Turnkey dashboard \u2192 API keys / settings / wallet account)"
10399
- );
10400
- printOut(
10401
- " # use a NON-ROOT API user + explicit ALLOW policy; TURNKEY_SIGN_WITH is the 0x ADDRESS, not a wallet id"
10402
- );
10403
- printOut(
10404
- " # 2. adopt + anchor the Turnkey address (no local key is created):"
10405
- );
10406
- printOut(" (cd app/agent && bag wallet new)");
10407
10217
  } else {
10408
10218
  printOut(
10409
10219
  " # 1. edit .studio/.env.local and set WALLET_PASSWORD (encrypts the keystore + signs all on-chain ops)"
@@ -10627,10 +10437,6 @@ function printConfigSummary(agentRoot2) {
10627
10437
  ".studio/wallets/altana-session.json"
10628
10438
  )}`
10629
10439
  );
10630
- } else if (walletKind2 === "turnkey") {
10631
- printOut(
10632
- " wallet : Turnkey remote signer (key in AWS Nitro enclave; TURNKEY_* credentials in .studio/.env.local) \u2014 the sole signer; receives your $U"
10633
- );
10634
10440
  } else {
10635
10441
  printOut(
10636
10442
  ` wallet : local keystore (${shown(
@@ -10751,16 +10557,6 @@ function runtimeEnvKeysCore(cfg, resolvable) {
10751
10557
  }
10752
10558
  } else if (walletKind2 === "altana") {
10753
10559
  keys = [];
10754
- } else if (walletKind2 === "turnkey") {
10755
- keys = [
10756
- "TURNKEY_API_PUBLIC_KEY",
10757
- "TURNKEY_API_PRIVATE_KEY",
10758
- "TURNKEY_ORG_ID",
10759
- "TURNKEY_SIGN_WITH"
10760
- ];
10761
- if (resolvable("TURNKEY_API_BASE_URL")) {
10762
- keys.push("TURNKEY_API_BASE_URL");
10763
- }
10764
10560
  } else {
10765
10561
  keys = ["WALLET_PASSWORD"];
10766
10562
  }
@@ -11285,17 +11081,10 @@ async function cmdDev(opts) {
11285
11081
  );
11286
11082
  return 2;
11287
11083
  }
11288
- const requiredWalletEnv = walletKind2 === "twak" ? ["TWAK_WALLET_PASSWORD"] : walletKind2 === "altana" ? [] : walletKind2 === "turnkey" ? [
11289
- "TURNKEY_API_PUBLIC_KEY",
11290
- "TURNKEY_API_PRIVATE_KEY",
11291
- "TURNKEY_ORG_ID",
11292
- "TURNKEY_SIGN_WITH"
11293
- ] : ["WALLET_PASSWORD"];
11294
- const missingWalletEnv = requiredWalletEnv.filter((key) => !process.env[key]);
11295
- if (missingWalletEnv.length > 0) {
11296
- const plural = missingWalletEnv.length > 1 ? "vars are" : "var is";
11084
+ const pwEnv = walletKind2 === "twak" ? "TWAK_WALLET_PASSWORD" : "WALLET_PASSWORD";
11085
+ if (walletKind2 !== "altana" && !process.env[pwEnv]) {
11297
11086
  printErr(
11298
- `error: ${missingWalletEnv.join(", ")} env ${plural} required to run \`bag dev\` with wallet.kind='${walletKind2}' (the Agent is the sole signer). Set ${missingWalletEnv.length > 1 ? "them" : "it"} in .studio/.env.local or your shell.`
11087
+ `error: ${pwEnv} env var is required to run \`bag dev\` (the Agent is the sole signer). Set it in .studio/.env.local or your shell.`
11299
11088
  );
11300
11089
  return 2;
11301
11090
  }
@@ -11676,9 +11465,6 @@ async function checkLocalKeystoreExists(root, _target) {
11676
11465
  if (walletCfg.kind === "altana") {
11677
11466
  return [];
11678
11467
  }
11679
- if (walletCfg.kind === "turnkey") {
11680
- return [];
11681
- }
11682
11468
  const signer = walletCfg.signer ?? "local";
11683
11469
  if (signer !== "local") {
11684
11470
  return [];
@@ -11704,9 +11490,6 @@ async function checkWalletPasswordEnvSet(root, _target) {
11704
11490
  if (kind === "altana") {
11705
11491
  return [];
11706
11492
  }
11707
- if (kind === "turnkey") {
11708
- return [];
11709
- }
11710
11493
  if (process.env.WALLET_PASSWORD) {
11711
11494
  return [];
11712
11495
  }
@@ -12049,11 +11832,11 @@ function x402SellerRailChecks(agentRoot2, cfg, target) {
12049
11832
  }
12050
11833
  }
12051
11834
  const walletKind2 = String(tableOf2(cfg, "wallet").kind ?? "evm-local");
12052
- if (paid && !["evm-local", "twak", "turnkey", "altana"].includes(walletKind2)) {
11835
+ if (paid && !["evm-local", "twak"].includes(walletKind2)) {
12053
11836
  out.push({
12054
11837
  level: Level.CRITICAL,
12055
11838
  name: "x402_wallet_kind_unsupported",
12056
- message: `[wallet].kind = "${walletKind2}" cannot run the b402 seller rail; supported kinds are evm-local, twak, turnkey, and altana.`,
11839
+ message: `[wallet].kind = "${walletKind2}" cannot run the b402 seller rail; supported kinds are evm-local and twak.`,
12057
11840
  details: { walletKind: walletKind2 }
12058
11841
  });
12059
11842
  }
@@ -12330,46 +12113,6 @@ function awsJson(stdout) {
12330
12113
  return null;
12331
12114
  }
12332
12115
  }
12333
- async function checkAwsAccountMatchesTarget(root, target) {
12334
- if (target !== "agentcore") {
12335
- return [];
12336
- }
12337
- const [targetAccount, region] = readAwsTarget(root);
12338
- if (!targetAccount || !region || !await whichBin("aws")) {
12339
- return [];
12340
- }
12341
- const identity = await runCapture("aws", [
12342
- "sts",
12343
- "get-caller-identity",
12344
- "--region",
12345
- region,
12346
- "--output",
12347
- "json"
12348
- ]);
12349
- if (identity.code !== 0) {
12350
- return [];
12351
- }
12352
- const rawAccount = awsJson(identity.stdout)?.Account;
12353
- const credentialAccount = typeof rawAccount === "string" && /^\d{12}$/.test(rawAccount.trim()) ? rawAccount.trim() : null;
12354
- if (credentialAccount === null || credentialAccount === targetAccount) {
12355
- return [];
12356
- }
12357
- const targetPath = path24.join(root, "agentcore", "aws-targets.json");
12358
- return [
12359
- {
12360
- level: Level.CRITICAL,
12361
- name: "aws_account_mismatch",
12362
- message: `active AWS credentials resolve to account ${credentialAccount}, but agentcore/aws-targets.json pins account ${targetAccount}. The delegated deploy rejects this mismatch before provisioning. Switch credentials, or update the local target file after confirming which account should own the deployment.`,
12363
- details: {
12364
- credential_account: credentialAccount,
12365
- target_account: targetAccount,
12366
- region,
12367
- path: targetPath
12368
- },
12369
- fixCmd: `# edit agentcore/aws-targets.json and set the default account to ${credentialAccount}, or switch the active AWS credentials`
12370
- }
12371
- ];
12372
- }
12373
12116
  async function checkAgentcoreQuotaHeadroom(root, target) {
12374
12117
  if (target !== "agentcore") {
12375
12118
  return [];
@@ -12475,7 +12218,6 @@ var allChecks = [
12475
12218
  checkDeployCliRunnable,
12476
12219
  checkRuntimeSecretsInjected,
12477
12220
  checkAwsTargetsPopulated,
12478
- checkAwsAccountMatchesTarget,
12479
12221
  checkAgentcoreQuotaHeadroom
12480
12222
  ];
12481
12223
 
@@ -12611,7 +12353,7 @@ function collectRuntimeSecretsDetailed(root) {
12611
12353
  sources[KEYSTORE_JSON_ENV] = "wallet-file";
12612
12354
  }
12613
12355
  }
12614
- if (walletKind2 !== "altana" && walletKind2 !== "turnkey" && !(KEYSTORE_JSON_ENV in payload) && !(TWAK_WALLET_JSON_ENV in payload)) {
12356
+ if (walletKind2 !== "altana" && !(KEYSTORE_JSON_ENV in payload) && !(TWAK_WALLET_JSON_ENV in payload)) {
12615
12357
  printErr(
12616
12358
  `WARNING: no wallet signing material found (${KEYSTORE_JSON_ENV} for evm-local / ${TWAK_WALLET_JSON_ENV} for twak). The deployed runtime won't be able to sign quotes or deliveries. Create/adopt a wallet first (e.g. \`bag wallet new\`) and redeploy.`
12617
12359
  );
@@ -15287,15 +15029,6 @@ function printAgentClientPrompt(root, invokeUrl, status) {
15287
15029
  );
15288
15030
  }
15289
15031
  const endpointBlock = endpoints.join("\n");
15290
- const commerceShapeLines = hasA2aFace(faces) ? [
15291
- "MESSAGE SHAPES (complete A2A JSON-RPC requests)",
15292
- '- negotiate: {"jsonrpc":"2.0","id":"request-1","method":"message/send","params":{"message":{"messageId":"message-1","role":"user","parts":[{"kind":"data","data":{"skill":"negotiate","task_description":"<what you want done>","terms":{"deliverables":"...","quality_standards":"..."}}}]}}}',
15293
- '- notify_funded: {"jsonrpc":"2.0","id":"request-2","method":"message/send","params":{"message":{"messageId":"message-2","role":"user","parts":[{"kind":"data","data":{"skill":"notify_funded","job_id":123}}]}}}'
15294
- ] : [
15295
- "MCP TOOL ARGUMENTS",
15296
- '- negotiate: {"task_description":"<what you want done>","terms":{"deliverables":"...","quality_standards":"..."}}',
15297
- '- notify_funded: {"job_id":123}'
15298
- ];
15299
15032
  const lines = [
15300
15033
  "",
15301
15034
  CLIENT_PROMPT_RULE,
@@ -15328,7 +15061,9 @@ function printAgentClientPrompt(root, invokeUrl, status) {
15328
15061
  "- Remote ERC-8183 callers need an OAuth2 access token:",
15329
15062
  tokenSteps,
15330
15063
  "",
15331
- ...commerceShapeLines
15064
+ "MESSAGE SHAPES",
15065
+ '- negotiate: {"skill":"negotiate","task_description":"<what you want done>","terms":{"deliverables":"...","quality_standards":"..."}}',
15066
+ '- notify_funded: {"skill":"notify_funded","job_id":<int>}'
15332
15067
  ] : [
15333
15068
  "- The anonymous x402 route does not use the OAuth2 token flow shown for ERC-8183."
15334
15069
  ],
@@ -16775,28 +16510,6 @@ async function printAgentClientPrompt2(root, destination, opts = {}) {
16775
16510
  The invoke URL carries a querystring (?qualifier=...): never
16776
16511
  string-concatenate extra path segments onto it \u2014 that produces
16777
16512
  an invalid URL and an HTTP 405.`;
16778
- const commerceShapeLines = hasA2aFace(faces) ? [
16779
- "MESSAGE SHAPES (complete A2A JSON-RPC requests)",
16780
- '- negotiate: {"jsonrpc":"2.0","id":"request-1","method":"message/send","params":{"message":{"messageId":"message-1","role":"user","parts":[{"kind":"data","data":{"skill":"negotiate","task_description":"<what you want done>","terms":{"deliverables":"...","quality_standards":"..."}}}]}}}',
16781
- '- notify_funded: {"jsonrpc":"2.0","id":"request-2","method":"message/send","params":{"message":{"messageId":"message-2","role":"user","parts":[{"kind":"data","data":{"skill":"notify_funded","job_id":123}}]}}}'
16782
- ] : [
16783
- "MCP TOOL ARGUMENTS",
16784
- '- negotiate: {"task_description":"<what you want done>","terms":{"deliverables":"...","quality_standards":"..."}}',
16785
- '- notify_funded: {"job_id":123}'
16786
- ];
16787
- const mcpSessionLines = hasA2aFace(faces) && hasMcpFace(faces) ? [
16788
- "",
16789
- "MCP SESSION FLOW (A2A+MCP through envelope-v1)",
16790
- " 1) Keep X-Amzn-Bedrock-AgentCore-Runtime-Session-Id on every outer InvokeAgentRuntime request; this is the outer AgentCore runtime session.",
16791
- " 2) Send an envelope-v1 POST /mcp whose decoded body is the MCP initialize request, with no inner mcp-session-id header.",
16792
- ' 3) Decode the envelope response and read headers["mcp-session-id"]; this is the inner MCP session, separate from the outer header.',
16793
- " 4) Send notifications/initialized, then tools/list or tools/call in new envelopes whose inner headers carry that same mcp-session-id."
16794
- ] : hasMcpFace(faces) ? [
16795
- "",
16796
- "MCP SESSION FLOW",
16797
- " 1) Send initialize without mcp-session-id and capture the response mcp-session-id header.",
16798
- " 2) Send notifications/initialized, then tools/list or tools/call with that header."
16799
- ] : [];
16800
16513
  const lines = [
16801
16514
  "",
16802
16515
  CLIENT_PROMPT_RULE2,
@@ -16826,8 +16539,9 @@ async function printAgentClientPrompt2(root, destination, opts = {}) {
16826
16539
  "- Remote ERC-8183 callers need an OAuth2 access token:",
16827
16540
  tokenSteps,
16828
16541
  "",
16829
- ...commerceShapeLines,
16830
- ...mcpSessionLines
16542
+ "MESSAGE SHAPES",
16543
+ '- negotiate: {"skill":"negotiate","task_description":"<what you want done>","terms":{"deliverables":"...","quality_standards":"..."}}',
16544
+ '- notify_funded: {"skill":"notify_funded","job_id":<int>}'
16831
16545
  ] : [
16832
16546
  "- The anonymous x402 route does not use the OAuth2 token flow shown for ERC-8183."
16833
16547
  ],
@@ -17724,8 +17438,7 @@ var SECRET_ENV_KEYS = [
17724
17438
  "PIEVERSE_LLM_API_KEY",
17725
17439
  "STORAGE_API_KEY",
17726
17440
  "TWAK_ACCESS_ID",
17727
- "TWAK_HMAC_SECRET",
17728
- "TURNKEY_API_PRIVATE_KEY"
17441
+ "TWAK_HMAC_SECRET"
17729
17442
  ];
17730
17443
  function tableOf14(cfg, key) {
17731
17444
  const v = cfg[key];
@@ -17972,9 +17685,6 @@ async function checkWallet(projectRoot, data) {
17972
17685
  if (walletCfg.kind === "altana") {
17973
17686
  return checkWalletAltana(walletCfg, projectRoot, data);
17974
17687
  }
17975
- if (walletCfg.kind === "turnkey") {
17976
- return checkWalletTurnkey(walletCfg);
17977
- }
17978
17688
  if (!isLocalEvmWallet(walletCfg)) {
17979
17689
  return [
17980
17690
  {
@@ -18028,59 +17738,7 @@ async function checkWallet(projectRoot, data) {
18028
17738
  }
18029
17739
  return out;
18030
17740
  }
18031
- var TURNKEY_ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
18032
- var TURNKEY_REQUIRED_ENV = [
18033
- "TURNKEY_API_PUBLIC_KEY",
18034
- "TURNKEY_API_PRIVATE_KEY",
18035
- "TURNKEY_ORG_ID",
18036
- "TURNKEY_SIGN_WITH"
18037
- ];
18038
- function checkWalletTurnkey(walletCfg) {
18039
- const out = [];
18040
- const missing = TURNKEY_REQUIRED_ENV.filter((key) => !process.env[key]);
18041
- out.push(
18042
- missing.length === 0 ? {
18043
- name: "[wallet] turnkey credentials",
18044
- status: PASS,
18045
- detail: "API key pair + org id + sign-with address set; reminder: production should use a non-root API user with an explicit ALLOW policy (root keys bypass all Turnkey policies)"
18046
- } : {
18047
- name: "[wallet] turnkey credentials",
18048
- status: FAIL,
18049
- detail: `missing: ${missing.join(", ")} \u2014 set them in .studio/.env.local (Turnkey dashboard \u2192 API keys / settings / wallet account)`
18050
- }
18051
- );
18052
- const signWith = String(process.env.TURNKEY_SIGN_WITH ?? "").trim();
18053
- if (signWith !== "" && !TURNKEY_ADDRESS_RE.test(signWith)) {
18054
- out.push({
18055
- name: "TURNKEY_SIGN_WITH format",
18056
- status: FAIL,
18057
- detail: "must be the wallet account's Ethereum address (0x + 40 hex chars), not a Turnkey wallet id \u2014 copy it from the dashboard wallet-account view"
18058
- });
18059
- }
18060
- const anchored = String(walletCfg.address ?? "").trim();
18061
- if (anchored === "") {
18062
- out.push({
18063
- name: "[wallet] address anchor",
18064
- status: WARN,
18065
- detail: "no [wallet].address \u2014 run `bag wallet new` to adopt TURNKEY_SIGN_WITH"
18066
- });
18067
- } else if (signWith !== "" && TURNKEY_ADDRESS_RE.test(signWith)) {
18068
- const matches = anchored.toLowerCase() === signWith.toLowerCase();
18069
- out.push(
18070
- matches ? {
18071
- name: "[wallet] address anchor",
18072
- status: PASS,
18073
- detail: `${anchored} matches TURNKEY_SIGN_WITH`
18074
- } : {
18075
- name: "[wallet] address anchor",
18076
- status: FAIL,
18077
- detail: `[wallet].address ${anchored} does not match TURNKEY_SIGN_WITH ${signWith} \u2014 stale anchor or different Turnkey credentials; fix .studio/.env.local, then re-run \`bag wallet new\``
18078
- }
18079
- );
18080
- }
18081
- return out;
18082
- }
18083
- async function checkWalletAltana(walletCfg, projectRoot, data) {
17741
+ function checkWalletAltana(walletCfg, projectRoot, data) {
18084
17742
  const out = [];
18085
17743
  const contracts = erc8183ContractOverrideState(
18086
17744
  erc8183ContractEnvForProject(projectRoot)
@@ -18166,41 +17824,13 @@ async function checkWalletAltana(walletCfg, projectRoot, data) {
18166
17824
  out.push({
18167
17825
  name: "[wallet] Altana SDK",
18168
17826
  status: entry === null ? FAIL : PASS,
18169
- detail: entry === null ? "@altananetwork/sdk is not resolvable from this project \u2014 run `pnpm add @altananetwork/sdk@0.7.1`" : entry
17827
+ detail: entry === null ? "@altananetwork/sdk is not resolvable from this project \u2014 run `pnpm add @altananetwork/sdk@0.5.1`" : entry
18170
17828
  });
18171
17829
  } catch (error) {
18172
17830
  out.push({
18173
17831
  name: "[wallet] Altana SDK",
18174
17832
  status: FAIL,
18175
- detail: `${error instanceof Error ? error.message : String(error)} \u2014 run \`pnpm add @altananetwork/sdk@0.7.1\``
18176
- });
18177
- }
18178
- const networkName = String(tableOf14(data, "network").default ?? "bsc-mainnet");
18179
- try {
18180
- const allowanceRaw = await readUAllowanceRaw(
18181
- address,
18182
- PERMIT2_ADDRESS,
18183
- networkName
18184
- );
18185
- if (allowanceRaw !== null) {
18186
- const uToken = getNetwork9(networkName).token("U");
18187
- out.push(
18188
- allowanceRaw > 0n ? {
18189
- name: "[wallet] Altana x402 buying",
18190
- status: PASS,
18191
- detail: `U\u2192Permit2 allowance ${fromRaw3(allowanceRaw, uToken.decimals)} U on ${networkName} (b402 permit2 rail armed)`
18192
- } : {
18193
- name: "[wallet] Altana x402 buying",
18194
- status: WARN,
18195
- detail: `no U\u2192Permit2 allowance on ${networkName} \u2014 outbound x402 buying is not armed; run \`bag wallet session x402-setup --allowance-u <amount>\` (admin key) if this agent should pay b402 merchants`
18196
- }
18197
- );
18198
- }
18199
- } catch (error) {
18200
- out.push({
18201
- name: "[wallet] Altana x402 buying",
18202
- status: WARN,
18203
- detail: `could not read the U\u2192Permit2 allowance on ${networkName}: ${error instanceof Error ? error.message : String(error)}`
17833
+ detail: `${error instanceof Error ? error.message : String(error)} \u2014 run \`pnpm add @altananetwork/sdk@0.5.1\``
18204
17834
  });
18205
17835
  }
18206
17836
  return out;
@@ -18300,20 +17930,6 @@ function checkPassword(data) {
18300
17930
  }
18301
17931
  ];
18302
17932
  }
18303
- if (walletKind2 === "turnkey") {
18304
- const missing = TURNKEY_REQUIRED_ENV.filter((key) => !process.env[key]);
18305
- return [
18306
- missing.length === 0 ? {
18307
- name: "TURNKEY_* env",
18308
- status: PASS,
18309
- detail: "all Turnkey credentials set (WALLET_PASSWORD is not used for this kind)"
18310
- } : {
18311
- name: "TURNKEY_* env",
18312
- status: WARN,
18313
- detail: `missing: ${missing.join(", ")} \u2014 signing will fail (set in .studio/.env.local)`
18314
- }
18315
- ];
18316
- }
18317
17933
  if (process.env.WALLET_PASSWORD) {
18318
17934
  return [{ name: "WALLET_PASSWORD env", status: PASS, detail: "set" }];
18319
17935
  }
@@ -18682,11 +18298,11 @@ function checkX402Seller(data, agentRoot2) {
18682
18298
  }
18683
18299
  ];
18684
18300
  const walletKind2 = String(tableOf14(data, "wallet").kind ?? "evm-local");
18685
- if (!["evm-local", "twak", "turnkey", "altana"].includes(walletKind2)) {
18301
+ if (!["evm-local", "twak"].includes(walletKind2)) {
18686
18302
  out.push({
18687
18303
  name: "x402 payout wallet",
18688
18304
  status: FAIL,
18689
- detail: `PAID B402 supports evm-local, twak, turnkey or altana, not ${walletKind2}.`
18305
+ detail: `PAID B402 supports evm-local or twak, not ${walletKind2}.`
18690
18306
  });
18691
18307
  }
18692
18308
  const credentials = b402Credentials(agentRoot2);
@@ -18760,7 +18376,7 @@ function checkStorage(data) {
18760
18376
  }
18761
18377
  function balanceAddress(projectRoot, data) {
18762
18378
  const walletCfg = tableOf14(data, "wallet");
18763
- if (walletCfg.kind === "twak" || walletCfg.kind === "altana" || walletCfg.kind === "turnkey") {
18379
+ if (walletCfg.kind === "twak" || walletCfg.kind === "altana") {
18764
18380
  const addr = String(walletCfg.address ?? "").trim();
18765
18381
  return addr || null;
18766
18382
  }
@@ -21486,9 +21102,9 @@ async function cmdSellInit(priceFlag) {
21486
21102
  }
21487
21103
  const free = x402SellerPricingState({ price_usd: priceUsd }).kind === "free";
21488
21104
  const walletKind2 = String(tableOf16(cfg, "wallet").kind ?? "evm-local");
21489
- if (!free && !["evm-local", "twak", "turnkey", "altana"].includes(walletKind2)) {
21105
+ if (!free && !["evm-local", "twak"].includes(walletKind2)) {
21490
21106
  printErr(
21491
- `error: the b402 seller rail supports wallet.kind evm-local, twak, turnkey or altana only; '${walletKind2}' cannot act as the b402 payout wallet.`
21107
+ `error: the b402 seller rail supports wallet.kind evm-local or twak only; '${walletKind2}' cannot act as the b402 payout wallet.`
21492
21108
  );
21493
21109
  return 1;
21494
21110
  }
@@ -21614,21 +21230,16 @@ async function cmdSellStatus(probe) {
21614
21230
  }
21615
21231
  try {
21616
21232
  const supported = await _probeB402Supported(process.env);
21617
- const matching = (method) => supported?.kinds.find(
21618
- (kind) => kind.x402Version === 2 && kind.scheme === "exact" && kind.network === network && kind.extra.assetTransferMethod === method && kind.extra.name === token.eip712Name && kind.extra.version === token.eip712Version
21619
- );
21620
- const available = token.methods.filter(
21621
- (method) => matching(method) !== void 0
21233
+ const methodKind = supported?.kinds.find(
21234
+ (kind) => kind.x402Version === 2 && kind.scheme === "exact" && kind.network === network && kind.extra.assetTransferMethod === "eip3009"
21622
21235
  );
21623
- if (available.length > 0) {
21624
- const missing = token.methods.filter((m) => !available.includes(m));
21625
- printOut(
21626
- `B402 probe: exact U available for ${network} (${available.join(", ")})${missing.length > 0 ? ` \u2014 advertised but not offered by the facilitator: ${missing.join(", ")}` : ""}`
21627
- );
21236
+ if (methodKind && methodKind.extra.name === token.eip712Name && methodKind.extra.version === token.eip712Version) {
21237
+ printOut(`B402 probe: exact/eip3009 U available for ${network}`);
21628
21238
  return 0;
21629
21239
  }
21240
+ const observed = methodKind ? `observed name=${String(methodKind.extra.name ?? "(missing)")} version=${String(methodKind.extra.version ?? "(missing)")}` : "no exact/eip3009 kind was returned";
21630
21241
  printOut(
21631
- `B402 probe: mismatch for ${network}; expected an exact kind (${token.methods.join(" or ")}) with name=${token.eip712Name} version=${token.eip712Version}; none was returned. Check that the credentials belong to the matching B402 environment.`
21242
+ `B402 probe: mismatch for ${network}; expected name=${token.eip712Name} version=${token.eip712Version}; ${observed}. Check that the credentials belong to the matching B402 environment.`
21632
21243
  );
21633
21244
  } catch {
21634
21245
  printOut(
@@ -21757,30 +21368,6 @@ async function cmdBuy2(url, opts) {
21757
21368
  );
21758
21369
  return 1;
21759
21370
  }
21760
- const buyWalletKind = String(tableOf16(cfg, "wallet").kind ?? "evm-local");
21761
- if (buyWalletKind === "altana") {
21762
- let allowanceRaw;
21763
- try {
21764
- allowanceRaw = await readUAllowanceRaw(
21765
- wallet.address,
21766
- PERMIT2_ADDRESS,
21767
- networkName
21768
- );
21769
- } catch (exc) {
21770
- printErr(`error: permit2 allowance check failed: ${errMsg6(exc)}`);
21771
- return 1;
21772
- }
21773
- if (allowanceRaw !== null && allowanceRaw < neededRaw) {
21774
- const uToken = getNetwork11(networkName).token("U");
21775
- printErr(
21776
- `error: U\u2192Permit2 allowance ${fromRaw5(allowanceRaw, uToken.decimals)} U cannot cover max_usd $${opts.maxUsd.toFixed(2)}: b402 settles Altana payments by pulling through Permit2 (${PERMIT2_ADDRESS}).`
21777
- );
21778
- printErr(
21779
- "fix: bag wallet session x402-setup --allowance-u <amount> (admin key; approves the x402 signature checker and sets the bounded Permit2 allowance)"
21780
- );
21781
- return 1;
21782
- }
21783
- }
21784
21371
  let result;
21785
21372
  try {
21786
21373
  result = await auditedOp4(
@@ -21820,7 +21407,7 @@ async function cmdBuy2(url, opts) {
21820
21407
  }
21821
21408
  const paidUsd = result.paidUsd ?? 0;
21822
21409
  const envelope = result.txPaymentEnvelope ?? "";
21823
- const envelopePreview = envelope ? `${envelope.slice(0, 40)}...` : result.paidUsd !== null ? "(delegated x402 client \u2014 the envelope never leaves the wallet client)" : "(no payment \u2014 server did not 402)";
21410
+ const envelopePreview = envelope ? `${envelope.slice(0, 40)}...` : "(no payment \u2014 server did not 402)";
21824
21411
  const ok = result.statusCode >= 200 && result.statusCode < 300;
21825
21412
  if (result.paidUsd === null) {
21826
21413
  if (ok) {