arc402-cli 1.8.3 → 1.8.5

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.
Files changed (132) hide show
  1. package/dist/chat/harness.d.ts +1 -0
  2. package/dist/chat/harness.d.ts.map +1 -1
  3. package/dist/chat/harness.js +28 -3
  4. package/dist/chat/harness.js.map +1 -1
  5. package/dist/commands/arena-v2.js +1 -1
  6. package/dist/commands/arena-v2.js.map +1 -1
  7. package/dist/commands/chat.d.ts.map +1 -1
  8. package/dist/commands/chat.js +4 -3
  9. package/dist/commands/chat.js.map +1 -1
  10. package/dist/commands/config.d.ts.map +1 -1
  11. package/dist/commands/config.js +22 -2
  12. package/dist/commands/config.js.map +1 -1
  13. package/dist/commands/daemon.d.ts.map +1 -1
  14. package/dist/commands/daemon.js +57 -11
  15. package/dist/commands/daemon.js.map +1 -1
  16. package/dist/commands/openshell.d.ts.map +1 -1
  17. package/dist/commands/openshell.js +16 -5
  18. package/dist/commands/openshell.js.map +1 -1
  19. package/dist/commands/wallet.d.ts.map +1 -1
  20. package/dist/commands/wallet.js +69 -50
  21. package/dist/commands/wallet.js.map +1 -1
  22. package/dist/commands/workroom.d.ts.map +1 -1
  23. package/dist/commands/workroom.js +4 -2
  24. package/dist/commands/workroom.js.map +1 -1
  25. package/dist/config.d.ts +4 -1
  26. package/dist/config.d.ts.map +1 -1
  27. package/dist/config.js +108 -13
  28. package/dist/config.js.map +1 -1
  29. package/dist/daemon/config.d.ts +1 -1
  30. package/dist/daemon/config.d.ts.map +1 -1
  31. package/dist/daemon/config.js +2 -2
  32. package/dist/daemon/config.js.map +1 -1
  33. package/dist/daemon/index.d.ts.map +1 -1
  34. package/dist/daemon/index.js +60 -1
  35. package/dist/daemon/index.js.map +1 -1
  36. package/dist/daemon/worker-executor.d.ts +1 -0
  37. package/dist/daemon/worker-executor.d.ts.map +1 -1
  38. package/dist/daemon/worker-executor.js +16 -1
  39. package/dist/daemon/worker-executor.js.map +1 -1
  40. package/dist/openshell-runtime.d.ts +6 -0
  41. package/dist/openshell-runtime.d.ts.map +1 -1
  42. package/dist/openshell-runtime.js +93 -4
  43. package/dist/openshell-runtime.js.map +1 -1
  44. package/dist/renderer/ThemedText.d.ts +2 -1
  45. package/dist/renderer/ThemedText.d.ts.map +1 -1
  46. package/dist/renderer/ThemedText.js +4 -1
  47. package/dist/renderer/ThemedText.js.map +1 -1
  48. package/dist/renderer/reconciler.d.ts.map +1 -1
  49. package/dist/renderer/reconciler.js +13 -1
  50. package/dist/renderer/reconciler.js.map +1 -1
  51. package/dist/tui/App.d.ts +3 -1
  52. package/dist/tui/App.d.ts.map +1 -1
  53. package/dist/tui/App.js +44 -6
  54. package/dist/tui/App.js.map +1 -1
  55. package/dist/tui/Header.d.ts.map +1 -1
  56. package/dist/tui/Header.js +2 -1
  57. package/dist/tui/Header.js.map +1 -1
  58. package/dist/tui/InputLine.d.ts.map +1 -1
  59. package/dist/tui/InputLine.js +2 -1
  60. package/dist/tui/InputLine.js.map +1 -1
  61. package/dist/tui/KernelPayloadRenderer.d.ts.map +1 -1
  62. package/dist/tui/KernelPayloadRenderer.js +17 -0
  63. package/dist/tui/KernelPayloadRenderer.js.map +1 -1
  64. package/dist/tui/Viewport.d.ts +4 -8
  65. package/dist/tui/Viewport.d.ts.map +1 -1
  66. package/dist/tui/Viewport.js +18 -28
  67. package/dist/tui/Viewport.js.map +1 -1
  68. package/dist/tui/command-catalog.d.ts.map +1 -1
  69. package/dist/tui/command-catalog.js +7 -2
  70. package/dist/tui/command-catalog.js.map +1 -1
  71. package/dist/tui/command-renderers.d.ts +20 -12
  72. package/dist/tui/command-renderers.d.ts.map +1 -1
  73. package/dist/tui/command-renderers.js +154 -37
  74. package/dist/tui/command-renderers.js.map +1 -1
  75. package/dist/tui/components/AnsiTextLine.d.ts +4 -0
  76. package/dist/tui/components/AnsiTextLine.d.ts.map +1 -0
  77. package/dist/tui/components/AnsiTextLine.js +92 -0
  78. package/dist/tui/components/AnsiTextLine.js.map +1 -0
  79. package/dist/tui/components/Button.js +1 -1
  80. package/dist/tui/components/Button.js.map +1 -1
  81. package/dist/tui/components/ChatHarnessSelector.d.ts.map +1 -1
  82. package/dist/tui/components/ChatHarnessSelector.js +4 -3
  83. package/dist/tui/components/ChatHarnessSelector.js.map +1 -1
  84. package/dist/tui/components/CompletionDropdown.d.ts.map +1 -1
  85. package/dist/tui/components/CompletionDropdown.js +4 -3
  86. package/dist/tui/components/CompletionDropdown.js.map +1 -1
  87. package/dist/tui/components/ConfirmPrompt.d.ts.map +1 -1
  88. package/dist/tui/components/ConfirmPrompt.js +2 -1
  89. package/dist/tui/components/ConfirmPrompt.js.map +1 -1
  90. package/dist/tui/components/commerce/FeedCard.d.ts +13 -0
  91. package/dist/tui/components/commerce/FeedCard.d.ts.map +1 -0
  92. package/dist/tui/components/commerce/FeedCard.js +26 -0
  93. package/dist/tui/components/commerce/FeedCard.js.map +1 -0
  94. package/dist/tui/components/commerce/JobStatusCard.d.ts +17 -0
  95. package/dist/tui/components/commerce/JobStatusCard.d.ts.map +1 -0
  96. package/dist/tui/components/commerce/JobStatusCard.js +11 -0
  97. package/dist/tui/components/commerce/JobStatusCard.js.map +1 -0
  98. package/dist/tui/components/commerce/RoundsList.js +1 -1
  99. package/dist/tui/components/commerce/RoundsList.js.map +1 -1
  100. package/dist/tui/components/commerce/StandingsCard.d.ts +13 -0
  101. package/dist/tui/components/commerce/StandingsCard.d.ts.map +1 -0
  102. package/dist/tui/components/commerce/StandingsCard.js +9 -0
  103. package/dist/tui/components/commerce/StandingsCard.js.map +1 -0
  104. package/dist/tui/components/commerce/StatusCard.d.ts.map +1 -1
  105. package/dist/tui/components/commerce/StatusCard.js +1 -2
  106. package/dist/tui/components/commerce/StatusCard.js.map +1 -1
  107. package/dist/tui/components/commerce/common.d.ts.map +1 -1
  108. package/dist/tui/components/commerce/common.js +13 -12
  109. package/dist/tui/components/commerce/common.js.map +1 -1
  110. package/dist/tui/index.d.ts.map +1 -1
  111. package/dist/tui/index.js +3 -1
  112. package/dist/tui/index.js.map +1 -1
  113. package/dist/tui/kernel-payload.d.ts +23 -0
  114. package/dist/tui/kernel-payload.d.ts.map +1 -1
  115. package/dist/tui/kernel.d.ts.map +1 -1
  116. package/dist/tui/kernel.js +350 -2
  117. package/dist/tui/kernel.js.map +1 -1
  118. package/dist/tui/useDaemonEvents.d.ts.map +1 -1
  119. package/dist/tui/useDaemonEvents.js +142 -44
  120. package/dist/tui/useDaemonEvents.js.map +1 -1
  121. package/dist/tui/viewport-measure.d.ts +28 -0
  122. package/dist/tui/viewport-measure.d.ts.map +1 -0
  123. package/dist/tui/viewport-measure.js +35 -0
  124. package/dist/tui/viewport-measure.js.map +1 -0
  125. package/dist/ui/rpc-fallback.d.ts.map +1 -1
  126. package/dist/ui/rpc-fallback.js +4 -5
  127. package/dist/ui/rpc-fallback.js.map +1 -1
  128. package/dist/walletconnect.d.ts +1 -0
  129. package/dist/walletconnect.d.ts.map +1 -1
  130. package/dist/walletconnect.js +207 -128
  131. package/dist/walletconnect.js.map +1 -1
  132. package/package.json +2 -2
