@deserialize/multi-vm-wallet 1.5.1 → 1.5.3

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 (43) hide show
  1. package/MULTI_CHAIN_SAVINGS_PLAN.md +1028 -0
  2. package/MULTI_CHAIN_SAVINGS_USAGE.md +428 -0
  3. package/SAVINGS_TEST_EXAMPLES.md +411 -0
  4. package/dist/IChainWallet.d.ts +11 -7
  5. package/dist/IChainWallet.js +15 -6
  6. package/dist/evm/evm.d.ts +10 -1
  7. package/dist/evm/evm.js +82 -32
  8. package/dist/evm/utils.d.ts +1 -0
  9. package/dist/evm/utils.js +8 -1
  10. package/dist/index.d.ts +4 -2
  11. package/dist/index.js +33 -2
  12. package/dist/savings/evm-savings.d.ts +52 -0
  13. package/dist/savings/evm-savings.js +159 -0
  14. package/dist/savings/index.d.ts +9 -1
  15. package/dist/savings/index.js +12 -1
  16. package/dist/savings/multi-chain-savings.d.ts +48 -0
  17. package/dist/savings/multi-chain-savings.js +203 -0
  18. package/dist/savings/savings-manager.d.ts +28 -0
  19. package/dist/savings/savings-manager.js +55 -0
  20. package/dist/savings/svm-savings.d.ts +40 -0
  21. package/dist/savings/svm-savings.js +176 -0
  22. package/dist/svm/index.d.ts +1 -0
  23. package/dist/svm/index.js +1 -0
  24. package/dist/svm/svm.d.ts +10 -1
  25. package/dist/svm/svm.js +64 -21
  26. package/dist/test.js +118 -4
  27. package/dist/vm-validation.d.ts +0 -1
  28. package/dist/vm-validation.js +0 -12
  29. package/package.json +1 -1
  30. package/utils/IChainWallet.ts +76 -15
  31. package/utils/evm/evm.ts +123 -291
  32. package/utils/evm/utils.ts +12 -0
  33. package/utils/index.ts +13 -3
  34. package/utils/savings/evm-savings.ts +354 -0
  35. package/utils/savings/index.ts +18 -1
  36. package/utils/savings/multi-chain-savings.ts +458 -0
  37. package/utils/savings/savings-manager.ts +189 -0
  38. package/utils/savings/svm-savings.ts +394 -0
  39. package/utils/svm/index.ts +2 -1
  40. package/utils/svm/svm.ts +100 -24
  41. package/utils/test.ts +175 -7
  42. package/utils/utils.ts +7 -0
  43. package/utils/vm-validation.ts +17 -17
package/utils/test.ts CHANGED
@@ -22,7 +22,7 @@ import { entryPoint07Address } from "viem/account-abstraction";
22
22
  import { KERNEL_V3_3, KernelVersionToAddressesMap } from '@zerodev/sdk/constants';
23
23
  import { deserializeSessionKey } from "./evm/aa-service";
24
24
  import { toSpendingLimitHook } from "@zerodev/hooks"
25
- import { SavingsManager } from "./savings";
25
+ import { EVMSavingsManager, SVMSavingsManager, MultiChainSavingsManager } from "./savings";
26
26
  // const mnemonic = GenerateNewMnemonic()
27
27
 
28
28
 
@@ -212,27 +212,195 @@ const testPrice = async () => {
212
212
  walletA.getPrices(['0x98d0baa52b2D063E780DE12F615f963Fe8537553']).then(console.log)
213
213
  }
214
214
 
215
+ // ============================================
216
+ // EVM Savings Pocket Test
217
+ // ============================================
215
218
  const testSavingsPocket = async () => {
219
+ console.log('\n========== EVM Savings Test ==========');
220
+ const mnemonic = EVMVM.generateMnemonicFromPrivateKey(evmPrivateKeyExposed)
221
+ console.log('Mnemonic:', mnemonic);
222
+
223
+ // Using new EVMSavingsManager (multi-chain compatible)
224
+ const savingsManager = new EVMSavingsManager(mnemonic, evmChainConfig, wallet.index)
225
+
226
+ const pocket0 = savingsManager.getPocket(0)
227
+ console.log('\nPocket 0 Info:');
228
+ console.log(' Address:', pocket0.address);
229
+ console.log(' Derivation path:', pocket0.derivationPath);
230
+ console.log(' Index:', pocket0.index);
231
+
232
+ // Uncomment to test transfer
233
+ // const deposited = await savingsManager.transferToPocket(walletA.wallet, 0, "0.00001")
234
+ // console.log('deposited: ', deposited);
216
235
 
236
+ // Get balance (updated API: getPocketBalance(pocketIndex, tokens[]))
237
+ const balance = await savingsManager.getPocketBalance(0, [])
238
+ console.log('\nPocket 0 Balance:');
239
+ console.log(' Native balance:', balance[0].balance.formatted, 'ETH');
240
+
241
+ // Get multiple pockets
242
+ const pocket1 = savingsManager.getPocket(1)
243
+ const pocket2 = savingsManager.getPocket(2)
244
+ console.log('\nAdditional Pockets:');
245
+ console.log(' Pocket 1:', pocket1.address);
246
+ console.log(' Pocket 2:', pocket2.address);
247
+
248
+ // Cleanup
249
+ savingsManager.dispose();
250
+ console.log('\nāœ… EVM Savings Test Complete\n');
251
+ }
217
252
 
