arc402-cli 0.4.0 → 0.4.2

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 (87) hide show
  1. package/dist/commands/arbitrator.d.ts.map +1 -1
  2. package/dist/commands/arbitrator.js +62 -13
  3. package/dist/commands/arbitrator.js.map +1 -1
  4. package/dist/commands/arena.d.ts.map +1 -1
  5. package/dist/commands/arena.js +4 -3
  6. package/dist/commands/arena.js.map +1 -1
  7. package/dist/commands/cancel.d.ts.map +1 -1
  8. package/dist/commands/cancel.js +20 -10
  9. package/dist/commands/cancel.js.map +1 -1
  10. package/dist/commands/config.d.ts.map +1 -1
  11. package/dist/commands/config.js +1 -0
  12. package/dist/commands/config.js.map +1 -1
  13. package/dist/commands/deliver.d.ts.map +1 -1
  14. package/dist/commands/deliver.js +16 -3
  15. package/dist/commands/deliver.js.map +1 -1
  16. package/dist/commands/discover.d.ts.map +1 -1
  17. package/dist/commands/discover.js +2 -0
  18. package/dist/commands/discover.js.map +1 -1
  19. package/dist/commands/dispute.d.ts.map +1 -1
  20. package/dist/commands/dispute.js +11 -10
  21. package/dist/commands/dispute.js.map +1 -1
  22. package/dist/commands/hire.d.ts.map +1 -1
  23. package/dist/commands/hire.js +12 -2
  24. package/dist/commands/hire.js.map +1 -1
  25. package/dist/commands/migrate.d.ts.map +1 -1
  26. package/dist/commands/migrate.js +29 -29
  27. package/dist/commands/migrate.js.map +1 -1
  28. package/dist/commands/negotiate.d.ts.map +1 -1
  29. package/dist/commands/negotiate.js +8 -7
  30. package/dist/commands/negotiate.js.map +1 -1
  31. package/dist/commands/openshell.d.ts.map +1 -1
  32. package/dist/commands/openshell.js +6 -5
  33. package/dist/commands/openshell.js.map +1 -1
  34. package/dist/commands/owner.d.ts.map +1 -1
  35. package/dist/commands/owner.js +2 -1
  36. package/dist/commands/owner.js.map +1 -1
  37. package/dist/commands/policy.d.ts.map +1 -1
  38. package/dist/commands/policy.js +22 -10
  39. package/dist/commands/policy.js.map +1 -1
  40. package/dist/commands/relay.js +6 -5
  41. package/dist/commands/relay.js.map +1 -1
  42. package/dist/commands/remediate.js +3 -2
  43. package/dist/commands/remediate.js.map +1 -1
  44. package/dist/commands/reputation.d.ts.map +1 -1
  45. package/dist/commands/reputation.js +12 -5
  46. package/dist/commands/reputation.js.map +1 -1
  47. package/dist/commands/trust.d.ts.map +1 -1
  48. package/dist/commands/trust.js +16 -1
  49. package/dist/commands/trust.js.map +1 -1
  50. package/dist/commands/verify.d.ts.map +1 -1
  51. package/dist/commands/verify.js +6 -4
  52. package/dist/commands/verify.js.map +1 -1
  53. package/dist/commands/wallet.d.ts.map +1 -1
  54. package/dist/commands/wallet.js +202 -165
  55. package/dist/commands/wallet.js.map +1 -1
  56. package/dist/commands/watchtower.d.ts.map +1 -1
  57. package/dist/commands/watchtower.js +30 -13
  58. package/dist/commands/watchtower.js.map +1 -1
  59. package/dist/commands/workroom.d.ts.map +1 -1
  60. package/dist/commands/workroom.js +123 -95
  61. package/dist/commands/workroom.js.map +1 -1
  62. package/dist/config.d.ts.map +1 -1
  63. package/dist/config.js +1 -0
  64. package/dist/config.js.map +1 -1
  65. package/package.json +1 -1
  66. package/src/commands/arbitrator.ts +45 -10
  67. package/src/commands/arena.ts +4 -3
  68. package/src/commands/cancel.ts +19 -10
  69. package/src/commands/config.ts +1 -0
  70. package/src/commands/deliver.ts +16 -3
  71. package/src/commands/discover.ts +2 -0
  72. package/src/commands/dispute.ts +12 -10
  73. package/src/commands/hire.ts +9 -2
  74. package/src/commands/migrate.ts +28 -26
  75. package/src/commands/negotiate.ts +8 -7
  76. package/src/commands/openshell.ts +7 -5
  77. package/src/commands/owner.ts +2 -1
  78. package/src/commands/policy.ts +18 -10
  79. package/src/commands/relay.ts +5 -5
  80. package/src/commands/remediate.ts +2 -2
  81. package/src/commands/reputation.ts +9 -5
  82. package/src/commands/trust.ts +10 -1
  83. package/src/commands/verify.ts +5 -4
  84. package/src/commands/wallet.ts +203 -165
  85. package/src/commands/watchtower.ts +25 -13
  86. package/src/commands/workroom.ts +121 -95
  87. package/src/config.ts +2 -1
@@ -20,6 +20,7 @@ import { sendTelegramMessage } from "../telegram-notify";
20
20
  import { renderTree } from "../ui/tree";
21
21
  import { startSpinner } from "../ui/spinner";
22
22
  import { c } from "../ui/colors";
23
+ import { formatAddress } from "../ui/format";
23
24
 
24
25
  const POLICY_ENGINE_DEFAULT = "0x44102e70c2A366632d98Fe40d892a2501fC7fFF2";
25
26
 
@@ -69,9 +70,9 @@ async function runWalletOnboardingCeremony(
69
70
  alreadyDefiEnabled = await policyGov.defiAccessEnabled(walletAddress);
70
71
  } catch { /* assume not enabled */ }
71
72
 
72
- console.log("\n── Onboarding ceremony ────────────────────────────────────────");
73
- console.log(` PolicyEngine: ${policyAddress}`);
74
- console.log(` Wallet: ${walletAddress}`);
73
+ console.log("\n" + c.dim("── Onboarding ceremony ────────────────────────────────────────"));
74
+ console.log(" " + c.dim("PolicyEngine:") + " " + c.white(policyAddress));
75
+ console.log(" " + c.dim("Wallet: ") + " " + c.white(walletAddress));
75
76
 
76
77
  // Step 1: registerWallet (if not already done)
77
78
  if (!alreadyRegistered) {
@@ -89,7 +90,7 @@ async function runWalletOnboardingCeremony(
89
90
  value: "0x0",
90
91
  }, "registerWallet on PolicyEngine");
91
92
  } else {
92
- console.log(" registerWallet — already done by constructor");
93
+ console.log(" " + c.success + c.dim(" registerWallet — already done by constructor"));
93
94
  }
94
95
 