@@ -58,7 +58,6 @@ const telegram_notify_1 = require("../telegram-notify");
58
58
  const tree_1 = require("../ui/tree");
59
59
  const spinner_1 = require("../ui/spinner");
60
60
  const colors_1 = require("../ui/colors");
61
- const POLICY_ENGINE_DEFAULT = "0x44102e70c2A366632d98Fe40d892a2501fC7fFF2";
62
61
  const GUARDIAN_KEY_PATH = path_1.default.join(os_1.default.homedir(), ".arc402", "guardian.key");
63
62
  /** Save guardian private key to a restricted standalone file (never to config.json). */
64
63
  function saveGuardianKey(privateKey) {
@@ -86,6 +85,34 @@ function parseAmount(raw) {
86
85
  }
87
86
  return BigInt(raw);
88
87
  }
88
+ function resolvePolicyEngineAddress(config) {
89
+ return (config.policyEngineAddress ??
90
+ config_1.NETWORK_DEFAULTS[config.network]?.policyEngineAddress ??
91
+ "0x9449B15268bE7042C0b473F3f711a41A29220866");
92
+ }
93
+ function getWalletAddressFromFactoryLogs(factoryInterface, logs) {
94
+ for (const log of logs) {
95
+ try {
96
+ const parsed = factoryInterface.parseLog(log);
97
+ if (!parsed)
98
+ continue;
99
+ if (parsed.name === "WalletDeployed") {
100
+ const wallet = parsed.args.wallet ?? parsed.args.walletAddress ?? parsed.args[0];
101
+ if (wallet)
102
+ return ethers_1.ethers.getAddress(wallet);
103
+ }
104
+ if (parsed.name === "WalletCreated") {
105
+ const wallet = parsed.args.walletAddress ?? parsed.args.wallet ?? parsed.args[1] ?? parsed.args[0];
106
+ if (wallet)
107
+ return ethers_1.ethers.getAddress(wallet);
108
+ }
109
+ }
110
+ catch {
111
+ // skip unparseable logs
112
+ }
113
+ }
114
+ return null;
115
+ }
89
116
  // Standard onboarding categories required for a newly deployed wallet.