253
+ // ============================================
254
+ // SVM (Solana) Savings Pocket Test
255
+ // ============================================
256
+ const testSavingsPocketSVM = async () => {
257
+ console.log('\n========== SVM (Solana) Savings Test ==========');
218
258
  const mnemonic = EVMVM.generateMnemonicFromPrivateKey(evmPrivateKeyExposed)
219
- console.log('mnemonic: ', mnemonic);
259
+ console.log('Mnemonic:', mnemonic);
220
260
 
221
- const savingsManager = new SavingsManager(mnemonic, evmChainConfig, wallet.index)
261
+ // Using SVMSavingsManager for Solana
262
+ const savingsManager = new SVMSavingsManager(
263
+ mnemonic,
264
+ chainConfig.rpcUrl,
265
+ 0 // wallet index
266
+ )
222
267
 
223
268
  const pocket0 = savingsManager.getPocket(0)
269
+ console.log('\nPocket 0 Info:');
270
+ console.log(' Address:', pocket0.address.toBase58());
271
+ console.log(' Derivation path:', pocket0.derivationPath);
272
+ console.log(' Index:', pocket0.index);
273
+
274
+ // Get balance
275
+ const balance = await savingsManager.getPocketBalance(0, [])
276
+ console.log('\nPocket 0 Balance:');
277
+ console.log(' Native balance:', balance[0].balance.formatted, 'SOL');
278
+
279
+ // Get multiple pockets
280
+ const pocket1 = savingsManager.getPocket(1)
281
+ const pocket2 = savingsManager.getPocket(2)
282
+ console.log('\nAdditional Pockets:');
283
+ console.log(' Pocket 1:', pocket1.address.toBase58());
284
+ console.log(' Pocket 2:', pocket2.address.toBase58());
285
+
286
+ // Note: Solana addresses are DIFFERENT from EVM addresses!
287
+ console.log('\nšŸ’” Note: Solana uses coin type 501, so addresses differ from EVM');
288
+
289
+ // Cleanup
290
+ savingsManager.dispose();
291
+ console.log('\nāœ… SVM Savings Test Complete\n');
292
+ }
224
293
 
225
- // const deposited = await savingsManager.transferToPocket(walletA.wallet, pocket0.index, "0.00001")
294
+ // ============================================
295
+ // Multi-Chain Savings Test
296
+ // ============================================
297
+ const testSavingsPocketMultiChain = async () => {
298
+ console.log('\n========== Multi-Chain Savings Test ==========');
299
+ const mnemonic = EVMVM.generateMnemonicFromPrivateKey(evmPrivateKeyExposed)
300
+ console.log('Mnemonic:', mnemonic);
226
301
 
227
- const balance = await savingsManager.getPocketTokenBalance([], 0)
228
- console.log('balance: ', balance);
302
+ // Create multi-chain manager with EVM and Solana
303
+ const multiChainManager = new MultiChainSavingsManager(
304
+ mnemonic,
305
+ [
306
+ {
307
+ id: 'base',
308
+ type: 'EVM',
309
+ config: evmChainConfig
310
+ },
311
+ {
312
+ id: 'ethereum',
313
+ type: 'EVM',
314
+ config: {
315
+ chainId: 1,
316
+ name: 'Ethereum',
317
+ rpcUrl: 'https://eth-mainnet.g.alchemy.com/v2/demo',
318
+ explorerUrl: 'https://etherscan.io',
319
+ nativeToken: { name: 'Ethereum', symbol: 'ETH', decimals: 18 },
320
+ confirmationNo: 1,
321
+ vmType: 'EVM'
322
+ }
323
+ },
324
+ {
325
+ id: 'solana',
326
+ type: 'SVM',
327
+ config: {
328
+ rpcUrl: chainConfig.rpcUrl
329
+ }
330
+ }
331
+ ],
332
+ 0 // wallet index
333
+ );
334
+
335
+ console.log('\nAvailable chains:', multiChainManager.getChains());
336
+ console.log('EVM chains:', multiChainManager.getEVMChains());
337
+ console.log('SVM chains:', multiChainManager.getSVMChains());
338
+
339
+ // Get pocket 0 address on different chains
340
+ console.log('\nPocket 0 Addresses Across Chains:');
341
+ const baseAddress = multiChainManager.getPocketAddress('base', 0);
342
+ const ethAddress = multiChainManager.getPocketAddress('ethereum', 0);
343
+ const solAddress = multiChainManager.getPocketAddress('solana', 0);
344
+
345
+ console.log(' Base:', baseAddress);
346
+ console.log(' Ethereum:', ethAddress);
347
+ console.log(' Solana:', solAddress);
348
+
349
+ // Verify EVM chains share addresses
350
+ console.log('\nšŸ” EVM Address Check:');
351
+ console.log(' Base === Ethereum?', baseAddress === ethAddress, 'āœ…');
352
+ console.log(' Base === Solana?', baseAddress === solAddress, 'āŒ (different chain type)');
353
+
354
+ // Get balances across chains
355
+ console.log('\nšŸ“Š Getting balances across all chains...');
356
+ try {
357
+ const balances = await multiChainManager.getPocketBalanceAcrossChains(
358
+ 0, // pocket index
359
+ new Map([
360
+ ['base', []], // No tokens, just native
361
+ ['ethereum', []],
362
+ ['solana', []]
363
+ ])
364
+ );
365
+
366
+ console.log('\nBalances for Pocket 0:');
367
+ balances.forEach(chainBalance => {
368
+ console.log(`\n ${chainBalance.chainId.toUpperCase()} (${chainBalance.chainType}):`);
369
+ console.log(` Address: ${chainBalance.address}`);
370
+ chainBalance.balances.forEach(bal => {
371
+ const tokenName = bal.token === 'native' ? 'Native' : bal.token;
372
+ console.log(` ${tokenName}: ${bal.balance.formatted}`);
373
+ });
374
+ });
375
+ } catch (error) {
376
+ console.log(' āš ļø Balance fetch error (expected for demo RPCs):', (error as Error).message);
377
+ }
229
378
 
230
- // console.log('deposited: ', deposited);
379
+ // Get specific chain managers for advanced operations
380
+ console.log('\nšŸ”§ Advanced: Direct chain manager access');
381
+ const baseManager = multiChainManager.getEVMManager('base');
382
+ const solanaManager = multiChainManager.getSVMManager('solana');
383
+ console.log(' Base manager type:', baseManager.constructor.name);
384
+ console.log(' Solana manager type:', solanaManager.constructor.name);
231
385
 
386
+ // Cleanup
387
+ multiChainManager.dispose();
388
+ console.log('\nāœ… Multi-Chain Savings Test Complete\n');
389
+ }
232
390
 