95
96
  // Step 2: enableDefiAccess (if not already done)
@@ -100,7 +101,7 @@ async function runWalletOnboardingCeremony(
100
101
  value: "0x0",
101
102
  }, "enableDefiAccess on PolicyEngine");
102
103
  } else {
103
- console.log(" enableDefiAccess — already done by constructor");
104
+ console.log(" " + c.success + c.dim(" enableDefiAccess — already done by constructor"));
104
105
  }
105
106
 
106
107
  // Steps 3–6: category limits (always set — idempotent)
@@ -116,10 +117,10 @@ async function runWalletOnboardingCeremony(
116
117
  }, `setCategoryLimitFor: ${name} → ${amountEth} ETH`);
117
118
  }
118
119
 
119
- console.log("── Onboarding complete ─────────────────────────────────────────");
120
- console.log("💡 Tip: For production security, also configure:");
121
- console.log(" arc402 wallet set-velocity-limit <eth> — wallet-level hourly ETH cap");
122
- console.log(" arc402 wallet policy set-daily-limit --category general --amount <eth> — daily per-category cap");
120
+ console.log(c.dim("── Onboarding complete ─────────────────────────────────────────"));
121
+ console.log(c.dim("Tip: For production security, also configure:"));
122
+ console.log(" " + c.dim("arc402 wallet set-velocity-limit <eth> — wallet-level hourly ETH cap"));
123
+ console.log(" " + c.dim("arc402 wallet policy set-daily-limit --category general --amount <eth> — daily per-category cap"));
123
124
  }
124
125
 
125
126
  function printOpenShellHint(): void {
@@ -177,10 +178,18 @@ export function registerWalletCommands(program: Command): void {
177
178
  if (opts.json) {
178
179
  console.log(JSON.stringify(payload, null, 2));
179
180
  } else {
180
- console.log(`${payload.address}\nETH=${payload.ethBalance}\nUSDC=${payload.usdcBalance}\nTrust=${payload.trustScore} ${payload.trustTier}`);
181
- if (payload.walletContractAddress) console.log(`Contract=${payload.walletContractAddress}`);
182
- if (contractFrozen !== null) console.log(`Frozen=${contractFrozen}`);
183
- if (contractGuardian && contractGuardian !== ethers.ZeroAddress) console.log(`Guardian=${contractGuardian}`);
181
+ const treeItems: { label: string; value: string; last?: boolean }[] = [
182
+ { label: "Address", value: payload.address },
183
+ { label: "Network", value: payload.network },
184
+ { label: "ETH", value: payload.ethBalance + " ETH" },
185
+ { label: "USDC", value: payload.usdcBalance + " USDC" },
186
+ { label: "Trust", value: `${payload.trustScore} ${payload.trustTier}` },
187
+ ];
188
+ if (payload.walletContractAddress) treeItems.push({ label: "Contract", value: payload.walletContractAddress });
189
+ if (contractFrozen !== null) treeItems.push({ label: "Frozen", value: contractFrozen ? c.red("YES") : c.green("no") });
190
+ if (contractGuardian && contractGuardian !== ethers.ZeroAddress) treeItems.push({ label: "Guardian", value: contractGuardian });
191
+ treeItems[treeItems.length - 1].last = true;
192
+ renderTree(treeItems);
184
193
  }
185
194
  });
186
195
 
@@ -215,7 +224,7 @@ export function registerWalletCommands(program: Command): void {
215
224
  if (opts.json) {
216
225
  console.log(JSON.stringify({ ok: false, error: `Could not delete ${wcStoragePath}: ${msg}` }));
217
226
  } else {
218
- console.warn(`⚠ Could not delete ${wcStoragePath}: ${msg}`);
227
+ console.warn(" " + c.warning + " " + c.yellow(`Could not delete ${wcStoragePath}: ${msg}`));
219
228
  console.warn(" You may need to delete it manually.");
220
229
  }
221
230
  return;
@@ -224,10 +233,10 @@ export function registerWalletCommands(program: Command): void {
224
233
  if (opts.json) {
225
234
  console.log(JSON.stringify({ ok: true, hadSession, storageWiped }));
226
235
  } else {
227
- console.log(" WalletConnect session cleared");
228
- if (storageWiped) console.log(` Storage wiped: ${wcStoragePath}`);
229
- else console.log(" (No storage file found — already clean)");
230
- console.log("\nNext: run any wallet command and scan the fresh QR code.");
236
+ console.log(" " + c.success + c.white(" WalletConnect session cleared"));
237
+ if (storageWiped) console.log(" " + c.dim("Storage wiped:") + " " + c.white(wcStoragePath));
238
+ else console.log(" " + c.dim("(No storage file found — already clean)"));
239
+ console.log("\n" + c.dim("Next: run any wallet command and scan the fresh QR code."));
231
240
  }
232
241
  });
233
242
 
@@ -252,9 +261,11 @@ export function registerWalletCommands(program: Command): void {
252
261
  walletFactoryAddress: defaults.walletFactoryAddress,
253
262
  };
254
263
  saveConfig(config);
255
- console.log(`Address: ${generated.address}`);
256
- console.log(`Config saved to ${getConfigPath()}`);
257
- console.log(`Next: fund your wallet with ETH, then run: arc402 wallet deploy`);
264
+ renderTree([
265
+ { label: "Address", value: generated.address },
266
+ { label: "Config", value: getConfigPath(), last: true },
267
+ ]);
268
+ console.log(c.dim("Next: fund your wallet with ETH, then run: arc402 wallet deploy"));
258
269
  });
259
270
 
260
271
  // ─── import ────────────────────────────────────────────────────────────────
@@ -284,9 +295,11 @@ export function registerWalletCommands(program: Command): void {
284
295
  walletFactoryAddress: defaults.walletFactoryAddress,
285
296
  };
286
297
  saveConfig(config);
287
- console.log(`Address: ${imported.address}`);
288
- console.log(`Config saved to ${getConfigPath()}`);
289
- console.warn(`WARN: Store your private key safely — anyone with it controls your wallet`);
298
+ renderTree([
299
+ { label: "Address", value: imported.address },
300
+ { label: "Config", value: getConfigPath(), last: true },
301
+ ]);
302
+ console.warn(" " + c.warning + " " + c.yellow("Store your private key safely — anyone with it controls your wallet"));
290
303
  });
291
304
 
292
305
  // ─── fund ──────────────────────────────────────────────────────────────────
