@deserialize/multi-vm-wallet 1.3.4 → 1.4.1

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 (42) hide show
  1. package/dist/IChainWallet.d.ts +1 -0
  2. package/dist/IChainWallet.js.map +1 -1
  3. package/dist/evm/evm.d.ts +12 -174
  4. package/dist/evm/evm.js +33 -506
  5. package/dist/evm/evm.js.map +1 -1
  6. package/dist/evm/transaction.utils.d.ts +3 -3
  7. package/dist/evm/utils.d.ts +115 -80
  8. package/dist/evm/utils.js +272 -497
  9. package/dist/evm/utils.js.map +1 -1
  10. package/dist/helpers/index.d.ts +1 -0
  11. package/dist/helpers/index.js +5 -0
  12. package/dist/helpers/index.js.map +1 -1
  13. package/dist/savings/index.d.ts +0 -0
  14. package/dist/savings/index.js +3 -0
  15. package/dist/savings/index.js.map +1 -0
  16. package/dist/savings/saving-actions.d.ts +0 -0
  17. package/dist/savings/saving-actions.js +78 -0
  18. package/dist/savings/saving-actions.js.map +1 -0
  19. package/dist/savings/savings-manager.d.ts +1 -1
  20. package/dist/savings/savings-manager.js +3 -3
  21. package/dist/savings/savings-manager.js.map +1 -1
  22. package/dist/svm/svm.d.ts +2 -0
  23. package/dist/svm/svm.js +6 -0
  24. package/dist/svm/svm.js.map +1 -1
  25. package/dist/test.js +7 -7
  26. package/dist/test.js.map +1 -1
  27. package/dist/utils.d.ts +2 -1
  28. package/dist/utils.js +20 -0
  29. package/dist/utils.js.map +1 -1
  30. package/dist/vm.js.map +1 -1
  31. package/package.json +1 -1
  32. package/utils/IChainWallet.ts +2 -0
  33. package/utils/evm/evm.ts +321 -683
  34. package/utils/evm/utils.ts +438 -662
  35. package/utils/helpers/index.ts +6 -0
  36. package/utils/savings/index.ts +1 -0
  37. package/utils/savings/saving-actions.ts +92 -0
  38. package/utils/savings/savings-manager.ts +1 -1
  39. package/utils/svm/svm.ts +8 -0
  40. package/utils/test.ts +11 -3
  41. package/utils/utils.ts +19 -2
  42. package/utils/vm.ts +1 -0
package/dist/evm/evm.js CHANGED
@@ -4,23 +4,18 @@
4
4
  * @param phrase this is the pass phrase for this vm
5
5
  * this is a class that will be responsible for creating several evm wallets code
6
6
  */
7
- var __importDefault = (this && this.__importDefault) || function (mod) {
8
- return (mod && mod.__esModule) ? mod : { "default": mod };
9
- };
10
7
  Object.defineProperty(exports, "__esModule", { value: true });
11
8
  exports.EVMChainWallet = exports.EVMVM = void 0;
12
9
  const walletBip32_1 = require("../walletBip32");
13
10
  const IChainWallet_1 = require("../IChainWallet");
14
11
  const vm_1 = require("../vm");
15
12
  const ethers_1 = require("ethers");
16
- const bn_js_1 = __importDefault(require("bn.js"));
17
13
  const utils_1 = require("./utils");
18
14
  const transactionParsing_1 = require("./transactionParsing");
19
15
  const viem_1 = require("viem");
20
16
  const smartWallet_1 = require("./smartWallet");
21
- const savings_manager_1 = require("../savings/savings-manager");
22
- const smart_savings_1 = require("../savings/smart-savings");
23
17
  const price_1 = require("../price");