391
+ const testEntropy = () => {
392
+ const p = EVMVM.convertFromEntropyToPrivateKey("thishgbmytesentropystringis32bytes!hjkjkhknkjtdyftgkh,jryctdrfygh")
393
+ console.log('p: ', p);
394
+ const res = new EVMChainWallet(evmChainConfig, p, 0)
395
+ console.log('res: ', res);
233
396
  }
234
397
 
398
+ testEntropy()
399
+
400
+ // Uncomment to run tests
235
401
  // testSavingsPocket()
402
+ // testSavingsPocketSVM()
403
+ // testSavingsPocketMultiChain()
236
404
 
237
405
  // testPrice()
238
406
 
package/utils/utils.ts CHANGED
@@ -18,3 +18,10 @@ export const getPrivateKeyFromAnother = (privateKey: any, fromVm: vmTypes, toVm:
18
18
  throw new Error("No conversion available for this vms yet")
19
19
  }
20
20
  }
21
+
22
+
23
+ //TODO:
24
+
25
+ // create a unified evm svm balan e querying function
26
+ //create a chain wallet class that takes address and chain config and probably vm
27
+
@@ -161,23 +161,23 @@ export class VMValidation {
161
161
  * @param minLength - Minimum password length (default: 8)
162
162
  * @throws Error if password is weak
163
163
  */
164
- static validatePassword(password: string, minLength: number = 8): void {
165
- if (typeof password !== 'string') {
166
- throw new Error(`Password must be a string, got: ${typeof password}`);
167
- }
168
-
169
- if (password.length < minLength) {
170
- throw new Error(
171
- `Password too short. Minimum length: ${minLength}, got: ${password.length}`
172
- );
173
- }
174
-
175
- // Check for common weak passwords
176
- const weakPasswords = ['password', '12345678', 'qwerty', 'abc123'];
177
- if (weakPasswords.includes(password.toLowerCase())) {
178
- throw new Error('Password is too weak. Choose a stronger password.');
179
- }
180
- }
164
+ // static validatePassword(password: string, minLength: number = 8): void {
165
+ // if (typeof password !== 'string') {
166
+ // throw new Error(`Password must be a string, got: ${typeof password}`);
167
+ // }
168
+
169
+ // if (password.length < minLength) {
170
+ // throw new Error(
171
+ // `Password too short. Minimum length: ${minLength}, got: ${password.length}`
172
+ // );
173
+ // }
174
+
175
+ // // Check for common weak passwords
176
+ // const weakPasswords = ['password', '12345678', 'qwerty', 'abc123'];
177
+ // if (weakPasswords.includes(password.toLowerCase())) {
178
+ // throw new Error('Password is too weak. Choose a stronger password.');
179
+ // }
180
+ // }
181
181
 
182
182
  /**
183
183
  * Validate amount (bigint)