@@ -524,16 +537,19 @@ export function registerWalletCommands(program: Command): void {
524
537
  config.walletContractAddress = senderAddress;
525
538
  config.ownerAddress = ownerAddress;
526
539
  saveConfig(config);
527
- console.log(`\n ARC402Wallet deployed (sponsored) at: ${senderAddress}`);
528
- console.log("Gas sponsorship active — initial setup ops are free");
529
- console.log(`Owner: ${ownerAddress}`);
530
- console.log(`\n⚠ IMPORTANT: Onboarding ceremony was not run on this wallet.`);
531
- console.log(` Category spend limits have NOT been configured. All executeSpend and`);
532
- console.log(` executeTokenSpend calls will fail with "PolicyEngine: category not configured"`);
533
- console.log(` until you run governance setup manually via WalletConnect:`);
534
- console.log(`\n arc402 wallet governance setup`);
535
- console.log(`\n This must be done before making any spend from this wallet.`);
536
- console.log(`\nNext: arc402 wallet set-passkey <x> <y> --sponsored`);
540
+ console.log("\n" + c.success + c.white(" ARC402Wallet deployed (sponsored)"));
541
+ renderTree([
542
+ { label: "Wallet", value: senderAddress },
543
+ { label: "Owner", value: ownerAddress },
544
+ { label: "Gas", value: "Sponsorship active initial setup ops are free", last: true },
545
+ ]);
546
+ console.log(" " + c.warning + " " + c.yellow("IMPORTANT: Onboarding ceremony was not run on this wallet."));
547
+ console.log(c.dim(" Category spend limits have NOT been configured. All executeSpend and"));
548
+ console.log(c.dim(` executeTokenSpend calls will fail with "PolicyEngine: category not configured"`));
549
+ console.log(c.dim(" until you run governance setup manually via WalletConnect:"));
550
+ console.log("\n" + c.dim(" arc402 wallet governance setup"));
551
+ console.log("\n" + c.dim(" This must be done before making any spend from this wallet."));
552
+ console.log("\n" + c.dim("Next: arc402 wallet set-passkey <x> <y> --sponsored"));
537
553
  printOpenShellHint();
538
554
  } else if (opts.smartWallet) {
539
555
  const { txHash, account } = await requestCoinbaseSmartWalletSignature(
@@ -570,10 +586,13 @@ export function registerWalletCommands(program: Command): void {
570
586
  config.walletContractAddress = walletAddress;
571
587
  config.ownerAddress = account;
572
588
  saveConfig(config);
573
- console.log(`ARC402Wallet deployed at: ${walletAddress}`);
574
- console.log(`Owner: ${account} (your Base Smart Wallet)`);
575
- console.log(`Your wallet contract is ready for policy enforcement`);
576
- console.log(`\nNext: run 'arc402 wallet set-guardian' to configure the emergency guardian key.`);
589
+ console.log("\n" + c.success + c.white(" ARC402Wallet deployed"));
590
+ renderTree([
591
+ { label: "Wallet", value: walletAddress },
592
+ { label: "Owner", value: account + c.dim(" (Base Smart Wallet)"), last: true },
593
+ ]);
594
+ console.log(c.dim("Your wallet contract is ready for policy enforcement"));
595
+ console.log(c.dim("\nNext: run 'arc402 wallet set-guardian' to configure the emergency guardian key."));
577
596
  printOpenShellHint();
578
597
  } else if (config.walletConnectProjectId) {
579
598
  const telegramOpts = config.telegramBotToken && config.telegramChatId
@@ -590,7 +609,7 @@ export function registerWalletCommands(program: Command): void {
590
609
 
591
610
  const networkName = chainId === 8453 ? "Base" : "Base Sepolia";
592
611
  const shortAddr = `${account.slice(0, 6)}...${account.slice(-5)}`;
593
- console.log(`\n Connected: ${shortAddr} on ${networkName}`);
612
+ console.log("\n" + c.success + c.white(` Connected: ${shortAddr} on ${networkName}`));
594
613
 
595
614
  if (telegramOpts) {
596
615
  // Send "connected" message with a deploy confirmation button.
@@ -639,8 +658,11 @@ export function registerWalletCommands(program: Command): void {
639
658
  config.walletContractAddress = walletAddress;
640
659
  config.ownerAddress = account;
641
660
  saveConfig(config);
642
- console.log(`\n ARC402Wallet deployed at: ${walletAddress}`);
643
- console.log(`Owner: ${account} (your phone wallet)`);
661
+ console.log("\n" + c.success + c.white(" ARC402Wallet deployed"));
662
+ renderTree([
663
+ { label: "Wallet", value: walletAddress },
664
+ { label: "Owner", value: account + c.dim(" (phone wallet)"), last: true },
665
+ ]);
644
666
 
645
667
  // ── Mandatory onboarding ceremony (same WalletConnect session) ────────
646
668
  console.log("\nStarting mandatory onboarding ceremony in this WalletConnect session...");
@@ -650,21 +672,21 @@ export function registerWalletCommands(program: Command): void {
650
672
  config,
651
673
  provider,
652
674
  async (call, description) => {
653
- console.log(` Sending: ${description}`);
675
+ console.log(" " + c.dim(`Sending: ${description}`));
654
676
  const hash = await sendTransactionWithSession(client, session, account, chainId, call);
655
677
  await provider.waitForTransaction(hash, 1);
656
- console.log(` ✓ ${description}: ${hash}`);
678
+ console.log(" " + c.success + " " + c.dim(description) + " " + c.dim(hash));
657
679
  return hash;
658
680
  },
659
681
  );
660
682
 
661
- console.log(`Your wallet contract is ready for policy enforcement`);
683
+ console.log(c.dim("Your wallet contract is ready for policy enforcement"));
662
684
  const paymasterUrl2 = config.paymasterUrl ?? NETWORK_DEFAULTS[config.network]?.paymasterUrl;
663
685
  const deployedBalance = await provider.getBalance(walletAddress);
664
686
  if (paymasterUrl2 && deployedBalance < BigInt(1_000_000_000_000_000)) {
665
- console.log("Gas sponsorship active — initial setup ops are free");
687
+ console.log(c.dim("Gas sponsorship active — initial setup ops are free"));
666
688
  }
667
- console.log(`\nNext: run 'arc402 wallet set-guardian' to configure the emergency guardian key.`);
689
+ console.log(c.dim("\nNext: run 'arc402 wallet set-guardian' to configure the emergency guardian key."));
668
690
  printOpenShellHint();
669
691
  } else {
670
692
  console.warn("⚠ WalletConnect not configured. Using stored private key (insecure).");
@@ -711,10 +733,10 @@ export function registerWalletCommands(program: Command): void {
711
733
  config,
712
734
  provider2,
713
735
  async (call, description) => {
714
- console.log(` Sending: ${description}`);
736
+ console.log(" " + c.dim(`Sending: ${description}`));
715
737
  const tx2 = await signer.sendTransaction({ to: call.to, data: call.data, value: call.value === "0x0" ? 0n : BigInt(call.value) });
716
738
  await tx2.wait(1);
717
- console.log(` ✓ ${description}: ${tx2.hash}`);
739
+ console.log(" " + c.success + " " + c.dim(description) + " " + c.dim(tx2.hash));
718
740
  return tx2.hash;
719
741
  },
720
742
  );
@@ -935,9 +957,9 @@ export function registerWalletCommands(program: Command): void {
935
957
  );
936
958
 
937
959
  await provider.waitForTransaction(txHash);
938
- console.log(`\n Active policy updated`);
939
- console.log(` Tx: ${txHash}`);
940
- console.log(` Policy: ${policyIdHex}`);
960
+ console.log("\n" + c.success + c.white(" Active policy updated"));
961
+ console.log(" " + c.dim("Tx:") + " " + c.white(txHash));
962
+ console.log(" " + c.dim("Policy:") + " " + c.white(policyIdHex));
941
963
  });
942
964
 
943
965
  // ─── freeze (guardian key — emergency wallet freeze) ──────────────────────
@@ -1021,11 +1043,11 @@ export function registerWalletCommands(program: Command): void {
1021
1043
 
1022
1044
  const networkName = chainId === 8453 ? "Base" : "Base Sepolia";
1023
1045
  const shortAddr = `${account.slice(0, 6)}...${account.slice(-5)}`;
1024
- console.log(`\n Connected: ${shortAddr} on ${networkName}`);
1025
- console.log(`\nWallet to unfreeze: ${config.walletContractAddress}`);
1046
+ console.log("\n" + c.success + c.white(` Connected: ${shortAddr} on ${networkName}`));
1047
+ console.log("\n" + c.dim("Wallet to unfreeze:") + " " + c.white(config.walletContractAddress ?? ""));
1026
1048
  // WalletConnect approval already confirmed intent — sending automatically
1027
1049
 
1028
- console.log("Sending transaction...");
1050
+ console.log(c.dim("Sending transaction..."));
1029
1051
  const txHash = await sendTransactionWithSession(client, session, account, chainId, {
1030
1052
  to: config.walletContractAddress,
1031
1053
  data: walletInterface.encodeFunctionData("unfreeze", []),
@@ -1036,8 +1058,8 @@ export function registerWalletCommands(program: Command): void {
1036
1058
  if (opts.json) {
1037
1059
  console.log(JSON.stringify({ txHash, walletAddress: config.walletContractAddress }));
1038
1060
  } else {
1039
- console.log(`\n Wallet ${config.walletContractAddress} unfrozen`);
1040
- console.log(` Tx: ${txHash}`);
1061
+ console.log("\n" + c.success + c.white(` Wallet ${config.walletContractAddress} unfrozen`));
1062
+ console.log(" " + c.dim("Tx:") + " " + c.white(txHash));
1041
1063
  }
1042
1064
  });
1043
1065
 
@@ -1094,10 +1116,10 @@ export function registerWalletCommands(program: Command): void {
1094
1116
 
1095
1117
  const networkName = chainId === 8453 ? "Base" : "Base Sepolia";
1096
1118
  const shortAddr = `${account.slice(0, 6)}...${account.slice(-5)}`;
1097
- console.log(`\n Connected: ${shortAddr} on ${networkName}`);
1119
+ console.log("\n" + c.success + c.white(` Connected: ${shortAddr} on ${networkName}`));
1098
1120
  // WalletConnect approval already confirmed intent — sending automatically
1099
1121
 
1100
- console.log("Sending transaction...");
1122
+ console.log(c.dim("Sending transaction..."));
1101
1123
  const txHash = await sendTransactionWithSession(client, session, account, chainId, {
1102
1124
  to: config.walletContractAddress,
1103
1125
  data: walletInterface.encodeFunctionData("setGuardian", [guardianWallet.address]),
@@ -1108,10 +1130,10 @@ export function registerWalletCommands(program: Command): void {
1108
1130
  config.guardianPrivateKey = guardianWallet.privateKey;
1109
1131
  config.guardianAddress = guardianWallet.address;
1110
1132
  saveConfig(config);
1111
- console.log(`\n Guardian set to: ${guardianWallet.address}`);
1112
- console.log(` Tx: ${txHash}`);
1113
- console.log(` Guardian private key saved to config.`);
1114
- console.log(` WARN: The guardian key can freeze your wallet. Store it separately from your hot key.`);
1133
+ console.log("\n" + c.success + c.white(` Guardian set to: ${guardianWallet.address}`));
1134
+ console.log(" " + c.dim("Tx:") + " " + c.white(txHash));
1135
+ console.log(" " + c.dim("Guardian private key saved to config."));
1136
+ console.log(" " + c.warning + " " + c.yellow("The guardian key can freeze your wallet. Store it separately from your hot key."));
1115
1137
  });
1116
1138
 
1117
1139
  // ─── policy-engine freeze / unfreeze (legacy — for PolicyEngine-level freeze) ──
@@ -1208,11 +1230,11 @@ export function registerWalletCommands(program: Command): void {
1208
1230
 
1209
1231
  const networkName = chainId === 8453 ? "Base" : "Base Sepolia";
1210
1232
  const shortAddr = `${account.slice(0, 6)}...${account.slice(-5)}`;
1211
- console.log(`\n Connected: ${shortAddr} on ${networkName}`);
1233
+ console.log("\n" + c.success + c.white(` Connected: ${shortAddr} on ${networkName}`));
1212
1234
 
1213
1235
  // WalletConnect approval already confirmed intent — sending automatically
1214
1236
 
1215
- console.log("Sending transaction...");
1237
+ console.log(c.dim("Sending transaction..."));
1216
1238
  const txHash = await sendTransactionWithSession(client, session, account, chainId, {
1217
1239
  to: config.walletContractAddress,
1218
1240
  data: calldata,
@@ -1220,9 +1242,9 @@ export function registerWalletCommands(program: Command): void {
1220
1242
  });
1221
1243
 
1222
1244
  const unlockAt = new Date(Date.now() + 2 * 24 * 60 * 60 * 1000);
1223
- console.log(`\n Registry upgrade proposed`);
1224
- console.log(` Tx: ${txHash}`);
1225
- console.log(` Unlock at: ${unlockAt.toISOString()} (approximately)`);
1245
+ console.log("\n" + c.success + c.white(" Registry upgrade proposed"));
1246
+ console.log(" " + c.dim("Tx:") + " " + c.white(txHash));
1247
+ console.log(" " + c.dim("Unlock at:") + " " + c.white(unlockAt.toISOString()) + c.dim(" (approximately)"));
1226
1248
  console.log(`\nNext steps:`);
1227
1249
  console.log(` Wait 2 days, then run:`);
1228
1250
  console.log(` arc402 wallet execute-registry-upgrade`);
@@ -1306,9 +1328,9 @@ export function registerWalletCommands(program: Command): void {
1306
1328
  confirmedRegistry = await walletContract.registry();
1307
1329
  } catch { /* use pendingRegistry as fallback */ }
1308
1330
 
1309
- console.log(`\n Registry upgrade executed`);
1310
- console.log(` Tx: ${txHash}`);
1311
- console.log(` New registry: ${confirmedRegistry}`);
1331
+ console.log("\n" + c.success + c.white(" Registry upgrade executed"));
1332
+ console.log(" " + c.dim("Tx:") + " " + c.white(txHash));
1333
+ console.log(" " + c.dim("New registry:") + " " + c.white(confirmedRegistry));
1312
1334
  if (confirmedRegistry.toLowerCase() === pendingRegistry.toLowerCase()) {
1313
1335
  console.log(` Registry updated successfully — addresses now resolve through new registry.`);
1314
1336
  } else {
@@ -1362,7 +1384,7 @@ export function registerWalletCommands(program: Command): void {
1362
1384
  } catch { /* ignore */ }
1363
1385
 
1364
1386
  if (alreadyWhitelisted) {
1365
- console.log(`✓ ${checksumTarget} is already whitelisted for ${config.walletContractAddress}`);
1387
+ console.log(" " + c.success + " " + c.white(checksumTarget) + c.dim(` is already whitelisted for ${config.walletContractAddress}`));
1366
1388
  process.exit(0);
1367
1389
  }
1368
1390
 
@@ -1397,10 +1419,12 @@ export function registerWalletCommands(program: Command): void {
1397
1419
  if (opts.json) {
1398
1420
  console.log(JSON.stringify({ ok: true, txHash, wallet: config.walletContractAddress, target: checksumTarget }));
1399
1421
  } else {
1400
- console.log(`\n Contract whitelisted`);
1401
- console.log(` Tx: ${txHash}`);
1402
- console.log(` Wallet: ${config.walletContractAddress}`);
1403
- console.log(` Target: ${checksumTarget}`);
1422
+ console.log("\n" + c.success + c.white(" Contract whitelisted"));
1423
+ renderTree([
1424
+ { label: "Tx", value: txHash },
1425
+ { label: "Wallet", value: config.walletContractAddress ?? "" },
1426
+ { label: "Target", value: checksumTarget, last: true },
1427
+ ]);
1404
1428
  }
1405
1429
  });
1406
1430
 
@@ -1459,9 +1483,9 @@ export function registerWalletCommands(program: Command): void {
1459
1483
  );
1460
1484
 
1461
1485
  await provider.waitForTransaction(txHash);
1462
- console.log(`\n X402 interceptor updated`);
1463
- console.log(` Tx: ${txHash}`);
1464
- console.log(` Interceptor: ${checksumAddress}`);
1486
+ console.log("\n" + c.success + c.white(" X402 interceptor updated"));
1487
+ console.log(" " + c.dim("Tx:") + " " + c.white(txHash));
1488
+ console.log(" " + c.dim("Interceptor:") + " " + c.white(checksumAddress));
1465
1489
  });
1466
1490
 
1467
1491
  // ─── set-velocity-limit ────────────────────────────────────────────────────
@@ -1524,9 +1548,9 @@ export function registerWalletCommands(program: Command): void {
1524
1548
  );
1525
1549
 
1526
1550
  await provider.waitForTransaction(txHash);
1527
- console.log(`\n Velocity limit updated`);
1528
- console.log(` Tx: ${txHash}`);
1529
- console.log(` New limit: ${limitEth} ETH per rolling window`);
1551
+ console.log("\n" + c.success + c.white(" Velocity limit updated"));
1552
+ console.log(" " + c.dim("Tx:") + " " + c.white(txHash));
1553
+ console.log(" " + c.dim("New limit:") + " " + c.white(`${limitEth} ETH per rolling window`));
1530
1554
  });
1531
1555
 
1532
1556
  // ─── register-policy ───────────────────────────────────────────────────────
@@ -1598,9 +1622,9 @@ export function registerWalletCommands(program: Command): void {
1598
1622
  );
1599
1623
 
1600
1624
  await provider.waitForTransaction(txHash);
1601
- console.log(`\n Wallet registered on PolicyEngine`);
1602
- console.log(` Tx: ${txHash}`);
1603
- console.log(`\nNext: run 'arc402 wallet policy set-limit' to configure spending limits.`);
1625
+ console.log("\n" + c.success + c.white(" Wallet registered on PolicyEngine"));
1626
+ console.log(" " + c.dim("Tx:") + " " + c.white(txHash));
1627
+ console.log(c.dim("\nNext: run 'arc402 wallet policy set-limit' to configure spending limits."));
1604
1628
  });
1605
1629
 
1606
1630
  // ─── cancel-registry-upgrade ───────────────────────────────────────────────
@@ -1670,8 +1694,8 @@ export function registerWalletCommands(program: Command): void {
1670
1694
  config
1671
1695
  );
1672
1696
 
1673
- console.log(`\n Registry upgrade cancelled`);
1674
- console.log(` Tx: ${txHash}`);
1697
+ console.log("\n" + c.success + c.white(" Registry upgrade cancelled"));
1698
+ console.log(" " + c.dim("Tx:") + " " + c.white(txHash));
1675
1699
  });
1676
1700
 
1677
1701
  // ─── governance setup ──────────────────────────────────────────────────────
@@ -1925,17 +1949,17 @@ export function registerWalletCommands(program: Command): void {
1925
1949
  saveConfig(config);
1926
1950
  }
1927
1951
 
1928
- console.log(`\n Governance setup complete`);
1952
+ console.log("\n" + c.success + c.white(" Governance setup complete"));
1929
1953
  if (usedBatch) {
1930
- console.log(` Batch tx: ${txHashes[0]}`);
1954
+ console.log(" " + c.dim("Batch tx:") + " " + c.white(txHashes[0]));
1931
1955
  } else {
1932
- txHashes.forEach((h, i) => console.log(` Tx ${i + 1}: ${h}`));
1956
+ txHashes.forEach((h, i) => console.log(" " + c.dim(`Tx ${i + 1}:`) + " " + c.white(h)));
1933
1957
  }
1934
1958
  if (guardianWallet) {
1935
- console.log(` Guardian key saved to config — address: ${guardianWallet.address}`);
1936
- console.log(` WARN: Store the guardian private key separately from your hot key.`);
1959
+ console.log(" " + c.success + c.dim(` Guardian key saved to config — address: ${guardianWallet.address}`));
1960
+ console.log(" " + c.warning + " " + c.yellow("Store the guardian private key separately from your hot key."));
1937
1961
  }
1938
- console.log(`\nVerify with: arc402 wallet status && arc402 wallet policy show`);
1962
+ console.log(c.dim("\nVerify with: arc402 wallet status && arc402 wallet policy show"));
1939
1963
  });