90
117
  // These cover the full ARC-402 flow: spending, hiring, compute, research, protocol ops.
91
118
  const ONBOARDING_CATEGORIES = [
@@ -102,7 +129,7 @@ const ONBOARDING_CATEGORIES = [
102
129
  * Skips registerWallet/enableDeFiAccess if they were already done by the wallet constructor.
103
130
  */
104
131
  async function runWalletOnboardingCeremony(walletAddress, ownerAddress, config, provider, sendTx) {
105
- const policyAddress = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
132
+ const policyAddress = resolvePolicyEngineAddress(config);
106
133
  const executeIface = new ethers_1.ethers.Interface(abis_1.ARC402_WALLET_EXECUTE_ABI);
107
134
  const govIface = new ethers_1.ethers.Interface(abis_1.POLICY_ENGINE_GOVERNANCE_ABI);
108
135
  const limitsIface = new ethers_1.ethers.Interface(abis_1.POLICY_ENGINE_LIMITS_ABI);
@@ -181,7 +208,7 @@ async function runWalletOnboardingCeremony(walletAddress, ownerAddress, config,
181
208
  * 6. Summary — branded tree
182
209
  */
183
210
  async function runCompleteOnboardingCeremony(walletAddress, ownerAddress, config, provider, sendTx) {
184
- const policyAddress = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
211
+ const policyAddress = resolvePolicyEngineAddress(config);
185
212
  const agentRegistryAddress = config.agentRegistryV2Address ??
186
213
  config_1.NETWORK_DEFAULTS[config.network]?.agentRegistryV2Address;
187
214
  const handshakeAddress = config.handshakeAddress ??
@@ -703,22 +730,33 @@ function registerWalletCommands(program) {
703
730
  // ─── new ───────────────────────────────────────────────────────────────────
704
731
  wallet.command("new")
705
732
  .description("Generate a fresh keypair and save to config")
706
- .option("--network <network>", "Network (base-mainnet or base-sepolia)", "base-sepolia")
733
+ .option("--network <network>", "Network (base-mainnet or base-sepolia)")
707
734
  .action(async (opts) => {
708
- const network = opts.network;
735
+ const existing = fs_1.default.existsSync((0, config_1.getConfigPath)()) ? (0, config_1.loadConfig)() : undefined;
736
+ const network = (opts.network ?? existing?.network ?? "base-mainnet");
709
737
  const defaults = config_1.NETWORK_DEFAULTS[network];
710
738
  if (!defaults) {
711
739
  console.error(`Unknown network: ${network}. Use base-mainnet or base-sepolia.`);
712
740
  process.exit(1);
713
741
  }
714
742
  const generated = ethers_1.ethers.Wallet.createRandom();
743
+ const networkChanged = !!existing && existing.network !== network;
715
744
  const config = {
745
+ ...(existing ?? {}),
716
746
  network,
717
747
  rpcUrl: defaults.rpcUrl,
718
748
  privateKey: generated.privateKey,
719
749
  trustRegistryAddress: defaults.trustRegistryAddress,
750
+ policyEngineAddress: defaults.policyEngineAddress,
720
751
  walletFactoryAddress: defaults.walletFactoryAddress,
752
+ agentRegistryV2Address: defaults.agentRegistryV2Address,
721
753
  };
754
+ if (networkChanged) {
755
+ delete config.walletContractAddress;
756
+ delete config.ownerAddress;
757
+ delete config.onboardingProgress;
758
+ delete config.wcSession;
759
+ }
722
760
  (0, config_1.saveConfig)(config);
723
761
  (0, tree_1.renderTree)([
724
762
  { label: "Address", value: generated.address },
@@ -729,10 +767,11 @@ function registerWalletCommands(program) {
729
767
  // ─── import ────────────────────────────────────────────────────────────────
730
768
  wallet.command("import")
731
769
  .description("Import an existing private key (use --key-file or stdin prompt)")
732
- .option("--network <network>", "Network (base-mainnet or base-sepolia)", "base-sepolia")
770
+ .option("--network <network>", "Network (base-mainnet or base-sepolia)")
733
771
  .option("--key-file <path>", "Read private key from file instead of prompting")
734
772
  .action(async (opts) => {
735
- const network = opts.network;
773
+ const existing = fs_1.default.existsSync((0, config_1.getConfigPath)()) ? (0, config_1.loadConfig)() : undefined;
774
+ const network = (opts.network ?? existing?.network ?? "base-mainnet");
736
775
  const defaults = config_1.NETWORK_DEFAULTS[network];
737
776
  if (!defaults) {
738
777
  console.error(`Unknown network: ${network}. Use base-mainnet or base-sepolia.`);
@@ -769,13 +808,23 @@ function registerWalletCommands(program) {
769
808
  console.error("Invalid private key. Must be a 0x-prefixed hex string.");
770
809
  process.exit(1);
771
810
  }
811
+ const networkChanged = !!existing && existing.network !== network;
772
812
  const config = {
813
+ ...(existing ?? {}),
773
814
  network,
774
815
  rpcUrl: defaults.rpcUrl,
775
816
  privateKey: imported.privateKey,
776
817
  trustRegistryAddress: defaults.trustRegistryAddress,
818
+ policyEngineAddress: defaults.policyEngineAddress,
777
819
  walletFactoryAddress: defaults.walletFactoryAddress,
820
+ agentRegistryV2Address: defaults.agentRegistryV2Address,
778
821
  };
822
+ if (networkChanged) {
823
+ delete config.walletContractAddress;
824
+ delete config.ownerAddress;
825
+ delete config.onboardingProgress;
826
+ delete config.wcSession;
827
+ }
779
828
  (0, config_1.saveConfig)(config);
780
829
  (0, tree_1.renderTree)([
781
830
  { label: "Address", value: imported.address },
@@ -1054,18 +1103,8 @@ function registerWalletCommands(program) {
1054
1103
  console.error("Transaction not confirmed. Check on-chain.");
1055
1104
  process.exit(1);
1056
1105
  }
1057
- let walletAddress = null;
1058
1106
  const factoryContract = new ethers_1.ethers.Contract(factoryAddress, abis_1.WALLET_FACTORY_ABI, provider);
1059
- for (const log of receipt.logs) {
1060
- try {
1061
- const parsed = factoryContract.interface.parseLog(log);
1062
- if (parsed?.name === "WalletDeployed" || parsed?.name === "WalletCreated") {
1063
- walletAddress = parsed.args.walletAddress;
1064
- break;
1065
- }
1066
- }
1067
- catch { /* skip unparseable logs */ }
1068
- }
1107
+ const walletAddress = getWalletAddressFromFactoryLogs(factoryContract.interface, receipt.logs);
1069
1108
  if (!walletAddress) {
1070
1109
  console.error("Could not find WalletDeployed/WalletCreated event in receipt. Check the transaction on-chain.");
1071
1110
  process.exit(1);
@@ -1156,18 +1195,8 @@ function registerWalletCommands(program) {
1156
1195
  console.error("Transaction not confirmed. Check on-chain.");
1157
1196
  process.exit(1);
1158
1197
  }
1159
- let deployedWallet = null;
1160
1198
  const factoryContract = new ethers_1.ethers.Contract(factoryAddress, abis_1.WALLET_FACTORY_ABI, provider);
1161
- for (const log of receipt.logs) {
1162
- try {
1163
- const parsed = factoryContract.interface.parseLog(log);
1164
- if (parsed?.name === "WalletDeployed" || parsed?.name === "WalletCreated") {
1165
- deployedWallet = parsed.args.walletAddress;
1166
- break;
1167
- }
1168
- }
1169
- catch { /* skip unparseable logs */ }
1170
- }
1199
+ const deployedWallet = getWalletAddressFromFactoryLogs(factoryContract.interface, receipt.logs);
1171
1200
  if (!deployedWallet) {
1172
1201
  console.error("Could not find WalletDeployed/WalletCreated event in receipt. Check the transaction on-chain.");
1173
1202
  process.exit(1);
@@ -1207,17 +1236,7 @@ function registerWalletCommands(program) {
1207
1236
  const deploySpinner = (0, spinner_1.startSpinner)(`Deploying ARC402Wallet via factory at ${factoryAddress}...`);
1208
1237
  const tx = await factory["deployWallet()"]();
1209
1238
  const receipt = await tx.wait();
1210
- let walletAddress = null;
1211
- for (const log of receipt.logs) {
1212
- try {
1213
- const parsed = factory.interface.parseLog(log);
1214
- if (parsed?.name === "WalletDeployed" || parsed?.name === "WalletDeployed" || parsed?.name === "WalletCreated") {
1215
- walletAddress = parsed.args.walletAddress;
1216
- break;
1217
- }
1218
- }
1219
- catch { /* skip unparseable logs */ }
1220
- }
1239
+ const walletAddress = getWalletAddressFromFactoryLogs(factory.interface, receipt.logs);
1221
1240
  if (!walletAddress) {
1222
1241
  deploySpinner.fail("Could not find WalletDeployed/WalletCreated event in receipt. Check the transaction on-chain.");
1223
1242
  process.exit(1);
@@ -1277,7 +1296,7 @@ function registerWalletCommands(program) {
1277
1296
  process.exit(1);
1278
1297
  }
1279
1298
  const walletAddress = config.walletContractAddress;
1280
- const policyAddress = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
1299
+ const policyAddress = resolvePolicyEngineAddress(config);
1281
1300
  const chainId = config.network === "base-mainnet" ? 8453 : 84532;
1282
1301
  const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
1283
1302
  // Resolve protocol contracts to whitelist
@@ -1490,7 +1509,7 @@ function registerWalletCommands(program) {
1490
1509
  .requiredOption("--category <cat>", "Category name (e.g. code.review)")
1491
1510
  .action(async (opts) => {
1492
1511
  const config = (0, config_1.loadConfig)();
1493
- const policyAddress = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
1512
+ const policyAddress = resolvePolicyEngineAddress(config);
1494
1513
  const walletAddr = config.walletContractAddress;
1495
1514
  if (!walletAddr) {
1496
1515
  console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
@@ -1516,7 +1535,7 @@ function registerWalletCommands(program) {
1516
1535
  .requiredOption("--amount <eth>", "Limit in ETH (e.g. 0.1)")
1517
1536
  .action(async (opts) => {
1518
1537
  const config = (0, config_1.loadConfig)();
1519
- const policyAddress = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
1538
+ const policyAddress = resolvePolicyEngineAddress(config);
1520
1539
  const chainId = config.network === "base-mainnet" ? 8453 : 84532;
1521
1540
  const amount = ethers_1.ethers.parseEther(opts.amount);
1522
1541
  const policyInterface = new ethers_1.ethers.Interface(abis_1.POLICY_ENGINE_LIMITS_ABI);
@@ -1564,7 +1583,7 @@ function registerWalletCommands(program) {
1564
1583
  console.log(` 1. Wallet-level (arc402 wallet set-velocity-limit): ETH cap per rolling hour, enforced by ARC402Wallet contract. Breach auto-freezes wallet.`);
1565
1584
  console.log(` 2. PolicyEngine-level (arc402 wallet policy set-daily-limit): Per-category daily cap, enforced by PolicyEngine. Breach returns a soft error without freezing.`);
1566
1585
  console.log(` Both must be configured for full protection.\n`);
1567
- const policyAddress = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
1586
+ const policyAddress = resolvePolicyEngineAddress(config);
1568
1587
  const chainId = config.network === "base-mainnet" ? 8453 : 84532;
1569
1588
  const walletAddr = config.walletContractAddress;
1570
1589
  if (!walletAddr) {
@@ -1607,7 +1626,7 @@ function registerWalletCommands(program) {
1607
1626
  .option("--protocol <eth>", "Protocol limit", "0.1")
1608
1627
  .action(async (opts) => {
1609
1628
  const config = (0, config_1.loadConfig)();
1610
- const policyAddress = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
1629
+ const policyAddress = resolvePolicyEngineAddress(config);
1611
1630
  const chainId = config.network === "base-mainnet" ? 8453 : 84532;
1612
1631
  const walletAddr = config.walletContractAddress;
1613
1632
  if (!walletAddr) {
@@ -2050,7 +2069,7 @@ function registerWalletCommands(program) {
2050
2069
  console.error(`Invalid address: ${target}`);
2051
2070
  process.exit(1);
2052
2071
  }
2053
- const policyAddress = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
2072
+ const policyAddress = resolvePolicyEngineAddress(config);
2054
2073
  const chainId = config.network === "base-mainnet" ? 8453 : 84532;
2055
2074
  const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
2056
2075
  // Check if already whitelisted
@@ -2211,7 +2230,7 @@ function registerWalletCommands(program) {
2211
2230
  console.error("walletConnectProjectId not set in config. Run `arc402 config set walletConnectProjectId <id>`.");
2212
2231
  process.exit(1);
2213
2232
  }
2214
- const policyAddress = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
2233
+ const policyAddress = resolvePolicyEngineAddress(config);
2215
2234
  const chainId = config.network === "base-mainnet" ? 8453 : 84532;
2216
2235
  const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
2217
2236
  let ownerAddress = config.ownerAddress;
@@ -2339,7 +2358,7 @@ function registerWalletCommands(program) {
2339
2358
  console.error("walletConnectProjectId not set in config. Run `arc402 config set walletConnectProjectId <id>`.");
2340
2359
  process.exit(1);
2341
2360
  }
2342
- const policyAddress = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
2361
+ const policyAddress = resolvePolicyEngineAddress(config);
2343
2362
  const chainId = config.network === "base-mainnet" ? 8453 : 84532;
2344
2363
  // ── Step 1: velocity limit ────────────────────────────────────────────
2345
2364
  const { velocityEth } = await (0, prompts_1.default)({
@@ -3077,7 +3096,7 @@ function registerWalletCommands(program) {
3077
3096
  process.exit(1);
3078
3097
  }
3079
3098
  // Check category is configured on PolicyEngine
3080
- const policyAddress = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
3099
+ const policyAddress = resolvePolicyEngineAddress(config);
3081
3100
  const policyContract = new ethers_1.ethers.Contract(policyAddress, abis_1.POLICY_ENGINE_LIMITS_ABI, provider);
3082
3101
  const categoryLimit = await policyContract.categoryLimits(walletAddr, opts.category);
3083
3102
  if (categoryLimit === 0n) {
@@ -3330,7 +3349,7 @@ function registerWalletCommands(program) {
3330
3349
  process.exit(1);
3331
3350
  }
3332
3351
  // Check category is configured on PolicyEngine
3333
- const policyAddressT = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
3352
+ const policyAddressT = resolvePolicyEngineAddress(config);
3334
3353
  const policyContractT = new ethers_1.ethers.Contract(policyAddressT, abis_1.POLICY_ENGINE_LIMITS_ABI, provider);
3335
3354
  const categoryLimitT = await policyContractT.categoryLimits(walletAddr, opts.category);
3336
3355
  if (categoryLimitT === 0n) {