agentvault 1.0.0

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 (188) hide show
  1. package/.dfx/local/network-id +4 -0
  2. package/.next/trace +2 -0
  3. package/.vercel/README.txt +11 -0
  4. package/.vercel/project.json +1 -0
  5. package/AGENTS.md +43 -0
  6. package/CHANGELOG.md +196 -0
  7. package/LICENSE +21 -0
  8. package/PLAN_VAULT_INTEGRATION.md +318 -0
  9. package/README.md +253 -0
  10. package/backups/agentvault-backup-test-agent-2026-02-12T17-54-28-967Z.json +28 -0
  11. package/backups/agentvault-backup-test-agent-2026-02-12T17-54-29-032Z.backup +1 -0
  12. package/backups/agentvault-backup-test-agent-2026-02-12T17-57-42-373Z.json +28 -0
  13. package/backups/agentvault-backup-test-agent-2026-02-12T17-57-42-428Z.backup +1 -0
  14. package/backups/agentvault-backup-test-agent-2026-02-12T18-52-25-132Z.json +28 -0
  15. package/backups/agentvault-backup-test-agent-2026-02-12T18-52-25-247Z.backup +1 -0
  16. package/backups/agentvault-backup-test-agent-2026-02-12T18-54-09-216Z.json +28 -0
  17. package/backups/agentvault-backup-test-agent-2026-02-12T18-54-09-283Z.backup +1 -0
  18. package/backups/agentvault-backup-test-agent-2026-02-12T22-18-22-772Z.backup +1 -0
  19. package/backups/agentvault-backup-test-agent-2026-02-12T22-18-22-793Z.json +28 -0
  20. package/backups/test-backup.json +28 -0
  21. package/dist/cli/commands/approve.d.ts +4 -0
  22. package/dist/cli/commands/approve.js +232 -0
  23. package/dist/cli/commands/archive.d.ts +4 -0
  24. package/dist/cli/commands/archive.js +192 -0
  25. package/dist/cli/commands/backup.d.ts +4 -0
  26. package/dist/cli/commands/backup.js +164 -0
  27. package/dist/cli/commands/cloud-backup.d.ts +4 -0
  28. package/dist/cli/commands/cloud-backup.js +221 -0
  29. package/dist/cli/commands/cycles.d.ts +8 -0
  30. package/dist/cli/commands/cycles.js +83 -0
  31. package/dist/cli/commands/decrypt.d.ts +16 -0
  32. package/dist/cli/commands/decrypt.js +101 -0
  33. package/dist/cli/commands/deploy.d.ts +32 -0
  34. package/dist/cli/commands/deploy.js +208 -0
  35. package/dist/cli/commands/exec.d.ts +26 -0
  36. package/dist/cli/commands/exec.js +109 -0
  37. package/dist/cli/commands/fetch.d.ts +23 -0
  38. package/dist/cli/commands/fetch.js +164 -0
  39. package/dist/cli/commands/health.d.ts +8 -0
  40. package/dist/cli/commands/health.js +72 -0
  41. package/dist/cli/commands/identity.d.ts +8 -0
  42. package/dist/cli/commands/identity.js +140 -0
  43. package/dist/cli/commands/inference.d.ts +4 -0
  44. package/dist/cli/commands/inference.js +225 -0
  45. package/dist/cli/commands/info.d.ts +8 -0
  46. package/dist/cli/commands/info.js +59 -0
  47. package/dist/cli/commands/init.d.ts +19 -0
  48. package/dist/cli/commands/init.js +135 -0
  49. package/dist/cli/commands/instrument.d.ts +8 -0
  50. package/dist/cli/commands/instrument.js +35 -0
  51. package/dist/cli/commands/list.d.ts +36 -0
  52. package/dist/cli/commands/list.js +173 -0
  53. package/dist/cli/commands/logs.d.ts +8 -0
  54. package/dist/cli/commands/logs.js +96 -0
  55. package/dist/cli/commands/monitor.d.ts +8 -0
  56. package/dist/cli/commands/monitor.js +84 -0
  57. package/dist/cli/commands/network.d.ts +14 -0
  58. package/dist/cli/commands/network.js +258 -0
  59. package/dist/cli/commands/package.d.ts +36 -0
  60. package/dist/cli/commands/package.js +188 -0
  61. package/dist/cli/commands/profile.d.ts +8 -0
  62. package/dist/cli/commands/profile.js +76 -0
  63. package/dist/cli/commands/promote.d.ts +8 -0
  64. package/dist/cli/commands/promote.js +89 -0
  65. package/dist/cli/commands/rebuild.d.ts +21 -0
  66. package/dist/cli/commands/rebuild.js +140 -0
  67. package/dist/cli/commands/rollback.d.ts +8 -0
  68. package/dist/cli/commands/rollback.js +120 -0
  69. package/dist/cli/commands/show.d.ts +36 -0
  70. package/dist/cli/commands/show.js +200 -0
  71. package/dist/cli/commands/stats.d.ts +8 -0
  72. package/dist/cli/commands/stats.js +34 -0
  73. package/dist/cli/commands/status.d.ts +14 -0
  74. package/dist/cli/commands/status.js +83 -0
  75. package/dist/cli/commands/test.d.ts +8 -0
  76. package/dist/cli/commands/test.js +109 -0
  77. package/dist/cli/commands/tokens.d.ts +8 -0
  78. package/dist/cli/commands/tokens.js +62 -0
  79. package/dist/cli/commands/trace.d.ts +8 -0
  80. package/dist/cli/commands/trace.js +68 -0
  81. package/dist/cli/commands/wallet-export.d.ts +13 -0
  82. package/dist/cli/commands/wallet-export.js +140 -0
  83. package/dist/cli/commands/wallet-history.d.ts +10 -0
  84. package/dist/cli/commands/wallet-history.js +127 -0
  85. package/dist/cli/commands/wallet-import.d.ts +10 -0
  86. package/dist/cli/commands/wallet-import.js +209 -0
  87. package/dist/cli/commands/wallet-multi-send.d.ts +17 -0
  88. package/dist/cli/commands/wallet-multi-send.js +195 -0
  89. package/dist/cli/commands/wallet-process-queue.d.ts +19 -0
  90. package/dist/cli/commands/wallet-process-queue.js +209 -0
  91. package/dist/cli/commands/wallet-sign.d.ts +13 -0
  92. package/dist/cli/commands/wallet-sign.js +207 -0
  93. package/dist/cli/commands/wallet.d.ts +12 -0
  94. package/dist/cli/commands/wallet.js +794 -0
  95. package/dist/cli/index.d.ts +10 -0
  96. package/dist/cli/index.js +96 -0
  97. package/dist/vitest.config.d.ts +3 -0
  98. package/dist/vitest.config.js +14 -0
  99. package/fixup_1_0_OSS_release.md +136 -0
  100. package/fixup_REALEASE_PRD.md +136 -0
  101. package/package.json +79 -0
  102. package/pnpm-workspace.yaml +5 -0
  103. package/scripts/dev-dashboard.mjs +84 -0
  104. package/site/README.md +63 -0
  105. package/site/docusaurus.config.ts +148 -0
  106. package/site/package-lock.json +18383 -0
  107. package/site/package.json +47 -0
  108. package/site/sidebars.ts +86 -0
  109. package/site/static/.gitkeep +0 -0
  110. package/site/static/img/logo.svg +28 -0
  111. package/site/static/img/og-image.svg +35 -0
  112. package/src/archival/archive-manager.ts +372 -0
  113. package/src/archival/arweave-client.ts +289 -0
  114. package/src/archival/index.ts +8 -0
  115. package/src/backup/backup.ts +315 -0
  116. package/src/backup/index.ts +7 -0
  117. package/src/cloud-storage/cloud-sync.ts +461 -0
  118. package/src/cloud-storage/index.ts +11 -0
  119. package/src/cloud-storage/provider-detector.ts +198 -0
  120. package/src/cloud-storage/types.ts +104 -0
  121. package/src/debugging/index.ts +6 -0
  122. package/src/debugging/logs.ts +193 -0
  123. package/src/debugging/types.ts +100 -0
  124. package/src/deployment/deployer.ts +274 -0
  125. package/src/deployment/icpClient.ts +620 -0
  126. package/src/deployment/index.ts +46 -0
  127. package/src/deployment/promotion.ts +161 -0
  128. package/src/deployment/types.ts +111 -0
  129. package/src/icp/batch.ts +374 -0
  130. package/src/icp/cycles.ts +50 -0
  131. package/src/icp/environment.ts +215 -0
  132. package/src/icp/icpcli.ts +438 -0
  133. package/src/icp/icwasm.ts +222 -0
  134. package/src/icp/identity.ts +77 -0
  135. package/src/icp/index.ts +94 -0
  136. package/src/icp/optimization.ts +242 -0
  137. package/src/icp/tokens.ts +36 -0
  138. package/src/icp/tool-detector.ts +110 -0
  139. package/src/icp/types.ts +574 -0
  140. package/src/index.ts +25 -0
  141. package/src/inference/bittensor-client.ts +304 -0
  142. package/src/inference/index.ts +8 -0
  143. package/src/inference/inference-manager.ts +327 -0
  144. package/src/metrics/index.ts +7 -0
  145. package/src/metrics/metrics.ts +186 -0
  146. package/src/monitoring/alerting.ts +190 -0
  147. package/src/monitoring/health.ts +197 -0
  148. package/src/monitoring/index.ts +38 -0
  149. package/src/monitoring/info.ts +114 -0
  150. package/src/monitoring/types.ts +99 -0
  151. package/src/network/index.ts +5 -0
  152. package/src/network/network-config.ts +129 -0
  153. package/src/packaging/compiler.ts +647 -0
  154. package/src/packaging/config-persistence.ts +135 -0
  155. package/src/packaging/config-schemas.ts +156 -0
  156. package/src/packaging/detector.ts +220 -0
  157. package/src/packaging/index.ts +90 -0
  158. package/src/packaging/packager.ts +118 -0
  159. package/src/packaging/parsers/clawdbot.ts +278 -0
  160. package/src/packaging/parsers/cline.ts +223 -0
  161. package/src/packaging/parsers/generic.ts +266 -0
  162. package/src/packaging/parsers/goose.ts +214 -0
  163. package/src/packaging/parsers/index.ts +11 -0
  164. package/src/packaging/serializer.ts +260 -0
  165. package/src/packaging/types.ts +144 -0
  166. package/src/packaging/wasmedge-compiler.ts +406 -0
  167. package/src/security/index.ts +17 -0
  168. package/src/security/multisig.ts +415 -0
  169. package/src/security/types.ts +416 -0
  170. package/src/security/vetkeys.ts +655 -0
  171. package/src/testing/index.ts +6 -0
  172. package/src/testing/local-runner.ts +264 -0
  173. package/src/testing/types.ts +104 -0
  174. package/src/wallet/cbor-serializer.ts +323 -0
  175. package/src/wallet/chain-dispatcher.ts +313 -0
  176. package/src/wallet/cross-chain-aggregator.ts +346 -0
  177. package/src/wallet/index.ts +76 -0
  178. package/src/wallet/key-derivation.ts +425 -0
  179. package/src/wallet/providers/base-provider.ts +154 -0
  180. package/src/wallet/providers/cketh-provider.ts +434 -0
  181. package/src/wallet/providers/polkadot-provider.ts +503 -0
  182. package/src/wallet/providers/solana-provider.ts +490 -0
  183. package/src/wallet/transaction-queue.ts +284 -0
  184. package/src/wallet/types.ts +178 -0
  185. package/src/wallet/vetkeys-adapter.ts +431 -0
  186. package/src/wallet/wallet-manager.ts +597 -0
  187. package/src/wallet/wallet-storage.ts +380 -0
  188. package/vercel.json +8 -0