1940
1964
 
1941
1965
  // ─── authorize-machine-key ─────────────────────────────────────────────────
@@ -1972,7 +1996,7 @@ export function registerWalletCommands(program: Command): void {
1972
1996
  } catch { /* ignore */ }
1973
1997
 
1974
1998
  if (alreadyAuthorized) {
1975
- console.log(`\n ${checksumKey} is already authorized as a machine key on ${config.walletContractAddress}`);
1999
+ console.log("\n" + c.success + " " + c.white(checksumKey) + c.dim(` is already authorized as a machine key on ${config.walletContractAddress}`));
1976
2000
  process.exit(0);
1977
2001
  }
1978
2002
 
@@ -2000,24 +2024,26 @@ export function registerWalletCommands(program: Command): void {
2000
2024
  }
2001
2025
  );
2002
2026
 
2003
- console.log(`\n Connected: ${account}`);
2004
- console.log("Sending authorizeMachineKey transaction...");
2027
+ console.log("\n" + c.success + c.white(` Connected: ${account}`));
2028
+ console.log(c.dim("Sending authorizeMachineKey transaction..."));
2005
2029
 
2006
2030
  const hash = await sendTransactionWithSession(client, session, account, chainId, txData);
2007
- console.log(`\nTransaction submitted: ${hash}`);
2008
- console.log("Waiting for confirmation...");
2031
+ console.log("\n" + c.dim("Transaction submitted:") + " " + c.white(hash));
2032
+ console.log(c.dim("Waiting for confirmation..."));
2009
2033
 