18
+ const accounts_1 = require("viem/accounts");
24
19
  class EVMVM extends vm_1.VM {
25
20
  derivationPath = "m/44'/60'/0'/0/"; // Default EVM derivation path
26
21
  constructor(seed) {
@@ -84,47 +79,31 @@ class EVMVM extends vm_1.VM {
84
79
  // Implement token balance retrieval logic here
85
80
  return await (0, utils_1.getTokenBalance)(tokenAddress, address, connection);
86
81
  }
82
+ static convertFromEntropyToPrivateKey = (entropy) => {
83
+ return (0, viem_1.toHex)(entropy);
84
+ };
87
85
  }
88
86
  exports.EVMVM = EVMVM;
89
87
  class EVMChainWallet extends IChainWallet_1.ChainWallet {
90
- client;
91
88
  wallet;
92
89
  smartWallet;
93
- savingsManager;
94
- smartSavingsManager;
90
+ // private savingsManager?: SavingsManager
91
+ // private smartSavingsManager?: SmartSavingsManager
95
92
  constructor(config, privateKey, index) {
93
+ privateKey = privateKey.startsWith('0x') ? privateKey : `0x${privateKey}`;
96
94
  super(config, privateKey, index);
97
- this.connection = new ethers_1.JsonRpcProvider(config.rpcUrl);
98
- const wallet = new ethers_1.Wallet(privateKey, this.connection);
99
- this.wallet = wallet;
100
- this.address = wallet.address;
101
- this.privateKey = privateKey;
102
- //client for viem
103
- this.client = (0, viem_1.createPublicClient)({
104
- chain: {
105
- rpcUrls: {
106
- default: {
107
- http: [config.rpcUrl]
108
- }
109
- },
110
- id: config.chainId,
111
- name: config.name,
112
- nativeCurrency: {
113
- name: config.nativeToken.name,
114
- symbol: config.nativeToken.symbol,
115
- decimals: config.nativeToken.decimals
116
- },
117
- blockExplorers: {
118
- default: {
119
- name: config.name + " Explorer",
120
- url: config.explorerUrl,
121
- apiUrl: config.explorerUrl
122
- },
123
- },
124
- testnet: config.testnet || false
125
- },
95
+ this.connection = (0, viem_1.createPublicClient)({
96
+ chain: (0, utils_1.fromChainToViemChain)(config),
126
97
  transport: (0, viem_1.http)(config.rpcUrl)
127
98
  });
99
+ const account = (0, accounts_1.privateKeyToAccount)(privateKey);
100
+ this.wallet = (0, viem_1.createWalletClient)({
101
+ account,
102
+ chain: (0, utils_1.fromChainToViemChain)(config),
103
+ transport: (0, viem_1.http)(config.rpcUrl)
104
+ });
105
+ this.address = account.address;
106
+ this.privateKey = privateKey;
128
107
  }
129
108
  // ============================================
130
109
  // Smart Wallet Extension Methods
@@ -136,6 +115,9 @@ class EVMChainWallet extends IChainWallet_1.ChainWallet {
136
115
  isAASupportedByChain() {
137
116
  return this.config.aaSupport?.enabled === true;
138
117
  }
118
+ convertFromEntropyToPrivateKey = (entropy) => {
119
+ return (0, viem_1.toHex)(entropy);
120
+ };
139
121
  /**
140
122
  * Check if smart wallet is initialized and ready for AA operations
141
123
  * @returns true if extend() has been called and smart wallet exists
@@ -143,6 +125,9 @@ class EVMChainWallet extends IChainWallet_1.ChainWallet {
143
125
  isSmartWalletInitialized() {
144
126
  return !!this.smartWallet;
145
127
  }
128
+ // createSavingsManager(mnemonic: string, index: number = 0, chain: ChainWalletConfig) {
129
+ // return new SavingsManager(mnemonic, index, (chain))
130
+ // }
146
131
  /**
147
132
  * Validate that AA is available for sponsored transactions
148
133
  * @throws Error with helpful message if AA is not available
@@ -262,7 +247,7 @@ class EVMChainWallet extends IChainWallet_1.ChainWallet {
262
247
  // Existing Wallet Methods
263
248
  // ============================================
264
249
  getWallet() {
265
- return new ethers_1.Wallet(this.privateKey, this.connection);
250
+ return this.wallet;
266
251
  }
267
252
  generateAddress() {
268
253
  return this.address;
@@ -288,17 +273,17 @@ class EVMChainWallet extends IChainWallet_1.ChainWallet {
288
273
  }
289
274
  async transferNative(to, amount) {
290
275
  const wallet = this.getWallet();
291
- return await (0, utils_1.sendNativeToken)(wallet, to, amount.toString(), undefined, this.config.confirmationNo || 5);
276
+ return await (0, utils_1.sendNativeToken)(wallet, this.connection, to, amount.toString(), this.config.confirmationNo || 5);
292
277
  }
293
278
  async transferToken(tokenAddress, to, amount) {
294
279
  const wallet = this.getWallet();
295
- return await (0, utils_1.sendERC20Token)(wallet, tokenAddress.address, to, amount.toString(), undefined, this.config.confirmationNo || 5);
280
+ return await (0, utils_1.sendERC20Token)(wallet, this.connection, tokenAddress.address, to, BigInt(amount.toString()), this.config.confirmationNo || 5);
296
281
  }
297
282
  async getTransactionHistory() {
298
283
  const wallet = this.getWallet();
299
284
  let res;
300
285
  try {
301
- return await (0, transactionParsing_1.getEVMTransactionHistory)(this.client, wallet.address);
286
+ return await (0, transactionParsing_1.getEVMTransactionHistory)(this.connection, this.address);
302
287
  }
303
288
  catch (error) {
304
289
  return [];
@@ -317,138 +302,7 @@ class EVMChainWallet extends IChainWallet_1.ChainWallet {
317
302
  }
318
303
  // Updated swap method signature to match base class so created another method to use it inside swap
319
304
  async swap(tokenAddress, to, amount, slippage = 50) {
320
- if (amount <= 0) {
321
- return {
322
- success: false,
323
- hash: "",
324
- error: "Amount must be greater than 0"
325
- };
326
- }
327
- const tokenOut = {
328
- address: to,
329
- name: '',
330
- symbol: '',
331
- decimals: 18
332
- };
333
- return await this.performCompleteSwap(tokenAddress, tokenOut, amount, slippage);
334
- }
335
- async performCompleteSwap(tokenIn, tokenOut, amount, slippage = 50, recipient, deadline) {
336
- try {
337
- const wallet = this.getWallet();
338
- const chainId = (await this.connection.getNetwork()).chainId.toString();
339
- console.log(` Starting swap on chain ${chainId}:`, {
340
- from: tokenIn.symbol || tokenIn.address,
341
- to: tokenOut.symbol || tokenOut.address,
342
- amount: amount,
343
- slippage: `${slippage / 100}%`
344
- });
345
- // Check if this is a 0G chain that should use Debonk
346
- if ((0, utils_1.isChainSupportedByDebonk)(chainId)) {
347
- console.log('Using Debonk API for 0G chain swap');
348
- return await this.performDebonkSwap(tokenIn, tokenOut, amount, slippage, recipient, deadline);
349
- }
350
- // Otherwise use Kyber (existing flow)
351
- console.log('Using KyberSwap for non-0G chain swap');
352
- return await this.performKyberSwap(tokenIn, tokenOut, amount, slippage, recipient, deadline);
353
- }
354
- catch (error) {
355
- console.error('Swap failed:', error);
356
- throw new Error(`Swap failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
357
- }
358
- }
359
- async performDebonkSwap(tokenIn, tokenOut, amount, slippage = 50, // bps (e.g., 50 = 0.5%)
360
- recipient, deadline) {
361
- try {
362
- const BASE_URL = 'https://evm-api.deserialize.xyz';
363
- const tokenInAddress = tokenIn.address;
364
- const tokenOutAddress = tokenOut.address;
365
- // Convert amount to wei (multiply by 10^18 for 18 decimal tokens)
366
- const amountInWei = (amount * Math.pow(10, tokenIn.decimals || 18)).toString();
367
- // Convert slippage from bps to percentage (e.g., 50 bps -> 0.5%)
368
- const slippagePercentage = slippage / 100;
369
- // Step 1: Get quote from API
370
- const quotePayload = {
371
- tokenA: tokenInAddress,
372
- tokenB: tokenOutAddress,
373
- amountIn: amountInWei, // Use wei amount
374
- dexId: "ZERO_G"
375
- };
376
- const quoteResponse = await fetch(`${BASE_URL}/quote`, {
377
- method: 'POST',
378
- headers: {
379
- 'Content-Type': 'application/json',
380
- },
381
- body: JSON.stringify(quotePayload)
382
- });
383
- if (!quoteResponse.ok) {
384
- const errorText = await quoteResponse.text();
385
- console.error("Quote API error response:", errorText);
386
- return this.fail(`Quote API failed: ${quoteResponse.status} ${errorText}`);
387
- }
388
- const quote = await quoteResponse.json();
389
- // Step 2: Fix the quote dexId for swap API (it expects "ALL")
390
- const modifiedQuote = {
391
- ...quote,
392
- dexId: "ALL" // Change from "ZERO_G" to "ALL" as required by swap API
393
- };
394
- // Step 3: Get wallet address
395
- const walletAddress = await this.getWallet().getAddress();
396
- const swapPayload = {
397
- publicKey: walletAddress,
398
- slippage: slippagePercentage,
399
- quote: modifiedQuote
400
- };
401
- const swapResponse = await fetch(`${BASE_URL}/swap`, {
402
- method: 'POST',
403
- headers: {
404
- 'Content-Type': 'application/json',
405
- },
406
- body: JSON.stringify(swapPayload)
407
- });
408
- if (!swapResponse.ok) {
409
- const errorText = await swapResponse.text();
410
- console.error("Swap API error response:", errorText);
411
- return this.fail(`Swap API failed: ${swapResponse.status} ${errorText}`);
412
- }
413
- const swapData = await swapResponse.json();
414
- const wallet = this.getWallet();
415
- let lastTxHash = '';
416
- // Step 5: Execute each transaction sequentially
417
- for (let i = 0; i < swapData.transactions.length; i++) {
418
- const transaction = swapData.transactions[i];
419
- // Prepare transaction object
420
- const txRequest = {
421
- to: transaction.to,
422
- data: transaction.data,
423
- value: transaction.value,
424
- // gasPrice: 70000000000,
425
- // gasLimit: 70000, // Increase significantly
426
- };
427
- try {
428
- const txResponse = await wallet.sendTransaction(txRequest);
429
- console.log(`Transaction ${i + 1} sent:`, txResponse.hash);
430
- // Wait for confirmation
431
- const receipt = await txResponse.wait();
432
- if (!receipt) {
433
- return this.fail(`Transaction ${i + 1} failed - no receipt received`);
434
- }
435
- const txHash = receipt.hash || txResponse.hash;
436
- lastTxHash = txHash;
437
- }
438
- catch (txError) {
439
- console.error(`Transaction ${i + 1} failed:`, txError);
440
- return this.fail(`Transaction ${i + 1} failed: ${txError?.message ?? String(txError)}`);
441
- }
442
- }
443
- return {
444
- success: true,
445
- hash: lastTxHash // Return the hash of the last transaction
446
- };
447
- }
448
- catch (error) {
449
- console.error("Debonk API swap error:", error);
450
- return this.fail(`Debonk API swap failed: ${error?.message ?? String(error)}`);
451
- }
305
+ throw new Error("Not Implemented");
452
306
  }
453
307
  // Helper method for EVMChainWallet class
454
308
  fail(message) {
@@ -458,347 +312,20 @@ class EVMChainWallet extends IChainWallet_1.ChainWallet {
458
312
  error: message
459
313
  };
460
314
  }
461
- async performKyberSwap(tokenIn, tokenOut, amount, slippage = 50, recipient, deadline) {
462
- try {
463
- const wallet = this.getWallet();
464
- const chainId = (await this.connection.getNetwork()).chainId.toString();
465
- if (!(0, utils_1.isChainSupportedByKyber)(chainId)) {
466
- throw new Error(`Chain ${chainId} is not supported by KyberSwap`);
467
- }
468
- const isNativeIn = tokenIn.address === 'native' ||
469
- tokenIn.address.toLowerCase() === '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee';
470
- const isNativeOut = tokenOut.address === 'native' ||
471
- tokenOut.address.toLowerCase() === '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee';
472
- let tokenInDecimals = 18;
473
- if (!isNativeIn && tokenIn.decimals) {
474
- tokenInDecimals = tokenIn.decimals;
475
- }
476
- else if (!isNativeIn) {
477
- const tokenBalance = await this.getTokenBalance(tokenIn.address);
478
- tokenInDecimals = tokenBalance.decimal;
479
- }
480
- const { tokenInAddress, tokenOutAddress, formattedAmountIn } = (0, utils_1.prepareSwapParams)(tokenIn.address, tokenOut.address, amount.toString(), tokenInDecimals, isNativeIn, isNativeOut);
481
- if (isNativeIn) {
482
- const nativeBalance = await this.getNativeBalance();
483
- const requiredAmount = new bn_js_1.default(formattedAmountIn);
484
- if (nativeBalance.balance.lt(requiredAmount)) {
485
- throw new Error(`Insufficient native balance. Required: ${amount}, Available: ${nativeBalance.formatted}`);
486
- }
487
- }
488
- else {
489
- const tokenBalance = await this.getTokenBalance(tokenIn.address);
490
- const requiredAmount = new bn_js_1.default(formattedAmountIn);
491
- if (tokenBalance.balance.lt(requiredAmount)) {
492
- throw new Error(`Insufficient token balance. Required: ${amount}, Available: ${tokenBalance.formatted}`);
493
- }
494
- }
495
- const swapTx = await (0, utils_1.performSwap)({
496
- chainId,
497
- tokenIn: tokenInAddress,
498
- tokenOut: tokenOutAddress,
499
- amountIn: formattedAmountIn,
500
- sender: this.address,
501
- recipient: recipient || this.address,
502
- slippageTolerance: slippage,
503
- deadline: deadline ? Math.floor(Date.now() / 1000) + deadline : Math.floor(Date.now() / 1000) + 1200, // 20 minutes default
504
- clientId: 'EVMChainWallet'
505
- });
506
- console.log('Kyber swap transaction prepared:', {
507
- to: swapTx.to,
508
- dataLength: swapTx.data?.length || 0,
509
- gasLimit: swapTx.gasLimit?.toString(),
510
- value: swapTx.value?.toString()
511
- });
512
- if (!isNativeIn) {
513
- const approvalResult = await (0, utils_1.checkAndApprove)(wallet, tokenIn.address, swapTx.to, formattedAmountIn, undefined, undefined, this.config.confirmationNo || 1);
514
- if (approvalResult.approvalNeeded && approvalResult.approvalResult) {
515
- if (!approvalResult.approvalResult.success) {
516
- throw new Error('Token approval failed');
517
- }
518
- console.log('Token approval successful');
519
- }
520
- else if (approvalResult.approvalNeeded) {
521
- throw new Error('Token approval was needed but failed');
522
- }
523
- else {
524
- console.log('Token approval not needed - sufficient allowance');
525
- }
526
- }
527
- const result = await (0, utils_1.signSendAndConfirm)(wallet, {
528
- to: swapTx.to,
529
- data: swapTx.data,
530
- value: swapTx.value || '0',
531
- gasLimit: swapTx.gasLimit
532
- }, this.config.confirmationNo || 1);
533
- return result;
534
- }
535
- catch (error) {
536
- throw new Error(`Kyber swap failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
537
- }
538
- }
539
- async getSwapQuote(tokenIn, tokenOut, amount) {
540
- try {
541
- const chainId = (await this.connection.getNetwork()).chainId.toString();
542
- if (!(0, utils_1.isChainSupportedByKyber)(chainId)) {
543
- throw new Error(`Chain ${chainId} is not supported by KyberSwap`);
544
- }
545
- const isNativeIn = tokenIn.address === 'native' ||
546
- tokenIn.address.toLowerCase() === '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee';
547
- const isNativeOut = tokenOut.address === 'native' ||
548
- tokenOut.address.toLowerCase() === '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee';
549
- let tokenInDecimals = 18;
550
- if (!isNativeIn && tokenIn.decimals) {
551
- tokenInDecimals = tokenIn.decimals;
552
- }
553
- else if (!isNativeIn) {
554
- const tokenBalance = await this.getTokenBalance(tokenIn.address);
555
- tokenInDecimals = tokenBalance.decimal;
556
- }
557
- const { tokenInAddress, tokenOutAddress, formattedAmountIn } = (0, utils_1.prepareSwapParams)(tokenIn.address, tokenOut.address, amount.toString(), tokenInDecimals, isNativeIn, isNativeOut);
558
- throw new Error("Quote functionality requires direct API integration - use the swap method for full execution");
559
- }
560
- catch (error) {
561
- console.error('Error getting swap quote:', error);
562
- throw error;
563
- }
564
- }
565
315
  async approveToken(params) {
566
316
  const signer = this.getWallet();
567
- const r = await (0, utils_1.approveToken)(signer, params.tokenAddress, params.spender, params.amountRaw, params.gasLimit, params.confirmations ?? this.config.confirmationNo ?? 1);
317
+ const r = await (0, utils_1.approveToken)(signer, this.connection, params.tokenAddress, params.spender, BigInt(params.amountRaw), params.confirmations ?? this.config.confirmationNo ?? 1);
568
318
  return {
569
319
  hash: r.hash,
570
320
  success: r.success,
571
- error: r.error,
572
- };
573
- }
574
- async executeContractMethod(params) {
575
- const signer = this.getWallet();
576
- const r = await (0, utils_1.executeContractMethod)(signer, params.contractAddress, params.abi, params.methodName, params.methodParams ?? [], params.value);
577
- return {
578
- hash: r.hash,
579
- success: r.success,
580
- error: r.error,
581
321
  };
582
322
  }
583
323
  async signMessage(message) {
584
- const signer = this.getWallet();
585
- return signer.signMessage(message);
586
- }
587
- // ============================================
588
- // Savings Pocket Methods
589
- // ============================================
590
- /**
591
- * Get or create the SavingsManager instance (lazy initialization)
592
- * @private
593
- */
594
- getSavingsManager() {
595
- if (!this.savingsManager) {
596
- // Create a VM instance from the current wallet's seed
597
- // We need to get the seed from the privateKey
598
- // For now, we'll create an EVMVM from the wallet
599
- // Note: This requires access to the seed, which we'll need to handle
600
- throw new Error("SavingsManager requires access to the seed phrase. " +
601
- "Please initialize the wallet with a seed phrase or mnemonic to use savings features.");
602
- }
603
- return this.savingsManager;
604
- }
605
- /**
606
- * Initialize savings functionality with a seed phrase
607
- *
608
- * This must be called before using any savings methods.
609
- * The seed is used to derive savings accounts using BIP-44.
610
- *
611
- * @param seed - The wallet seed (hex string)
612
- *
613
- * @example
614
- * const seed = VM.mnemonicToSeed(mnemonic);
615
- * wallet.initializeSavings(seed);
616
- */
617
- initializeSavings(seed) {
618
- const vm = new EVMVM(seed);
619
- this.savingsManager = new savings_manager_1.SavingsManager(vm);
620
- }
621
- /**
622
- * Derive a new savings account from BIP-44 account index
623
- *
624
- * @param accountIndex - The BIP-44 account index (1+ for savings, 0 is main wallet)
625
- * @returns SavingsAccount with derived address and private key
626
- *
627
- * @example
628
- * const savingsAccount1 = wallet.deriveSavingsAccount(1); // m/44'/60'/1'/0/0
629
- * const savingsAccount2 = wallet.deriveSavingsAccount(2); // m/44'/60'/2'/0/0
630
- */
631
- deriveSavingsAccount(accountIndex) {
632
- return this.getSavingsManager().createSavingsAccount(accountIndex);
633
- }
634
- /**
635
- * Transfer native tokens to a savings account
636
- *
637
- * Security: Always derives the destination address from accountIndex.
638
- *
639
- * @param accountIndex - Savings account index to deposit to
640
- * @param amount - Amount in ether units (e.g., "1.5" for 1.5 ETH)
641
- * @param options - Optional security and priority settings
642
- * @returns Transaction result
643
- *
644
- * @example
645
- * const result = await wallet.transferToSavings(1, "1.5"); // Send 1.5 ETH to savings account 1
646
- */
647
- async transferToSavings(accountIndex, amount, options) {
648
- const manager = this.getSavingsManager();
649
- // Build transaction using derived address
650
- const amountWei = (0, viem_1.parseEther)(amount);
651
- const txParams = manager.buildDepositTransaction(accountIndex, amountWei, options);
652
- // Execute using existing transferNative method
653
- return await this.transferNative(txParams.to, Number(amount));
654
- }
655
- /**
656
- * Withdraw native tokens from a savings account
657
- *
658
- * Security: Uses the derived private key for signing.
659
- *
660
- * @param accountIndex - Savings account index to withdraw from
661
- * @param to - Destination address
662
- * @param amount - Amount in ether units (e.g., "0.5" for 0.5 ETH)
663
- * @param options - Optional security and priority settings
664
- * @returns Transaction result
665
- *
666
- * @example
667
- * const result = await wallet.withdrawFromSavings(1, destinationAddress, "0.5");
668
- */
669
- async withdrawFromSavings(accountIndex, to, amount, options) {
670
- const manager = this.getSavingsManager();
671
- // Build withdrawal transaction
672
- const amountWei = (0, viem_1.parseEther)(amount);
673
- const withdrawalParams = manager.buildWithdrawalTransaction(accountIndex, to, amountWei, options);
674
- // Create a temporary wallet with the savings account private key
675
- const savingsWallet = new ethers_1.Wallet(withdrawalParams.privateKey, this.connection);
676
- // Send transaction using the savings wallet
677
- const tx = await savingsWallet.sendTransaction({
678
- to: withdrawalParams.to,
679
- value: withdrawalParams.value
680
- });
681
- const receipt = await tx.wait(this.config.confirmationNo || 1);
682
- return {
683
- success: receipt?.status === 1,
684
- hash: receipt?.hash || tx.hash
685
- };
686
- }
687
- /**
688
- * Verify a stored savings address matches the derived address
689
- *
690
- * Security: Prevents database tampering attacks.
691
- *
692
- * @param accountIndex - The account index to verify
693
- * @param storedAddress - The address from storage/database
694
- * @returns Verification result
695
- *
696
- * @example
697
- * const result = wallet.verifySavingsAddress(1, storedAddress);
698
- * if (!result.isValid) {
699
- * console.error("Security alert: Address tampering detected!");
700
- * }
701
- */
702
- verifySavingsAddress(accountIndex, storedAddress) {
703
- return this.getSavingsManager().verifySavingsAddress(accountIndex, storedAddress);
704
- }
705
- /**
706
- * Audit multiple savings addresses at once
707
- *
708
- * @param addresses - Map of accountIndex to stored address
709
- * @returns Audit result with summary and details
710
- *
711
- * @example
712
- * const addresses = new Map([[1, "0xabc..."], [2, "0xdef..."]]);
713
- * const audit = wallet.auditSavingsAddresses(addresses);
714
- * console.log(`Valid: ${audit.valid}/${audit.total}`);
715
- */
716
- auditSavingsAddresses(addresses) {
717
- return this.getSavingsManager().auditSavingsAddresses(addresses);
718
- }
719
- /**
720
- * Get savings account information without exposing private key
721
- *
722
- * @param accountIndex - The account index
723
- * @returns Public account information (address and derivation path)
724
- *
725
- * @example
726
- * const info = wallet.getSavingsAccountInfo(1);
727
- * console.log(`Address: ${info.address}`);
728
- * console.log(`Path: ${info.derivationPath}`); // m/44'/60'/1'/0/0
729
- */
730
- getSavingsAccountInfo(accountIndex) {
731
- return this.getSavingsManager().getSavingsAccountInfo(accountIndex);
732
- }
733
- // ============================================
734
- // Smart Savings Methods (EIP-7702)
735
- // ============================================
736
- /**
737
- * Get or create the SmartSavingsManager instance (lazy initialization)
738
- * @private
739
- */
740
- getSmartSavingsManager() {
741
- if (!this.smartSavingsManager) {
742
- this.smartSavingsManager = new smart_savings_1.SmartSavingsManager(this.config);
743
- }
744
- return this.smartSavingsManager;
745
- }
746
- /**
747
- * Upgrade a savings account to a smart account with EIP-7702 delegation
748
- *
749
- * This enables advanced features:
750
- * - Lock modules for time-locked savings
751
- * - Hooks for spend & save
752
- * - Session keys for periodic savings
753
- * - Sponsored transactions via paymaster
754
- *
755
- * @param accountIndex - The savings account index to upgrade
756
- * @param options - Optional smart wallet configuration
757
- * @param autoInitialize - Whether to initialize the smart wallet (default: false)
758
- * @returns SmartSavingsAccount with EVMSmartWallet instance
759
- *
760
- * @example
761
- * // Upgrade without initialization
762
- * const smartSavings = await wallet.upgradeSavingsToSmartAccount(1);
763
- * await smartSavings.smartWallet.initialize(); // Initialize separately
764
- *
765
- * @example
766
- * // Upgrade and initialize in one step
767
- * const smartSavings = await wallet.upgradeSavingsToSmartAccount(1, {}, true);
768
- * // Ready to use immediately
769
- */
770
- async upgradeSavingsToSmartAccount(accountIndex, options, autoInitialize = false) {
771
- const manager = this.getSmartSavingsManager();
772
- // First derive the basic savings account
773
- const basicSavings = this.deriveSavingsAccount(accountIndex);
774
- // Then upgrade to smart account
775
- if (autoInitialize) {
776
- return await manager.upgradeSavingsAndInitialize(basicSavings, options);
777
- }
778
- else {
779
- return await manager.upgradeSavingsToSmartAccount(basicSavings, options);
780
- }
781
- }
782
- /**
783
- * Check if smart savings is supported on this chain
784
- *
785
- * @returns true if chain supports Account Abstraction
786
- *
787
- * @example
788
- * if (wallet.isSmartSavingsSupported()) {
789
- * const smartSavings = await wallet.upgradeSavingsToSmartAccount(1);
790
- * } else {
791
- * console.log("This chain doesn't support smart savings");
792
- * }
793
- */
794
- isSmartSavingsSupported() {
795
- try {
796
- const manager = this.getSmartSavingsManager();
797
- return manager.canUpgradeToSmartAccount();
798
- }
799
- catch (error) {
800
- return false;
324
+ const signer = this.wallet;
325
+ if (!signer.account) {
326
+ throw new Error("Account is required for signing, signer.account from this.wallet is undefined");
801
327
  }
328
+ return signer.signMessage({ message, account: signer.account?.address });
802
329
  }
803
330
  }
804
331
  exports.EVMChainWallet = EVMChainWallet;