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,597 @@
1
+ /**
2
+ * Wallet Manager
3
+ *
4
+ * Main wallet management module.
5
+ * Handles wallet creation, storage, and retrieval with per-agent isolation.
6
+ * Phase 5A: Added canister sync functionality.
7
+ */
8
+
9
+ import { randomBytes } from 'node:crypto';
10
+ import {
11
+ saveWallet,
12
+ loadWallet,
13
+ deleteWallet,
14
+ listWallets,
15
+ walletExists,
16
+ } from './wallet-storage.js';
17
+ import {
18
+ deriveWalletKey,
19
+ validateSeedPhrase,
20
+ generateMnemonic,
21
+ } from './key-derivation.js';
22
+ import type {
23
+ WalletData,
24
+ WalletCreationOptions,
25
+ WalletStorageOptions,
26
+ } from './types.js';
27
+
28
+ // Phase 5A: Canister imports (lazy load)
29
+ let _createActor: any = null;
30
+ let _canisterInitialized = false;
31
+
32
+ /**
33
+ * Lazy load canister actor
34
+ */
35
+ async function loadCanister() {
36
+ if (_canisterInitialized) return;
37
+
38
+ try {
39
+ const { createActor } = await import('../canister/actor.js');
40
+ _createActor = createActor;
41
+ _canisterInitialized = true;
42
+ } catch (error) {
43
+ console.warn('Canister integration not available:', error);
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Get or create canister actor
49
+ */
50
+ async function getCanisterActor(canisterId: string) {
51
+ await loadCanister();
52
+
53
+ if (!_createActor) {
54
+ throw new Error('Canister actor not initialized');
55
+ }
56
+
57
+ const { createAnonymousAgent } = await import('../canister/actor.js');
58
+ const agent = createAnonymousAgent();
59
+ return _createActor(canisterId, agent);
60
+ }
61
+
62
+ /**
63
+ * In-memory wallet connections cache
64
+ */
65
+ const walletConnections = new Map<string, any>();
66
+
67
+ /**
68
+ * Generate unique wallet ID
69
+ *
70
+ * @returns Unique wallet ID
71
+ */
72
+ function generateWalletId(): string {
73
+ const bytes = randomBytes(16);
74
+ return `wallet-${bytes.toString('hex')}`;
75
+ }
76
+
77
+ /**
78
+ * Create a new wallet
79
+ *
80
+ * @param options - Wallet creation options
81
+ * @param storageOptions - Storage options
82
+ * @returns Created wallet data
83
+ */
84
+ export function createWallet(
85
+ options: WalletCreationOptions,
86
+ storageOptions: WalletStorageOptions = {}
87
+ ): WalletData {
88
+ // Derive wallet key
89
+ const derivedKey = deriveWalletKey(
90
+ options.method,
91
+ options.seedPhrase,
92
+ options.privateKey,
93
+ options.derivationPath,
94
+ options.chain
95
+ );
96
+
97
+ // Create wallet data object
98
+ const walletData: WalletData = {
99
+ id: options.walletId || generateWalletId(),
100
+ agentId: options.agentId,
101
+ chain: options.chain,
102
+ address: derivedKey.address,
103
+ privateKey: options.method === 'private-key' ? derivedKey.privateKey : undefined,
104
+ mnemonic: (options.method === 'seed' || options.method === 'mnemonic')
105
+ ? options.seedPhrase
106
+ : undefined,
107
+ seedDerivationPath: derivedKey.derivationPath,
108
+ createdAt: Date.now(),
109
+ updatedAt: Date.now(),
110
+ creationMethod: options.method,
111
+ chainMetadata: options.chainMetadata,
112
+ };
113
+
114
+ // Save wallet to storage
115
+ saveWallet(walletData, storageOptions);
116
+
117
+ return walletData;
118
+ }
119
+
120
+ /**
121
+ * Import wallet from private key
122
+ *
123
+ * @param agentId - Agent ID
124
+ * @param chain - Blockchain type
125
+ * @param privateKey - Private key (hex)
126
+ * @param storageOptions - Storage options
127
+ * @returns Imported wallet data
128
+ */
129
+ export function importWalletFromPrivateKey(
130
+ agentId: string,
131
+ chain: string,
132
+ privateKey: string,
133
+ storageOptions: WalletStorageOptions = {}
134
+ ): WalletData {
135
+ return createWallet({
136
+ agentId,
137
+ chain: chain as any,
138
+ method: 'private-key',
139
+ privateKey,
140
+ }, storageOptions);
141
+ }
142
+
143
+ /**
144
+ * Import wallet from seed phrase
145
+ *
146
+ * @param agentId - Agent ID
147
+ * @param chain - Blockchain type
148
+ * @param seedPhrase - BIP39 seed phrase
149
+ * @param derivationPath - Optional custom derivation path
150
+ * @param storageOptions - Storage options
151
+ * @returns Imported wallet data
152
+ */
153
+ export function importWalletFromSeed(
154
+ agentId: string,
155
+ chain: string,
156
+ seedPhrase: string,
157
+ derivationPath?: string,
158
+ storageOptions: WalletStorageOptions = {}
159
+ ): WalletData {
160
+ return createWallet({
161
+ agentId,
162
+ chain: chain as any,
163
+ method: 'seed',
164
+ seedPhrase,
165
+ derivationPath,
166
+ }, storageOptions);
167
+ }
168
+
169
+ /**
170
+ * Import wallet from mnemonic
171
+ *
172
+ * @param agentId - Agent ID
173
+ * @param chain - Blockchain type
174
+ * @param mnemonic - BIP39 mnemonic phrase
175
+ * @param derivationPath - Optional custom derivation path
176
+ * @param storageOptions - Storage options
177
+ * @returns Imported wallet data
178
+ */
179
+ export function importWalletFromMnemonic(
180
+ agentId: string,
181
+ chain: string,
182
+ mnemonic: string,
183
+ derivationPath?: string,
184
+ storageOptions: WalletStorageOptions = {}
185
+ ): WalletData {
186
+ return createWallet({
187
+ agentId,
188
+ chain: chain as any,
189
+ method: 'mnemonic',
190
+ seedPhrase: mnemonic,
191
+ derivationPath,
192
+ }, storageOptions);
193
+ }
194
+
195
+ /**
196
+ * Generate new wallet
197
+ *
198
+ * @param agentId - Agent ID
199
+ * @param chain - Blockchain type
200
+ * @param storageOptions - Storage options
201
+ * @returns Generated wallet data
202
+ */
203
+ export function generateWallet(
204
+ agentId: string,
205
+ chain: string,
206
+ storageOptions: WalletStorageOptions = {}
207
+ ): WalletData {
208
+ const mnemonic = generateMnemonic(128);
209
+ return importWalletFromSeed(agentId, chain, mnemonic, undefined, storageOptions);
210
+ }
211
+
212
+ /**
213
+ * Get wallet by ID
214
+ *
215
+ * @param agentId - Agent ID
216
+ * @param walletId - Wallet ID
217
+ * @param storageOptions - Storage options
218
+ * @returns Wallet data or null if not found
219
+ */
220
+ export function getWallet(
221
+ agentId: string,
222
+ walletId: string,
223
+ storageOptions: WalletStorageOptions = {}
224
+ ): WalletData | null {
225
+ return loadWallet(agentId, walletId, storageOptions);
226
+ }
227
+
228
+ /**
229
+ * List all wallets for an agent
230
+ *
231
+ * @param agentId - Agent ID
232
+ * @param storageOptions - Storage options
233
+ * @returns Array of wallet IDs
234
+ */
235
+ export function listAgentWallets(
236
+ agentId: string,
237
+ storageOptions: WalletStorageOptions = {}
238
+ ): string[] {
239
+ return listWallets(agentId, storageOptions);
240
+ }
241
+
242
+ /**
243
+ * Check if wallet exists
244
+ *
245
+ * @param agentId - Agent ID
246
+ * @param walletId - Wallet ID
247
+ * @param storageOptions - Storage options
248
+ * @returns True if wallet exists
249
+ */
250
+ export function hasWallet(
251
+ agentId: string,
252
+ walletId: string,
253
+ storageOptions: WalletStorageOptions = {}
254
+ ): boolean {
255
+ return walletExists(agentId, walletId, storageOptions);
256
+ }
257
+
258
+ /**
259
+ * Remove wallet
260
+ *
261
+ * @param agentId - Agent ID
262
+ * @param walletId - Wallet ID
263
+ * @param storageOptions - Storage options
264
+ */
265
+ export function removeWallet(
266
+ agentId: string,
267
+ walletId: string,
268
+ storageOptions: WalletStorageOptions = {}
269
+ ): void {
270
+ deleteWallet(agentId, walletId, storageOptions);
271
+
272
+ // Remove from connections cache
273
+ walletConnections.delete(`${agentId}:${walletId}`);
274
+ }
275
+
276
+ /**
277
+ * Clear all wallets for an agent
278
+ *
279
+ * @param agentId - Agent ID
280
+ * @param storageOptions - Storage options
281
+ */
282
+ export function clearAgentWallets(
283
+ agentId: string,
284
+ storageOptions: WalletStorageOptions = {}
285
+ ): void {
286
+ const walletIds = listWallets(agentId, storageOptions);
287
+
288
+ for (const walletId of walletIds) {
289
+ deleteWallet(agentId, walletId, storageOptions);
290
+ walletConnections.delete(`${agentId}:${walletId}`);
291
+ }
292
+ }
293
+
294
+ /**
295
+ * Cache wallet connection
296
+ *
297
+ * @param agentId - Agent ID
298
+ * @param walletId - Wallet ID
299
+ * @param provider - Provider instance
300
+ */
301
+ export function cacheWalletConnection(
302
+ agentId: string,
303
+ walletId: string,
304
+ provider: any
305
+ ): void {
306
+ walletConnections.set(`${agentId}:${walletId}`, provider);
307
+ }
308
+
309
+ /**
310
+ * Get cached wallet connection
311
+ *
312
+ * @param agentId - Agent ID
313
+ * @param walletId - Wallet ID
314
+ * @returns Cached provider or undefined
315
+ */
316
+ export function getCachedConnection(
317
+ agentId: string,
318
+ walletId: string
319
+ ): any {
320
+ return walletConnections.get(`${agentId}:${walletId}`);
321
+ }
322
+
323
+ /**
324
+ * Clear wallet connection cache
325
+ *
326
+ * @param agentId - Agent ID
327
+ * @param walletId - Wallet ID
328
+ */
329
+ export function clearCachedConnection(
330
+ agentId: string,
331
+ walletId: string
332
+ ): void {
333
+ walletConnections.delete(`${agentId}:${walletId}`);
334
+ }
335
+
336
+ /**
337
+ * Validate seed phrase
338
+ *
339
+ * @param seedPhrase - Seed phrase to validate
340
+ * @returns True if valid
341
+ */
342
+ export function validateSeedPhraseWrapper(seedPhrase: string): boolean {
343
+ return validateSeedPhrase(seedPhrase);
344
+ }
345
+
346
+ // ==================== Phase 5A: Canister Sync Functions ====================
347
+
348
+ /**
349
+ * Sync wallet to canister (register wallet metadata)
350
+ *
351
+ * @param agentId - Agent ID
352
+ * @param walletId - Wallet ID
353
+ * @param canisterId - Canister ID to sync to
354
+ * @returns Sync result
355
+ */
356
+ export async function syncWalletToCanister(
357
+ agentId: string,
358
+ walletId: string,
359
+ canisterId: string
360
+ ): Promise<{ success: boolean; error?: string; registeredAt?: number }> {
361
+ try {
362
+ await loadCanister();
363
+
364
+ if (!_createActor) {
365
+ return { success: false, error: 'Canister not available' };
366
+ }
367
+
368
+ const wallet = getWallet(agentId, walletId);
369
+ if (!wallet) {
370
+ return { success: false, error: 'Wallet not found' };
371
+ }
372
+
373
+ const actor = await getCanisterActor(canisterId);
374
+
375
+ const result = await actor.registerWallet({
376
+ id: walletId,
377
+ agentId,
378
+ chain: wallet.chain,
379
+ address: wallet.address,
380
+ registeredAt: BigInt(wallet.createdAt),
381
+ status: { active: null },
382
+ });
383
+
384
+ if ('ok' in result) {
385
+ return {
386
+ success: true,
387
+ registeredAt: wallet.createdAt,
388
+ };
389
+ } else {
390
+ return {
391
+ success: false,
392
+ error: result.err,
393
+ };
394
+ }
395
+ } catch (error) {
396
+ return {
397
+ success: false,
398
+ error: error instanceof Error ? error.message : 'Unknown error',
399
+ };
400
+ }
401
+ }
402
+
403
+ /**
404
+ * Sync all wallets for an agent to canister
405
+ *
406
+ * @param agentId - Agent ID
407
+ * @param canisterId - Canister ID to sync to
408
+ * @returns Sync results
409
+ */
410
+ export async function syncAgentWallets(
411
+ agentId: string,
412
+ canisterId: string
413
+ ): Promise<{ synced: string[]; failed: { walletId: string; error: string }[] }> {
414
+ const walletIds = listAgentWallets(agentId);
415
+ const synced: string[] = [];
416
+ const failed: { walletId: string; error: string }[] = [];
417
+
418
+ for (const walletId of walletIds) {
419
+ const result = await syncWalletToCanister(agentId, walletId, canisterId);
420
+ if (result.success) {
421
+ synced.push(walletId);
422
+ } else {
423
+ failed.push({
424
+ walletId,
425
+ error: result.error || 'Unknown error',
426
+ });
427
+ }
428
+ }
429
+
430
+ return { synced, failed };
431
+ }
432
+
433
+ /**
434
+ * Get wallet sync status
435
+ *
436
+ * @param agentId - Agent ID
437
+ * @param walletId - Wallet ID
438
+ * @param canisterId - Canister ID
439
+ * @returns Wallet sync status
440
+ */
441
+ export async function getWalletSyncStatus(
442
+ agentId: string,
443
+ walletId: string,
444
+ canisterId: string
445
+ ): Promise<{
446
+ walletId: string;
447
+ inCanister: boolean;
448
+ canisterStatus?: any;
449
+ localExists: boolean;
450
+ synced: boolean;
451
+ }> {
452
+ try {
453
+ await loadCanister();
454
+
455
+ const localExists = hasWallet(agentId, walletId);
456
+ let inCanister = false;
457
+ let canisterStatus;
458
+
459
+ if (_createActor) {
460
+ const actor = await getCanisterActor(canisterId);
461
+ const result = await actor.getWallet(walletId);
462
+
463
+ if (result && result.length > 0) {
464
+ inCanister = true;
465
+ canisterStatus = result[0];
466
+ }
467
+ }
468
+
469
+ const wallet = localExists ? getWallet(agentId, walletId) : null;
470
+ const synced = inCanister && localExists && wallet && canisterStatus;
471
+
472
+ return {
473
+ walletId,
474
+ inCanister,
475
+ canisterStatus,
476
+ localExists,
477
+ synced,
478
+ };
479
+ } catch (_error) {
480
+ return {
481
+ walletId,
482
+ inCanister: false,
483
+ localExists: hasWallet(agentId, walletId),
484
+ synced: false,
485
+ };
486
+ }
487
+ }
488
+
489
+ /**
490
+ * List wallets from canister
491
+ *
492
+ * @param agentId - Agent ID
493
+ * @param canisterId - Canister ID
494
+ * @returns Array of canister wallet info
495
+ */
496
+ export async function listCanisterWallets(
497
+ agentId: string,
498
+ canisterId: string
499
+ ): Promise<any[]> {
500
+ try {
501
+ await loadCanister();
502
+
503
+ if (!_createActor) {
504
+ return [];
505
+ }
506
+
507
+ const actor = await getCanisterActor(canisterId);
508
+ return await actor.listWallets(agentId);
509
+ } catch (error) {
510
+ console.error('Failed to list canister wallets:', error);
511
+ return [];
512
+ }
513
+ }
514
+
515
+ /**
516
+ * Deregister wallet from canister
517
+ *
518
+ * @param walletId - Wallet ID
519
+ * @param canisterId - Canister ID
520
+ * @returns Deregistration result
521
+ */
522
+ export async function deregisterWalletFromCanister(
523
+ walletId: string,
524
+ canisterId: string
525
+ ): Promise<{ success: boolean; error?: string }> {
526
+ try {
527
+ await loadCanister();
528
+
529
+ if (!_createActor) {
530
+ return { success: false, error: 'Canister not available' };
531
+ }
532
+
533
+ const actor = await getCanisterActor(canisterId);
534
+ const result = await actor.deregisterWallet(walletId);
535
+
536
+ if ('ok' in result) {
537
+ return { success: true };
538
+ } else {
539
+ return {
540
+ success: false,
541
+ error: result.err,
542
+ };
543
+ }
544
+ } catch (error) {
545
+ return {
546
+ success: false,
547
+ error: error instanceof Error ? error.message : 'Unknown error',
548
+ };
549
+ }
550
+ }
551
+
552
+ /**
553
+ * Update wallet status in canister
554
+ *
555
+ * @param walletId - Wallet ID
556
+ * @param status - New status
557
+ * @param canisterId - Canister ID
558
+ * @returns Update result
559
+ */
560
+ export async function updateCanisterWalletStatus(
561
+ walletId: string,
562
+ status: 'active' | 'inactive' | 'revoked',
563
+ canisterId: string
564
+ ): Promise<{ success: boolean; error?: string }> {
565
+ try {
566
+ await loadCanister();
567
+
568
+ if (!_createActor) {
569
+ return { success: false, error: 'Canister not available' };
570
+ }
571
+
572
+ const actor = await getCanisterActor(canisterId);
573
+
574
+ const statusVariant =
575
+ status === 'active'
576
+ ? { active: null }
577
+ : status === 'inactive'
578
+ ? { inactive: null }
579
+ : { revoked: null };
580
+
581
+ const result = await actor.updateWalletStatus(walletId, statusVariant);
582
+
583
+ if ('ok' in result) {
584
+ return { success: true };
585
+ } else {
586
+ return {
587
+ success: false,
588
+ error: result.err,
589
+ };
590
+ }
591
+ } catch (error) {
592
+ return {
593
+ success: false,
594
+ error: error instanceof Error ? error.message : 'Unknown error',
595
+ };
596
+ }
597
+ }