2010
2034
  const receipt = await provider.waitForTransaction(hash, 1, 60000);
2011
2035
  if (!receipt || receipt.status !== 1) {
2012
- console.error("Transaction failed.");
2036
+ console.error(c.failure + " " + c.red("Transaction failed."));
2013
2037
  process.exit(1);
2014
2038
  }
2015
2039
 
2016
2040
  const confirmed = await walletContract.authorizedMachineKeys(checksumKey);
2017
- console.log(`\n Machine key authorized: ${confirmed ? "YES" : "NO"}`);
2018
- console.log(` Wallet: ${config.walletContractAddress}`);
2019
- console.log(` Machine key: ${checksumKey}`);
2020
- console.log(` Tx: ${hash}`);
2041
+ console.log("\n" + c.success + c.white(` Machine key authorized: ${confirmed ? "YES" : "NO"}`));
2042
+ renderTree([
2043
+ { label: "Wallet", value: config.walletContractAddress ?? "" },
2044
+ { label: "Machine key", value: checksumKey },
2045
+ { label: "Tx", value: hash, last: true },
2046
+ ]);
2021
2047
 
2022
2048
  await client.disconnect({ topic: session.topic, reason: { code: 6000, message: "done" } });
2023
2049
  process.exit(0);
@@ -2080,8 +2106,8 @@ export function registerWalletCommands(program: Command): void {
2080
2106
  { telegramOpts, prompt: `Revoke machine key ${checksumKey} on ARC402Wallet` }
2081
2107
  );