@@ -0,0 +1,794 @@
1
+ /**
2
+ * Wallet Command
3
+ *
4
+ * Main wallet management command for SoulRecall.
5
+ * Provides CLI interface for wallet operations.
6
+ */
7
+ import { Command } from 'commander';
8
+ import chalk from 'chalk';
9
+ import inquirer from 'inquirer';
10
+ import ora from 'ora';
11
+ import { generateWallet, importWalletFromPrivateKey, importWalletFromSeed, getWallet, listAgentWallets, removeWallet, } from '../../src/wallet/index.js';
12
+ import { CkEthProvider, } from '../../src/wallet/providers/cketh-provider.js';
13
+ /**
14
+ * Create wallet command
15
+ */
16
+ export function walletCommand() {
17
+ const command = new Command('wallet');
18
+ command
19
+ .description('Manage agent wallets (ckETH, Polkadot, Solana)')
20
+ .argument('<subcommand>', 'wallet subcommand to execute')
21
+ .option('-a, --agent-id <id>', 'agent ID (required)')
22
+ .option('-f, --file <path>', 'file path (for import)')
23
+ .action(async (subcommand, options) => {
24
+ await executeWalletCommand(subcommand, options);
25
+ });
26
+ return command;
27
+ }
28
+ /**
29
+ * Execute wallet subcommand
30
+ */
31
+ async function executeWalletCommand(subcommand, options) {
32
+ if (!options.agentId && subcommand !== 'vetkeys') {
33
+ console.error(chalk.red('Error: --agent-id is required'));
34
+ process.exit(1);
35
+ }
36
+ switch (subcommand) {
37
+ case 'connect':
38
+ await handleConnect(options.agentId);
39
+ break;
40
+ case 'disconnect':
41
+ await handleDisconnect(options.agentId);
42
+ break;
43
+ case 'balance':
44
+ await handleBalance(options.agentId);
45
+ break;
46
+ case 'send':
47
+ await handleSend(options.agentId);
48
+ break;
49
+ case 'list':
50
+ await handleList(options.agentId);
51
+ break;
52
+ case 'sign':
53
+ await handleSign(options.agentId);
54
+ break;
55
+ case 'history':
56
+ await handleHistory(options.agentId);
57
+ break;
58
+ case 'export':
59
+ await handleExport(options.agentId);
60
+ break;
61
+ case 'import':
62
+ await handleImport(options.agentId, options.file);
63
+ break;
64
+ case 'sync':
65
+ await handleSync(options.agentId);
66
+ break;
67
+ case 'status':
68
+ await handleStatus(options.agentId);
69
+ break;
70
+ case 'vetkeys':
71
+ await handleVetKeys();
72
+ break;
73
+ case 'queue':
74
+ await handleQueue(options.agentId);
75
+ break;
76
+ default:
77
+ console.error(chalk.red(`Unknown subcommand: ${subcommand}`));
78
+ console.log();
79
+ console.log(chalk.cyan('Available subcommands:'));
80
+ console.log(' connect - Connect or create a wallet');
81
+ console.log(' disconnect - Disconnect wallet');
82
+ console.log(' balance - Check wallet balance');
83
+ console.log(' send - Send transaction');
84
+ console.log(' list - List all wallets');
85
+ console.log(' sign - Sign transaction');
86
+ console.log(' history - Get transaction history');
87
+ console.log(' export - Export wallets to backup file');
88
+ console.log(' import - Import wallets from backup file');
89
+ console.log(' sync - Sync wallets to canister (Phase 5)');
90
+ console.log(' status - Get wallet sync status (Phase 5)');
91
+ console.log(' vetkeys - VetKeys operations (Phase 5)');
92
+ console.log(' queue - Transaction queue operations (Phase 5)');
93
+ process.exit(1);
94
+ }
95
+ }
96
+ /**
97
+ * Handle wallet connect/create
98
+ */
99
+ async function handleConnect(agentId) {
100
+ console.log(chalk.bold('\n🔑 Wallet Connect\n'));
101
+ const { method } = await inquirer.prompt([
102
+ {
103
+ type: 'list',
104
+ name: 'method',
105
+ message: 'How would you like to create the wallet?',
106
+ choices: [
107
+ { name: 'generate', value: 'Generate new wallet (recommended)' },
108
+ { name: 'seed', value: 'Import from seed phrase' },
109
+ { name: 'private-key', value: 'Import from private key' },
110
+ ],
111
+ },
112
+ ]);
113
+ const { chain } = await inquirer.prompt([
114
+ {
115
+ type: 'list',
116
+ name: 'chain',
117
+ message: 'Which blockchain?',
118
+ choices: [
119
+ { name: 'cketh', value: 'ckETH (Ethereum on ICP)' },
120
+ { name: 'polkadot', value: 'Polkadot' },
121
+ { name: 'solana', value: 'Solana' },
122
+ ],
123
+ },
124
+ ]);
125
+ let wallet;
126
+ if (method === 'generate') {
127
+ wallet = generateWallet(agentId, chain);
128
+ console.log(chalk.green('✓'), 'New wallet generated');
129
+ }
130
+ else if (method === 'seed') {
131
+ const { seedPhrase, derivationPath } = await inquirer.prompt([
132
+ {
133
+ type: 'password',
134
+ name: 'seedPhrase',
135
+ message: 'Enter seed phrase (BIP39):',
136
+ validate: (input) => input.split(' ').length >= 12,
137
+ },
138
+ {
139
+ type: 'input',
140
+ name: 'derivationPath',
141
+ message: 'Derivation path (optional):',
142
+ default: '',
143
+ },
144
+ ]);
145
+ wallet = importWalletFromSeed(agentId, chain, seedPhrase, derivationPath || undefined);
146
+ console.log(chalk.green('✓'), 'Wallet imported from seed phrase');
147
+ }
148
+ else if (method === 'private-key') {
149
+ const { privateKey } = await inquirer.prompt([
150
+ {
151
+ type: 'password',
152
+ name: 'privateKey',
153
+ message: 'Enter private key (hex):',
154
+ validate: (input) => /^0x[0-9a-fA-F]{64}$/.test(input),
155
+ },
156
+ ]);
157
+ wallet = importWalletFromPrivateKey(agentId, chain, privateKey);
158
+ console.log(chalk.green('✓'), 'Wallet imported from private key');
159
+ }
160
+ // Display wallet info
161
+ console.log();
162
+ console.log(chalk.cyan('Wallet Info:'));
163
+ if (!wallet) {
164
+ console.log(chalk.yellow('Wallet not found'));
165
+ return;
166
+ }
167
+ console.log(` ID: ${wallet.id}`);
168
+ console.log(` Chain: ${wallet.chain}`);
169
+ console.log(` Address: ${wallet.address}`);
170
+ console.log(` Created: ${new Date(wallet.createdAt).toISOString()}`);
171
+ // Test connection to provider
172
+ const spinner = ora('Testing provider connection...').start();
173
+ try {
174
+ const provider = new CkEthProvider({
175
+ chain: chain,
176
+ rpcUrl: CkEthProvider.getDefaultRpcUrl(),
177
+ isTestnet: false,
178
+ });
179
+ await provider.connect();
180
+ const balance = await provider.getBalance(wallet.address);
181
+ spinner.succeed('Provider connected');
182
+ console.log();
183
+ console.log(chalk.cyan('Balance:'));
184
+ console.log(` ${balance.amount} ${balance.denomination}`);
185
+ }
186
+ catch (error) {
187
+ const message = error instanceof Error ? error.message : 'Unknown error';
188
+ spinner.fail(`Provider connection failed: ${message}`);
189
+ }
190
+ }
191
+ /**
192
+ * Handle wallet disconnect
193
+ */
194
+ async function handleDisconnect(agentId) {
195
+ const wallets = listAgentWallets(agentId);
196
+ if (wallets.length === 0) {
197
+ console.log(chalk.yellow('No wallets found for this agent'));
198
+ return;
199
+ }
200
+ const { walletId } = await inquirer.prompt([
201
+ {
202
+ type: 'list',
203
+ name: 'walletId',
204
+ message: 'Select wallet to disconnect:',
205
+ choices: wallets,
206
+ },
207
+ ]);
208
+ removeWallet(agentId, walletId);
209
+ console.log(chalk.green('✓'), 'Wallet disconnected');
210
+ }
211
+ /**
212
+ * Handle wallet balance query
213
+ */
214
+ async function handleBalance(agentId) {
215
+ const wallets = listAgentWallets(agentId);
216
+ if (wallets.length === 0) {
217
+ console.log(chalk.yellow('No wallets found for this agent'));
218
+ return;
219
+ }
220
+ const { walletId } = await inquirer.prompt([
221
+ {
222
+ type: 'list',
223
+ name: 'walletId',
224
+ message: 'Select wallet:',
225
+ choices: wallets,
226
+ },
227
+ ]);
228
+ const wallet = getWallet(agentId, walletId);
229
+ if (!wallet) {
230
+ console.log(chalk.red('Wallet not found'));
231
+ return;
232
+ }
233
+ const spinner = ora('Fetching balance...').start();
234
+ try {
235
+ const provider = new CkEthProvider({
236
+ chain: wallet.chain,
237
+ rpcUrl: CkEthProvider.getDefaultRpcUrl(),
238
+ isTestnet: false,
239
+ });
240
+ await provider.connect();
241
+ const balance = await provider.getBalance(wallet.address);
242
+ spinner.succeed('Balance fetched');
243
+ console.log();
244
+ console.log(chalk.cyan('Balance:'));
245
+ console.log(` Address: ${wallet.address}`);
246
+ console.log(` Amount: ${balance.amount} ${balance.denomination}`);
247
+ console.log(` Block: ${balance.blockNumber}`);
248
+ }
249
+ catch (error) {
250
+ const message = error instanceof Error ? error.message : 'Unknown error';
251
+ spinner.fail(`Failed to fetch balance: ${message}`);
252
+ }
253
+ }
254
+ /**
255
+ * Handle wallet send transaction
256
+ */
257
+ async function handleSend(agentId) {
258
+ const wallets = listAgentWallets(agentId);
259
+ if (wallets.length === 0) {
260
+ console.log(chalk.yellow('No wallets found for this agent'));
261
+ return;
262
+ }
263
+ const { walletId } = await inquirer.prompt([
264
+ {
265
+ type: 'list',
266
+ name: 'walletId',
267
+ message: 'Select wallet:',
268
+ choices: wallets,
269
+ },
270
+ ]);
271
+ const wallet = getWallet(agentId, walletId);
272
+ if (!wallet) {
273
+ console.log(chalk.red('Wallet not found'));
274
+ return;
275
+ }
276
+ const { toAddress, amount } = await inquirer.prompt([
277
+ {
278
+ type: 'input',
279
+ name: 'toAddress',
280
+ message: 'Recipient address:',
281
+ validate: (input) => input.length > 0,
282
+ },
283
+ {
284
+ type: 'input',
285
+ name: 'amount',
286
+ message: 'Amount to send:',
287
+ validate: (input) => parseFloat(input) > 0,
288
+ },
289
+ ]);
290
+ const { confirm } = await inquirer.prompt([
291
+ {
292
+ type: 'confirm',
293
+ name: 'confirm',
294
+ message: `Send ${amount} to ${toAddress}?`,
295
+ default: false,
296
+ },
297
+ ]);
298
+ if (!confirm) {
299
+ console.log(chalk.yellow('\nTransaction cancelled'));
300
+ return;
301
+ }
302
+ const spinner = ora('Sending transaction...').start();
303
+ try {
304
+ const provider = new CkEthProvider({
305
+ chain: wallet.chain,
306
+ rpcUrl: CkEthProvider.getDefaultRpcUrl(),
307
+ isTestnet: false,
308
+ });
309
+ await provider.connect();
310
+ const tx = await provider.sendTransaction(wallet.address, {
311
+ to: toAddress,
312
+ amount,
313
+ chain: wallet.chain,
314
+ });
315
+ spinner.succeed('Transaction sent');
316
+ console.log();
317
+ console.log(chalk.cyan('Transaction:'));
318
+ console.log(` Hash: ${tx.hash}`);
319
+ console.log(` From: ${tx.from}`);
320
+ console.log(` To: ${tx.to}`);
321
+ console.log(` Amount: ${tx.amount}`);
322
+ console.log(` Status: ${tx.status}`);
323
+ }
324
+ catch (error) {
325
+ const message = error instanceof Error ? error.message : 'Unknown error';
326
+ spinner.fail(`Failed to send transaction: ${message}`);
327
+ }
328
+ }
329
+ /**
330
+ * Handle wallet list
331
+ */
332
+ async function handleList(agentId) {
333
+ const wallets = listAgentWallets(agentId);
334
+ if (wallets.length === 0) {
335
+ console.log(chalk.yellow('No wallets found for this agent'));
336
+ return;
337
+ }
338
+ console.log();
339
+ console.log(chalk.cyan(`Wallets for agent: ${agentId}`));
340
+ console.log();
341
+ for (const walletId of wallets) {
342
+ const wallet = getWallet(agentId, walletId);
343
+ if (wallet) {
344
+ console.log(chalk.white(walletId));
345
+ console.log(` Chain: ${wallet.chain}`);
346
+ console.log(` Address: ${wallet.address}`);
347
+ console.log(` Created: ${new Date(wallet.createdAt).toISOString()}`);
348
+ console.log();
349
+ }
350
+ }
351
+ }
352
+ /**
353
+ * Handle wallet sign
354
+ */
355
+ async function handleSign(agentId) {
356
+ const { handleSign: signHandler } = await import('./wallet-sign.js');
357
+ await signHandler(agentId);
358
+ }
359
+ /**
360
+ * Handle wallet history
361
+ */
362
+ async function handleHistory(agentId) {
363
+ const { handleHistory: historyHandler } = await import('./wallet-history.js');
364
+ await historyHandler(agentId);
365
+ }
366
+ /**
367
+ * Handle wallet export
368
+ */
369
+ async function handleExport(agentId) {
370
+ const { handleExport: exportHandler } = await import('./wallet-export.js');
371
+ await exportHandler(agentId);
372
+ }
373
+ /**
374
+ * Handle wallet import
375
+ */
376
+ async function handleImport(agentId, filePath) {
377
+ const { handleImport: importHandler } = await import('./wallet-import.js');
378
+ await importHandler(agentId, filePath || '');
379
+ }
380
+ /**
381
+ * Handle wallet sync to canister (Phase 5)
382
+ */
383
+ async function handleSync(agentId) {
384
+ console.log(chalk.bold('\n🔄 Wallet Sync to Canister\n'));
385
+ const { canisterId } = await inquirer.prompt([
386
+ {
387
+ type: 'input',
388
+ name: 'canisterId',
389
+ message: 'Enter canister ID:',
390
+ validate: (input) => input.length > 0,
391
+ },
392
+ ]);
393
+ const { syncAll } = await inquirer.prompt([
394
+ {
395
+ type: 'confirm',
396
+ name: 'syncAll',
397
+ message: 'Sync all wallets or specific wallet?',
398
+ default: true,
399
+ },
400
+ ]);
401
+ const spinner = ora('Syncing wallets...').start();
402
+ try {
403
+ const { syncAgentWallets, syncWalletToCanister, listAgentWallets, } = await import('../../src/wallet/wallet-manager.js');
404
+ if (syncAll) {
405
+ const result = await syncAgentWallets(agentId, canisterId);
406
+ spinner.succeed('Sync complete');
407
+ console.log();
408
+ console.log(chalk.cyan('Sync Results:'));
409
+ console.log(` Synced: ${result.synced.length}`);
410
+ console.log(` Failed: ${result.failed.length}`);
411
+ if (result.failed.length > 0) {
412
+ console.log();
413
+ console.log(chalk.yellow('Failed wallets:'));
414
+ for (const fail of result.failed) {
415
+ console.log(` - ${fail.walletId}: ${fail.error}`);
416
+ }
417
+ }
418
+ }
419
+ else {
420
+ const wallets = listAgentWallets(agentId);
421
+ if (wallets.length === 0) {
422
+ spinner.warn('No wallets found');
423
+ return;
424
+ }
425
+ spinner.stop();
426
+ const { walletId } = await inquirer.prompt([
427
+ {
428
+ type: 'list',
429
+ name: 'walletId',
430
+ message: 'Select wallet to sync:',
431
+ choices: wallets,
432
+ },
433
+ ]);
434
+ spinner.start('Syncing wallet...');
435
+ const result = await syncWalletToCanister(agentId, walletId, canisterId);
436
+ if (result.success) {
437
+ spinner.succeed('Wallet synced successfully');
438
+ console.log(` Registered at: ${new Date(result.registeredAt).toISOString()}`);
439
+ }
440
+ else {
441
+ spinner.fail(`Sync failed: ${result.error}`);
442
+ }
443
+ }
444
+ }
445
+ catch (error) {
446
+ const message = error instanceof Error ? error.message : 'Unknown error';
447
+ spinner.fail(`Sync failed: ${message}`);
448
+ }
449
+ }
450
+ /**
451
+ * Handle wallet sync status (Phase 5)
452
+ */
453
+ async function handleStatus(agentId) {
454
+ console.log(chalk.bold('\n📊 Wallet Sync Status\n'));
455
+ const { canisterId } = await inquirer.prompt([
456
+ {
457
+ type: 'input',
458
+ name: 'canisterId',
459
+ message: 'Enter canister ID:',
460
+ validate: (input) => input.length > 0,
461
+ },
462
+ ]);
463
+ const wallets = (await import('../../src/wallet/wallet-manager.js')).listAgentWallets(agentId);
464
+ if (wallets.length === 0) {
465
+ console.log(chalk.yellow('No wallets found for this agent'));
466
+ return;
467
+ }
468
+ console.log();
469
+ console.log(chalk.cyan(`Wallets for agent: ${agentId}`));
470
+ console.log();
471
+ const { getWalletSyncStatus } = await import('../../src/wallet/wallet-manager.js');
472
+ for (const walletId of wallets) {
473
+ const status = await getWalletSyncStatus(agentId, walletId, canisterId);
474
+ const localIcon = status.localExists ? chalk.green('✓') : chalk.red('✗');
475
+ const canisterIcon = status.inCanister ? chalk.green('✓') : chalk.red('✗');
476
+ const syncIcon = status.synced ? chalk.green('✓') : chalk.yellow('○');
477
+ console.log(chalk.white(walletId));
478
+ console.log(` Local: ${localIcon} ${status.localExists ? 'exists' : 'missing'}`);
479
+ console.log(` Canister: ${canisterIcon} ${status.inCanister ? 'registered' : 'not registered'}`);
480
+ console.log(` Synced: ${syncIcon} ${status.synced ? 'yes' : 'no'}`);
481
+ console.log();
482
+ }
483
+ }
484
+ /**
485
+ * Handle VetKeys operations (Phase 5)
486
+ */
487
+ async function handleVetKeys() {
488
+ console.log(chalk.bold('\n🔐 VetKeys Operations\n'));
489
+ const { operation } = await inquirer.prompt([
490
+ {
491
+ type: 'list',
492
+ name: 'operation',
493
+ message: 'Select VetKeys operation:',
494
+ choices: [
495
+ { name: 'status', value: 'Get VetKeys status' },
496
+ { name: 'list', value: 'List encrypted secrets' },
497
+ { name: 'get', value: 'Get encrypted secret' },
498
+ { name: 'delete', value: 'Delete encrypted secret' },
499
+ ],
500
+ },
501
+ ]);
502
+ const { canisterId } = await inquirer.prompt([
503
+ {
504
+ type: 'input',
505
+ name: 'canisterId',
506
+ message: 'Enter canister ID:',
507
+ validate: (input) => input.length > 0,
508
+ },
509
+ ]);
510
+ const { VetKeysImplementation } = await import('../../src/security/vetkeys.js');
511
+ const vetkeys = new VetKeysImplementation({
512
+ canisterId,
513
+ useCanister: true,
514
+ });
515
+ switch (operation) {
516
+ case 'status':
517
+ await handleVetKeysStatus(vetkeys);
518
+ break;
519
+ case 'list':
520
+ await handleVetKeysList(vetkeys);
521
+ break;
522
+ case 'get':
523
+ await handleVetKeysGet(vetkeys);
524
+ break;
525
+ case 'delete':
526
+ await handleVetKeysDelete(vetkeys);
527
+ break;
528
+ }
529
+ }
530
+ /**
531
+ * Handle VetKeys status operation
532
+ */
533
+ async function handleVetKeysStatus(vetkeys) {
534
+ const spinner = ora('Fetching VetKeys status...').start();
535
+ try {
536
+ const status = await vetkeys.getVetKeysStatusFromCanister();
537
+ spinner.succeed('VetKeys status fetched');
538
+ console.log();
539
+ console.log(chalk.cyan('VetKeys Status:'));
540
+ console.log(` Enabled: ${status.enabled ? chalk.green('yes') : chalk.red('no')}`);
541
+ console.log(` Threshold Support: ${status.thresholdSupported ? chalk.green('yes') : chalk.red('no')}`);
542
+ console.log(` Mode: ${status.mode}`);
543
+ }
544
+ catch (error) {
545
+ const message = error instanceof Error ? error.message : 'Unknown error';
546
+ spinner.fail(`Failed to fetch status: ${message}`);
547
+ }
548
+ }
549
+ /**
550
+ * Handle VetKeys list operation
551
+ */
552
+ async function handleVetKeysList(vetkeys) {
553
+ const spinner = ora('Listing encrypted secrets...').start();
554
+ try {
555
+ const secrets = await vetkeys.listEncryptedSecretsOnCanister();
556
+ spinner.succeed(`Found ${secrets.length} encrypted secrets`);
557
+ if (secrets.length > 0) {
558
+ console.log();
559
+ console.log(chalk.cyan('Encrypted Secrets:'));
560
+ for (const secretId of secrets) {
561
+ console.log(` - ${secretId}`);
562
+ }
563
+ }
564
+ }
565
+ catch (error) {
566
+ const message = error instanceof Error ? error.message : 'Unknown error';
567
+ spinner.fail(`Failed to list secrets: ${message}`);
568
+ }
569
+ }
570
+ /**
571
+ * Handle VetKeys get operation
572
+ */
573
+ async function handleVetKeysGet(vetkeys) {
574
+ const { secretId } = await inquirer.prompt([
575
+ {
576
+ type: 'input',
577
+ name: 'secretId',
578
+ message: 'Enter secret ID:',
579
+ validate: (input) => input.length > 0,
580
+ },
581
+ ]);
582
+ const spinner = ora('Fetching encrypted secret...').start();
583
+ try {
584
+ const secret = await vetkeys.getEncryptedSecretFromCanister(secretId);
585
+ if (secret) {
586
+ spinner.succeed('Secret found');
587
+ console.log();
588
+ console.log(chalk.cyan('Encrypted Secret:'));
589
+ console.log(` ID: ${secretId}`);
590
+ console.log(` Algorithm: ${secret.algorithm}`);
591
+ console.log(` IV: ${Array.from(secret.iv).map(b => b.toString(16).padStart(2, '0')).join('')}`);
592
+ console.log(` Tag: ${Array.from(secret.tag).map(b => b.toString(16).padStart(2, '0')).join('')}`);
593
+ console.log(` Data: ${Array.from(secret.ciphertext).slice(0, 32).map(b => b.toString(16).padStart(2, '0')).join('')}...`);
594
+ }
595
+ else {
596
+ spinner.warn('Secret not found');
597
+ }
598
+ }
599
+ catch (error) {
600
+ const message = error instanceof Error ? error.message : 'Unknown error';
601
+ spinner.fail(`Failed to fetch secret: ${message}`);
602
+ }
603
+ }
604
+ /**
605
+ * Handle VetKeys delete operation
606
+ */
607
+ async function handleVetKeysDelete(vetkeys) {
608
+ const { secretId } = await inquirer.prompt([
609
+ {
610
+ type: 'input',
611
+ name: 'secretId',
612
+ message: 'Enter secret ID to delete:',
613
+ validate: (input) => input.length > 0,
614
+ },
615
+ ]);
616
+ const { confirm } = await inquirer.prompt([
617
+ {
618
+ type: 'confirm',
619
+ name: 'confirm',
620
+ message: `Are you sure you want to delete secret ${secretId}?`,
621
+ default: false,
622
+ },
623
+ ]);
624
+ if (!confirm) {
625
+ console.log(chalk.yellow('\nDelete cancelled'));
626
+ return;
627
+ }
628
+ const spinner = ora('Deleting encrypted secret...').start();
629
+ try {
630
+ const success = await vetkeys.deleteEncryptedSecretFromCanister(secretId);
631
+ if (success) {
632
+ spinner.succeed('Secret deleted successfully');
633
+ }
634
+ else {
635
+ spinner.warn('Delete failed');
636
+ }
637
+ }
638
+ catch (error) {
639
+ const message = error instanceof Error ? error.message : 'Unknown error';
640
+ spinner.fail(`Failed to delete secret: ${message}`);
641
+ }
642
+ }
643
+ /**
644
+ * Handle transaction queue operations (Phase 5)
645
+ */
646
+ async function handleQueue(agentId) {
647
+ console.log(chalk.bold('\n📋 Transaction Queue\n'));
648
+ const { operation } = await inquirer.prompt([
649
+ {
650
+ type: 'list',
651
+ name: 'operation',
652
+ message: 'Select queue operation:',
653
+ choices: [
654
+ { name: 'list', value: 'List all transactions' },
655
+ { name: 'pending', value: 'List pending transactions' },
656
+ { name: 'stats', value: 'Get queue statistics' },
657
+ { name: 'clear', value: 'Clear completed transactions' },
658
+ ],
659
+ },
660
+ ]);
661
+ const { canisterId } = await inquirer.prompt([
662
+ {
663
+ type: 'input',
664
+ name: 'canisterId',
665
+ message: 'Enter canister ID:',
666
+ validate: (input) => input.length > 0,
667
+ },
668
+ ]);
669
+ switch (operation) {
670
+ case 'list':
671
+ await handleQueueList(agentId, canisterId);
672
+ break;
673
+ case 'pending':
674
+ await handleQueuePending(agentId, canisterId);
675
+ break;
676
+ case 'stats':
677
+ await handleQueueStats(agentId, canisterId);
678
+ break;
679
+ case 'clear':
680
+ await handleQueueClear(agentId, canisterId);
681
+ break;
682
+ }
683
+ }
684
+ /**
685
+ * Handle queue list operation
686
+ */
687
+ async function handleQueueList(_agentId, canisterId) {
688
+ const spinner = ora('Fetching transactions...').start();
689
+ try {
690
+ await import('../../src/canister/actor.js');
691
+ const { createActor } = await import('../../src/canister/actor.js');
692
+ const actor = createActor(canisterId);
693
+ const transactions = await actor.getQueuedTransactions();
694
+ spinner.succeed(`Found ${transactions.length} transactions`);
695
+ if (transactions.length > 0) {
696
+ console.log();
697
+ console.log(chalk.cyan('Transaction Queue:'));
698
+ for (const tx of transactions) {
699
+ console.log(` ID: ${tx.id}`);
700
+ console.log(` Action: ${tx.action.action}`);
701
+ console.log(` Status: ${tx.status}`);
702
+ console.log(` Created: ${new Date(Number(tx.createdAt)).toISOString()}`);
703
+ console.log();
704
+ }
705
+ }
706
+ }
707
+ catch (error) {
708
+ const message = error instanceof Error ? error.message : 'Unknown error';
709
+ spinner.fail(`Failed to fetch transactions: ${message}`);
710
+ }
711
+ }
712
+ /**
713
+ * Handle queue pending operation
714
+ */
715
+ async function handleQueuePending(_agentId, canisterId) {
716
+ const spinner = ora('Fetching pending transactions...').start();
717
+ try {
718
+ await import('../../src/canister/actor.js');
719
+ const { createActor } = await import('../../src/canister/actor.js');
720
+ const actor = createActor(canisterId);
721
+ const transactions = await actor.getPendingTransactions();
722
+ spinner.succeed(`Found ${transactions.length} pending transactions`);
723
+ if (transactions.length > 0) {
724
+ console.log();
725
+ console.log(chalk.cyan('Pending Transactions:'));
726
+ for (const tx of transactions) {
727
+ console.log(` ID: ${tx.id}`);
728
+ console.log(` Action: ${tx.action.action}`);
729
+ console.log(` Priority: ${tx.action.priority}`);
730
+ console.log(` Created: ${new Date(Number(tx.createdAt)).toISOString()}`);
731
+ console.log();
732
+ }
733
+ }
734
+ }
735
+ catch (error) {
736
+ const message = error instanceof Error ? error.message : 'Unknown error';
737
+ spinner.fail(`Failed to fetch pending transactions: ${message}`);
738
+ }
739
+ }
740
+ /**
741
+ * Handle queue stats operation
742
+ */
743
+ async function handleQueueStats(_agentId, canisterId) {
744
+ const spinner = ora('Fetching queue statistics...').start();
745
+ try {
746
+ await import('../../src/canister/actor.js');
747
+ const { createActor } = await import('../../src/canister/actor.js');
748
+ const actor = createActor(canisterId);
749
+ const stats = await actor.getTransactionQueueStats();
750
+ spinner.succeed('Queue statistics fetched');
751
+ console.log();
752
+ console.log(chalk.cyan('Transaction Queue Statistics:'));
753
+ console.log(` Total: ${stats.total}`);
754
+ console.log(` Pending: ${stats.pending}`);
755
+ console.log(` Queued: ${stats.queued}`);
756
+ console.log(` Signed: ${stats.signed}`);
757
+ console.log(` Completed: ${stats.completed}`);
758
+ console.log(` Failed: ${stats.failed}`);
759
+ }
760
+ catch (error) {
761
+ const message = error instanceof Error ? error.message : 'Unknown error';
762
+ spinner.fail(`Failed to fetch statistics: ${message}`);
763
+ }
764
+ }
765
+ /**
766
+ * Handle queue clear operation
767
+ */
768
+ async function handleQueueClear(_agentId, canisterId) {
769
+ const { confirm } = await inquirer.prompt([
770
+ {
771
+ type: 'confirm',
772
+ name: 'confirm',
773
+ message: 'Clear all completed transactions?',
774
+ default: false,
775
+ },
776
+ ]);
777
+ if (!confirm) {
778
+ console.log(chalk.yellow('\nClear cancelled'));
779
+ return;
780
+ }
781
+ const spinner = ora('Clearing completed transactions...').start();
782
+ try {
783
+ await import('../../src/canister/actor.js');
784
+ const { createActor } = await import('../../src/canister/actor.js');
785
+ const actor = createActor(canisterId);
786
+ await actor.clearCompletedTransactions();
787
+ spinner.succeed('Completed transactions cleared');
788
+ }
789
+ catch (error) {
790
+ const message = error instanceof Error ? error.message : 'Unknown error';
791
+ spinner.fail(`Failed to clear transactions: ${message}`);
792
+ }
793
+ }
794
+ //# sourceMappingURL=wallet.js.map