2082
2108
 
2083
- console.log(`\n Connected: ${account}`);
2084
- console.log("Sending revokeMachineKey transaction...");
2109
+ console.log("\n" + c.success + c.white(` Connected: ${account}`));
2110
+ console.log(c.dim("Sending revokeMachineKey transaction..."));
2085
2111
 
2086
2112
  const hash = await sendTransactionWithSession(client, session, account, chainId, {
2087
2113
  to: config.walletContractAddress,
@@ -2089,20 +2115,22 @@ export function registerWalletCommands(program: Command): void {
2089
2115
  value: "0x0",
2090
2116
  });
2091
2117
 
2092
- console.log(`\nTransaction submitted: ${hash}`);
2093
- console.log("Waiting for confirmation...");
2118
+ console.log("\n" + c.dim("Transaction submitted:") + " " + c.white(hash));
2119
+ console.log(c.dim("Waiting for confirmation..."));
2094
2120
 
2095
2121
  const receipt = await provider.waitForTransaction(hash, 1, 60000);
2096
2122
  if (!receipt || receipt.status !== 1) {
2097
- console.error("Transaction failed.");
2123
+ console.error(c.failure + " " + c.red("Transaction failed."));
2098
2124
  process.exit(1);
2099
2125
  }
2100
2126
 
2101
2127
  const stillAuthorized = await walletContract.authorizedMachineKeys(checksumKey);
2102
- console.log(`\n Machine key revoked: ${stillAuthorized ? "NO (still authorized — check tx)" : "YES"}`);
2103
- console.log(` Wallet: ${config.walletContractAddress}`);
2104
- console.log(` Machine key: ${checksumKey}`);
2105
- console.log(` Tx: ${hash}`);
2128
+ console.log("\n" + c.success + c.white(` Machine key revoked: ${stillAuthorized ? "NO (still authorized — check tx)" : "YES"}`));
2129
+ renderTree([
2130
+ { label: "Wallet", value: config.walletContractAddress ?? "" },
2131
+ { label: "Machine key", value: checksumKey },
2132
+ { label: "Tx", value: hash, last: true },
2133
+ ]);
2106
2134
 
2107
2135
  await client.disconnect({ topic: session.topic, reason: { code: 6000, message: "done" } });
2108
2136
  process.exit(0);
@@ -2228,11 +2256,13 @@ export function registerWalletCommands(program: Command): void {
2228
2256
  if (opts.json) {
2229
2257
  console.log(JSON.stringify({ walletAddress: walletAddr, contextId, taskType: opts.taskType, txHash: receipt?.hash }));
2230
2258
  } else {
2231
- console.log(`✓ Context opened`);
2232
- console.log(` contextId: ${contextId}`);
2233
- console.log(` taskType: ${opts.taskType}`);
2234
- console.log(` Tx: ${receipt?.hash}`);
2235
- console.log(`\nNote: Each context allows only one spend. Call \`arc402 wallet attest\` then \`arc402 wallet drain\` (or executeSpend directly).`);
2259
+ console.log(" " + c.success + c.white(" Context opened"));
2260
+ renderTree([
2261
+ { label: "contextId", value: contextId },
2262
+ { label: "taskType", value: opts.taskType },
2263
+ { label: "Tx", value: receipt?.hash ?? "", last: true },
2264
+ ]);
2265
+ console.log(c.dim("\nNote: Each context allows only one spend. Call `arc402 wallet attest` then `arc402 wallet drain` (or executeSpend directly)."));
2236
2266
  }
2237
2267
  });
2238
2268
 
@@ -2303,14 +2333,16 @@ export function registerWalletCommands(program: Command): void {
2303
2333
  txHash: receipt?.hash,
2304
2334
  }));
2305
2335
  } else {
2306
- console.log(`✓ Attestation created`);
2307
- console.log(` attestationId: ${attestationId}`);
2308
- console.log(` recipient: ${checksumRecipient}`);
2309
- console.log(` amount: ${opts.amount} ETH`);
2310
- console.log(` token: ${tokenAddress === ethers.ZeroAddress ? "ETH" : tokenAddress}`);
2311
- console.log(` expiresAt: ${new Date(expiresAt * 1000).toISOString()}`);
2312
- console.log(` Tx: ${receipt?.hash}`);
2313
- console.log(`\nUse this attestationId in \`arc402 wallet drain\` or your spend flow.`);
2336
+ console.log(" " + c.success + c.white(" Attestation created"));
2337
+ renderTree([
2338
+ { label: "attestationId", value: attestationId },
2339
+ { label: "recipient", value: checksumRecipient },
2340
+ { label: "amount", value: opts.amount + " ETH" },
2341
+ { label: "token", value: tokenAddress === ethers.ZeroAddress ? "ETH" : tokenAddress },
2342
+ { label: "expiresAt", value: new Date(expiresAt * 1000).toISOString() },
2343
+ { label: "Tx", value: receipt?.hash ?? "", last: true },
2344
+ ]);
2345
+ console.log(c.dim("\nUse this attestationId in `arc402 wallet drain` or your spend flow."));
2314
2346
  }
2315
2347
  });
2316
2348
 
@@ -2438,9 +2470,9 @@ export function registerWalletCommands(program: Command): void {
2438
2470
  if (opts.json) {
2439
2471
  console.log(JSON.stringify({ walletAddress: walletAddr, txHash: receipt?.hash, contextOpen: false }));
2440
2472
  } else {
2441
- console.log(`✓ Context closed`);
2442
- console.log(` Tx: ${receipt?.hash}`);
2443
- console.log(` Wallet: ${walletAddr}`);
2473
+ console.log(" " + c.success + c.white(" Context closed"));
2474
+ console.log(" " + c.dim("Tx:") + " " + c.white(receipt?.hash ?? ""));
2475
+ console.log(" " + c.dim("Wallet:") + " " + c.white(walletAddr));
2444
2476
  }
2445
2477
  });
2446
2478
 
@@ -2546,23 +2578,23 @@ export function registerWalletCommands(program: Command): void {
2546
2578
  // ── Step 1: context cleanup ────────────────────────────────────────────
2547
2579
  const isOpen: boolean = await walletContract.contextOpen();
2548
2580
  if (isOpen) {
2549
- console.log("Stale context found — closing it first...");
2581
+ console.log(c.dim("Stale context found — closing it first..."));
2550
2582
  const closeTx = await walletContract.closeContext();
2551
2583
  await closeTx.wait(2);
2552
- console.log(` Closed: ${closeTx.hash}`);
2584
+ console.log(" " + c.success + c.dim(` Closed: ${closeTx.hash}`));
2553
2585
  }
2554
2586
 
2555
2587
  // ── Step 2: openContext ────────────────────────────────────────────────
2556
2588
  const contextId = ethers.keccak256(ethers.toUtf8Bytes(`drain-${Date.now()}`));
2557
- console.log("Opening context...");
2589
+ console.log(c.dim("Opening context..."));
2558
2590
  const openTx = await walletContract.openContext(contextId, "drain");
2559
2591
  const openReceipt = await openTx.wait(1);
2560
- console.log(` openContext: ${openReceipt?.hash}`);
2592
+ console.log(" " + c.success + c.dim(` openContext: ${openReceipt?.hash}`));
2561
2593
 
2562
2594
  // ── Step 3: attest (direct on wallet — onlyOwnerOrMachineKey, NOT via executeContractCall)
2563
2595
  const attestationId = ethers.hexlify(ethers.randomBytes(32));
2564
2596
  const expiry = Math.floor(Date.now() / 1000) + 600; // 10 min TTL
2565
- console.log("Creating attestation (direct on wallet)...");
2597
+ console.log(c.dim("Creating attestation (direct on wallet)..."));
2566
2598
  const attestTx = await walletContract.attest(
2567
2599
  attestationId,
2568
2600
  "spend",
@@ -2573,10 +2605,10 @@ export function registerWalletCommands(program: Command): void {
2573
2605
  expiry,
2574
2606
  );
2575
2607
  const attestReceipt = await attestTx.wait(1);
2576
- console.log(` attest: ${attestReceipt?.hash}`);
2608
+ console.log(" " + c.success + c.dim(` attest: ${attestReceipt?.hash}`));
2577
2609
 
2578
2610
  // ── Step 4: executeSpend ───────────────────────────────────────────────
2579
- console.log("Executing spend...");
2611
+ console.log(c.dim("Executing spend..."));
2580
2612
  let spendReceiptHash: string | undefined;
2581
2613
  try {
2582
2614
  const spendTx = await walletContract.executeSpend(
@@ -2590,13 +2622,13 @@ export function registerWalletCommands(program: Command): void {
2590
2622
  } catch (e) {
2591
2623
  handleWalletError(e);
2592
2624
  }
2593
- console.log(` executeSpend: ${spendReceiptHash}`);
2625
+ console.log(" " + c.success + c.dim(` executeSpend: ${spendReceiptHash}`));
2594
2626
 
2595
2627
  // ── Step 5: closeContext ───────────────────────────────────────────────
2596
- console.log("Closing context...");
2628
+ console.log(c.dim("Closing context..."));
2597
2629
  const closeTx2 = await walletContract.closeContext();
2598
2630
  const closeReceipt = await closeTx2.wait(1);
2599
- console.log(` closeContext: ${closeReceipt?.hash}`);
2631
+ console.log(" " + c.success + c.dim(` closeContext: ${closeReceipt?.hash}`));
2600
2632
 
2601
2633
  const newBalance = await provider.getBalance(walletAddr);
2602
2634
  if (opts.json) {
@@ -2615,9 +2647,11 @@ export function registerWalletCommands(program: Command): void {
2615
2647
  remainingBalance: ethers.formatEther(newBalance),
2616
2648
  }));
2617
2649
  } else {
2618
- console.log(`\n Drain complete`);
2619
- console.log(` Sent: ${ethers.formatEther(drainAmount)} ETH → ${checksumRecipient}`);
2620
- console.log(` Remaining: ${ethers.formatEther(newBalance)} ETH`);
2650
+ console.log("\n" + c.success + c.white(" Drain complete"));
2651
+ renderTree([
2652
+ { label: "Sent", value: `${ethers.formatEther(drainAmount)} ETH → ${checksumRecipient}` },
2653
+ { label: "Remaining", value: `${ethers.formatEther(newBalance)} ETH`, last: true },
2654
+ ]);
2621
2655
  }
2622
2656
  });
2623
2657
 
@@ -2745,23 +2779,23 @@ export function registerWalletCommands(program: Command): void {
2745
2779
  // ── Step 1: context cleanup ──────────────────────────────────────────────
2746
2780
  const isOpenT: boolean = await walletContractT.contextOpen();
2747
2781
  if (isOpenT) {
2748
- console.log("Stale context found — closing it first...");
2782
+ console.log(c.dim("Stale context found — closing it first..."));
2749
2783
  const closeTxT = await walletContractT.closeContext();
2750
2784
  await closeTxT.wait(2);
2751
- console.log(` Closed: ${closeTxT.hash}`);
2785
+ console.log(" " + c.success + c.dim(` Closed: ${closeTxT.hash}`));
2752
2786
  }
2753
2787
 
2754
2788
  // ── Step 2: openContext ──────────────────────────────────────────────────
2755
2789
  const contextIdT = ethers.keccak256(ethers.toUtf8Bytes(`drain-token-${Date.now()}`));
2756
- console.log("Opening context...");
2790
+ console.log(c.dim("Opening context..."));
2757
2791
  const openTxT = await walletContractT.openContext(contextIdT, "drain");
2758
2792
  const openReceiptT = await openTxT.wait(1);
2759
- console.log(` openContext: ${openReceiptT?.hash}`);
2793
+ console.log(" " + c.success + c.dim(` openContext: ${openReceiptT?.hash}`));
2760
2794
 
2761
2795
  // ── Step 3: attest with token address ────────────────────────────────────
2762
2796
  const attestationIdT = ethers.hexlify(ethers.randomBytes(32));
2763
2797
  const expiryT = Math.floor(Date.now() / 1000) + 600; // 10 min TTL
2764
- console.log("Creating attestation (with token address)...");
2798
+ console.log(c.dim("Creating attestation (with token address)..."));
2765
2799
  const attestTxT = await walletContractT.attest(
2766
2800
  attestationIdT,
2767
2801
  "spend",
@@ -2772,10 +2806,10 @@ export function registerWalletCommands(program: Command): void {
2772
2806
  expiryT,
2773
2807
  );
2774
2808
  const attestReceiptT = await attestTxT.wait(1);
2775
- console.log(` attest: ${attestReceiptT?.hash}`);
2809
+ console.log(" " + c.success + c.dim(` attest: ${attestReceiptT?.hash}`));
2776
2810
 
2777
2811
  // ── Step 4: executeTokenSpend ────────────────────────────────────────────
2778
- console.log("Executing token spend...");
2812
+ console.log(c.dim("Executing token spend..."));
2779
2813
  const spendTxT = await walletContractT.executeTokenSpend(
2780
2814
  checksumRecipient,
2781
2815
  tokenAmount,
@@ -2784,13 +2818,13 @@ export function registerWalletCommands(program: Command): void {
2784
2818
  attestationIdT,
2785
2819
  );
2786
2820
  const spendReceiptT = await spendTxT.wait(1);
2787
- console.log(` executeTokenSpend: ${spendReceiptT?.hash}`);
2821
+ console.log(" " + c.success + c.dim(` executeTokenSpend: ${spendReceiptT?.hash}`));
2788
2822
 
2789
2823
  // ── Step 5: closeContext ─────────────────────────────────────────────────
2790
- console.log("Closing context...");
2824
+ console.log(c.dim("Closing context..."));
2791
2825
  const closeTxT2 = await walletContractT.closeContext();
2792
2826
  const closeReceiptT = await closeTxT2.wait(1);
2793
- console.log(` closeContext: ${closeReceiptT?.hash}`);
2827
+ console.log(" " + c.success + c.dim(` closeContext: ${closeReceiptT?.hash}`));
2794
2828
 
2795
2829
  const newTokenBalance: bigint = await erc20.balanceOf(walletAddr);
2796
2830
  if (opts.json) {
@@ -2810,10 +2844,12 @@ export function registerWalletCommands(program: Command): void {
2810
2844
  remainingTokenBalance: ethers.formatUnits(newTokenBalance, decimals),
2811
2845
  }));
2812
2846
  } else {
2813
- console.log(`\n Token drain complete`);
2814
- console.log(` Sent: ${amountArg} → ${checksumRecipient}`);
2815
- console.log(` Token: ${tokenAddress}`);
2816
- console.log(` Remaining: ${ethers.formatUnits(newTokenBalance, decimals)}`);
2847
+ console.log("\n" + c.success + c.white(" Token drain complete"));
2848
+ renderTree([
2849
+ { label: "Sent", value: `${amountArg} → ${checksumRecipient}` },
2850
+ { label: "Token", value: tokenAddress },
2851
+ { label: "Remaining", value: ethers.formatUnits(newTokenBalance, decimals), last: true },
2852
+ ]);
2817
2853
  }
2818
2854
  });
2819
2855
 
@@ -2876,25 +2912,27 @@ export function registerWalletCommands(program: Command): void {
2876
2912
  }
2877
2913
  );
2878
2914
 
2879
- console.log(`\n Connected: ${account}`);
2880
- console.log("Sending setPasskey transaction...");
2915
+ console.log("\n" + c.success + c.white(` Connected: ${account}`));
2916
+ console.log(c.dim("Sending setPasskey transaction..."));
2881
2917
 
2882
2918
  const hash = await sendTransactionWithSession(client, session, account, chainId, txData);
2883
- console.log(`\nTransaction submitted: ${hash}`);
2884
- console.log("Waiting for confirmation...");
2919
+ console.log("\n" + c.dim("Transaction submitted:") + " " + c.white(hash));
2920
+ console.log(c.dim("Waiting for confirmation..."));
2885
2921
 
2886
2922
  const receipt = await provider.waitForTransaction(hash, 1, 60000);
2887
2923
  if (!receipt || receipt.status !== 1) {
2888
- console.error("Transaction failed.");
2924
+ console.error(c.failure + " " + c.red("Transaction failed."));
2889
2925
  process.exit(1);
2890
2926
  }
2891
2927
 
2892
- console.log(`\n Passkey activated on ARC402Wallet`);
2893
- console.log(` Wallet: ${config.walletContractAddress}`);
2894
- console.log(` pubKeyX: ${pubKeyX}`);
2895
- console.log(` pubKeyY: ${pubKeyY}`);
2896
- console.log(` Tx: ${hash}`);
2897
- console.log(`\nGovernance ops now require Face ID instead of MetaMask.`);
2928
+ console.log("\n" + c.success + c.white(" Passkey activated on ARC402Wallet"));
2929
+ renderTree([
2930
+ { label: "Wallet", value: config.walletContractAddress ?? "" },
2931
+ { label: "pubKeyX", value: pubKeyX },
2932
+ { label: "pubKeyY", value: pubKeyY },
2933
+ { label: "Tx", value: hash, last: true },
2934
+ ]);
2935
+ console.log(c.dim("\nGovernance ops now require Face ID instead of MetaMask."));
2898
2936
 
2899
2937
  await client.disconnect({ topic: session.topic, reason: { code: 6000, message: "done" } });
2900
2938
  process.exit(0);