@deserialize/multi-vm-wallet 1.5.21 → 1.5.31

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.
package/utils/evm/evm.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import { EntropyToMnemonic, EVMDeriveChildPrivateKey } from "../walletBip32";
8
- import { ChainWallet } from "../IChainWallet";
8
+ import { ChainAddress, ChainWallet } from "../IChainWallet";
9
9
  import { Balance, ChainWalletConfig, NFTInfo, UserTokenBalance, TokenInfo, TransactionResult, NFT, DiscoveredWallet, WalletDiscoveryOptions, WalletDiscoveryResult, PocketDiscoveryOptions } from "../types";
10
10
  import { VM } from "../vm";
11
11
  import { VMValidation, sanitizeError, logSafeError } from "../vm-validation";
@@ -50,6 +50,133 @@ import { Account, generatePrivateKey, privateKeyToAccount } from "viem/accounts"
50
50
  // import { extendWalletClientWithSavings } from "../savings";
51
51
  // import { SavingsManager } from "../savings/saving-actions";
52
52
 
53
+ /**
54
+ * Create a viem public client for the given EVM chain configuration.
55
+ *
56
+ * @param config - Chain configuration with RPC endpoint and chain metadata.
57
+ * @returns Configured viem `PublicClient`.
58
+ */
59
+ export const createEvmPublicClient = (config: ChainWalletConfig): PublicClient =>
60
+ createPublicClient({
61
+ chain: fromChainToViemChain(config),
62
+ transport: http(config.rpcUrl),
63
+ });
64
+
65
+ /**
66
+ * Create a viem wallet client bound to a specific account.
67
+ *
68
+ * @param config - Chain configuration with RPC endpoint and chain metadata.
69
+ * @param account - Account used for signing transactions and messages.
70
+ * @returns Configured viem `WalletClient`.
71
+ */
72
+ export const createEvmWalletClient = (config: ChainWalletConfig, account: Account): WalletClient =>
73
+ createWalletClient({
74
+ account,
75
+ chain: fromChainToViemChain(config),
76
+ transport: http(config.rpcUrl),
77
+ });
78
+
79
+ /**
80
+ * Fetch transaction history and return an empty array on failure.
81
+ *
82
+ * @param connection - viem public client used to query chain data.
83
+ * @param address - Wallet address to inspect.
84
+ * @returns Parsed EVM transaction history items.
85
+ */
86
+ export const getEvmTransactionHistorySafe = async (
87
+ connection: PublicClient,
88
+ address: string
89
+ ): Promise<EVMTransactionHistoryItem[]> => {
90
+ try {
91
+ return await getEVMTransactionHistory(connection, address as Hex);
92
+ } catch {
93
+ return [];
94
+ }
95
+ };
96
+
97
+ /**
98
+ * Fetch token prices for EVM tokens on the configured chain.
99
+ *
100
+ * @param config - Chain configuration used for chain ID resolution.
101
+ * @param tokenAddresses - Token contract addresses to query.
102
+ * @returns Price data keyed by token address.
103
+ * @throws Error when the pricing service returns an error payload.
104
+ */
105
+ export const getSvmPricesForTokens = async (
106
+ config: ChainWalletConfig,
107
+ tokenAddresses: string[]
108
+ ): Promise<PriceResponse> => {
109
+ const result = await fetchPrices({
110
+ vm: 'EVM',
111
+ chainId: config.chainId,
112
+ tokenAddresses,
113
+ });
114
+
115
+ if (result.error) {
116
+ throw new Error(result.error.message);
117
+ }
118
+
119
+ return result.data as PriceResponse;
120
+ };
121
+
122
+ /**
123
+ * Get native token balance for an address.
124
+ *
125
+ * @param address - Wallet address to query.
126
+ * @param connection - viem public client.
127
+ * @returns Native balance details.
128
+ */
129
+ export const getEvmNativeBalance = async (
130
+ address: string,
131
+ connection: PublicClient
132
+ ): Promise<Balance> => {
133
+ return await EVMVM.getNativeBalance(address, connection);
134
+ };
135
+
136
+ /**
137
+ * Get ERC-20 token balance for an address.
138
+ *
139
+ * @param address - Wallet address to query.
140
+ * @param tokenAddress - ERC-20 contract address.
141
+ * @param connection - viem public client.
142
+ * @returns Token balance details.
143
+ */
144
+ export const getEvmTokenBalance = async (
145
+ address: string,
146
+ tokenAddress: string,
147
+ connection: PublicClient
148
+ ): Promise<Balance> => {
149
+ return await EVMVM.getTokenBalance(address, tokenAddress, connection);
150
+ };
151
+
152
+ /**
153
+ * Discover token balances held by an address.
154
+ *
155
+ * @param address - Wallet address to scan.
156
+ * @param config - Chain configuration.
157
+ * @returns Discovered token balances.
158
+ */
159
+ export const discoverEvmTokens = async (
160
+ address: string,
161
+ config: ChainWalletConfig
162
+ ): Promise<UserTokenBalance<string>[]> => {
163
+ return await discoverTokens(address, config);
164
+ };
165
+
166
+ /**
167
+ * Discover NFTs held by an address.
168
+ *
169
+ * @param address - Wallet address to scan.
170
+ * @param config - Chain configuration.
171
+ * @returns Discovered NFT items.
172
+ */
173
+ export const discoverEvmNFTs = async (
174
+ address: string,
175
+ config: ChainWalletConfig
176
+ ): Promise<NFT[]> => {
177
+ return await discoverNFTs(address, config);
178
+ };
179
+
53
180
 
54
181
  interface DebonkQuoteResponse {
55
182
  tokenA: string;
@@ -98,6 +225,15 @@ export class EVMVM extends VM<string, string, PublicClient> {
98
225
 
99
226
  getTokenInfo = getTokenInfo
100
227
  static getTokenInfo = getTokenInfo
228
+ /**
229
+ * Derive an EVM private key for a wallet index.
230
+ *
231
+ * @param index - Wallet index in the derivation path.
232
+ * @param seed - Optional explicit seed (takes priority over mnemonic).
233
+ * @param mnemonic - Optional mnemonic used when seed is not provided.
234
+ * @param derivationPath - Base derivation path prefix.
235
+ * @returns Derived private key and index.
236
+ */
101
237
  generatePrivateKey(index: number, seed?: string, mnemonic?: string, derivationPath = this.derivationPath) {
102
238
  // Validate inputs
103
239
  VMValidation.validateIndex(index, 'Wallet index');
@@ -121,10 +257,22 @@ export class EVMVM extends VM<string, string, PublicClient> {
121
257
  return { privateKey, index };
122
258
  }
123
259
 
260
+ /**
261
+ * Convert raw private key entropy into a mnemonic phrase.
262
+ *
263
+ * @param privateKey - Private key entropy input.
264
+ * @returns Generated mnemonic phrase.
265
+ */
124
266
  static generateMnemonicFromPrivateKey(privateKey: string): string {
125
267
 
126
268
  return EntropyToMnemonic(privateKey)
127
269
  }
270
+ /**
271
+ * Create an `EVMVM` instance from a mnemonic phrase.
272
+ *
273
+ * @param mnemonic - BIP-39 mnemonic phrase.
274
+ * @returns Initialized EVM VM instance.
275
+ */
128
276
  static fromMnemonic(mnemonic: string): VM<string, string, PublicClient> {
129
277
  const seed = VM.mnemonicToSeed(mnemonic)
130
278
  return new EVMVM(seed)
@@ -191,18 +339,40 @@ export class EVMVM extends VM<string, string, PublicClient> {
191
339
  return ethers.getAddress(address);
192
340
  }
193
341
 
342
+ /**
343
+ * Read the native token balance for an address.
344
+ *
345
+ * @param address - Wallet address to query.
346
+ * @param connection - viem public client.
347
+ * @returns Native balance details.
348
+ */
194
349
  static async getNativeBalance(address: string, connection: PublicClient): Promise<Balance> {
195
350
  // Implement native balance retrieval logic here
196
351
  return await getNativeBalance(address as Hex, connection)
197
352
  }
198
353
 
354
+ /**
355
+ * Read an ERC-20 token balance for an address.
356
+ *
357
+ * @param address - Wallet address that owns the token.
358
+ * @param tokenAddress - ERC-20 contract address.
359
+ * @param connection - viem public client.
360
+ * @returns Token balance details.
361
+ */
199
362
  static async getTokenBalance(address: string, tokenAddress: string, connection: PublicClient): Promise<Balance> {
200
363
  // Implement token balance retrieval logic here
201
364
  return await getTokenBalance(tokenAddress as Hex, address as Hex, connection)
202
365
  }
203
366
 
367
+ /**
368
+ * Convert arbitrary entropy text into a deterministic private-key-like hash.
369
+ *
370
+ * @param entropy - Input entropy string.
371
+ * @returns `keccak256` hash of the input.
372
+ */
204
373
  static convertFromEntropyToPrivateKey = (entropy: string): string => {
205
- return toHex(entropy).substring(0, 64)
374
+ const p = ethers.id(entropy)
375
+ return p
206
376
  }
207
377
 
208
378
  /**
@@ -687,29 +857,106 @@ export class EVMVM extends VM<string, string, PublicClient> {
687
857
 
688
858
  }
689
859
 
860
+ export class EVMChainAddress extends ChainAddress<string, PublicClient> {
861
+ /**
862
+ * Create an EVM chain address wrapper with an attached public client.
863
+ *
864
+ * @param config - Chain configuration.
865
+ * @param address - Wallet address.
866
+ * @param index - Optional derivation index.
867
+ */
868
+ constructor(config: ChainWalletConfig, address: string, index?: number) {
869
+ const connection = createEvmPublicClient(config);
870
+ super(config, address, index);
871
+ this.connection = connection;
872
+ }
873
+
874
+ /**
875
+ * Get native balance for this address.
876
+ *
877
+ * @returns Native balance details.
878
+ */
879
+ async getNativeBalance(): Promise<Balance> {
880
+ return await getEvmNativeBalance(this.address, this.connection!);
881
+ }
882
+
883
+ /**
884
+ * Get ERC-20 token balance for this address.
885
+ *
886
+ * @param tokenAddress - ERC-20 contract address.
887
+ * @returns Token balance details.
888
+ */
889
+ async getTokenBalance(tokenAddress: string): Promise<Balance> {
890
+ return await getEvmTokenBalance(this.address, tokenAddress, this.connection!);
891
+ }
892
+
893
+ /**
894
+ * Discover fungible tokens held by this address.
895
+ *
896
+ * @returns Discovered token balances.
897
+ */
898
+ async discoverToken(): Promise<UserTokenBalance<string>[]> {
899
+ return await discoverEvmTokens(this.address, this.config);
900
+ }
901
+
902
+ /**
903
+ * Discover NFTs held by this address.
904
+ *
905
+ * @returns Discovered NFTs.
906
+ */
907
+ async discoverNFT(): Promise<NFT[]> {
908
+ return await discoverEvmNFTs(this.address, this.config);
909
+ }
910
+
911
+ /**
912
+ * Retrieve transaction history for this address.
913
+ *
914
+ * @returns Parsed transaction history entries.
915
+ */
916
+ async getTransactionHistory(): Promise<EVMTransactionHistoryItem[]> {
917
+ return await getEvmTransactionHistorySafe(this.connection!, this.address);
918
+ }
919
+
920
+ /**
921
+ * Fetch price data for the provided token addresses.
922
+ *
923
+ * @param tokenAddresses - Token contract addresses.
924
+ * @returns Price response.
925
+ */
926
+ async getPrices(tokenAddresses: string[]): Promise<PriceResponse> {
927
+ return await getSvmPricesForTokens(this.config, tokenAddresses);
928
+ }
929
+
930
+
931
+ }
932
+
933
+
690
934
  export class EVMChainWallet extends ChainWallet<string, string, PublicClient> {
691
935
  wallet: WalletClient
692
936
  private smartWallet?: EVMSmartWallet
693
937
  // private savingsManager?: SavingsManager
694
938
  // private smartSavingsManager?: SmartSavingsManager
695
939
 
940
+ /**
941
+ * Create an EVM wallet bound to a chain configuration and private key.
942
+ *
943
+ * @param config - Chain configuration.
944
+ * @param privateKey - Hex private key (with or without `0x` prefix).
945
+ * @param index - Wallet index.
946
+ */
696
947
  constructor(config: ChainWalletConfig, privateKey: string, index: number) {
697
948
  privateKey = privateKey.startsWith('0x') ? privateKey : `0x${privateKey}`
698
- super(config, privateKey, index);
699
- this.connection = createPublicClient(
700
- {
701
- chain: fromChainToViemChain(config),
702
- transport: http(config.rpcUrl)
703
- },
704
- )
949
+ const connection = createEvmPublicClient(config);
705
950
  const account = privateKeyToAccount(privateKey as Hex)
706
- this.wallet = createWalletClient({
707
- account,
708
- chain: fromChainToViemChain(config),
709
- transport: http(config.rpcUrl)
710
- })
711
- this.address = account.address
951
+ const wallet = createEvmWalletClient(config, account);
952
+ const address = account.address
953
+ super(config, address, privateKey, index);
954
+
955
+
712
956
  this.privateKey = privateKey;
957
+ this.wallet = wallet;
958
+ this.connection = connection;
959
+ this.address = address
713
960
  }
714
961
 
715
962
  // ============================================
@@ -724,6 +971,12 @@ export class EVMChainWallet extends ChainWallet<string, string, PublicClient> {
724
971
  return this.config.aaSupport?.enabled === true;
725
972
  }
726
973
 
974
+ /**
975
+ * Convert entropy text into a hex string.
976
+ *
977
+ * @param entropy - Entropy string.
978
+ * @returns Hex-encoded string.
979
+ */
727
980
  convertFromEntropyToPrivateKey = (entropy: string): string => {
728
981
  return toHex(entropy)
729
982
  }
@@ -877,73 +1130,132 @@ export class EVMChainWallet extends ChainWallet<string, string, PublicClient> {
877
1130
  // Existing Wallet Methods
878
1131
  // ============================================
879
1132
 
1133
+ /**
1134
+ * Get the underlying viem wallet client.
1135
+ *
1136
+ * @returns Wallet client instance.
1137
+ */
880
1138
  getWallet(): WalletClient {
881
1139
  return this.wallet
882
1140
  }
883
1141
 
1142
+ /**
1143
+ * Get this wallet's address.
1144
+ *
1145
+ * @returns Wallet address.
1146
+ */
884
1147
  generateAddress(): string {
885
1148
  return this.address;
886
1149
  }
887
1150
 
1151
+ /**
1152
+ * Get native token balance for this wallet.
1153
+ *
1154
+ * @returns Native balance details.
1155
+ */
888
1156
  async getNativeBalance(): Promise<Balance> {
889
1157
  // Implement native balance retrieval logic here
890
- return await EVMVM.getNativeBalance(this.address, this.connection!)
1158
+ return await getEvmNativeBalance(this.address, this.connection!);
891
1159
  }
892
1160
 
1161
+ /**
1162
+ * Get ERC-20 token balance for this wallet.
1163
+ *
1164
+ * @param tokenAddress - ERC-20 contract address.
1165
+ * @returns Token balance details.
1166
+ */
893
1167
  async getTokenBalance(tokenAddress: string): Promise<Balance> {
894
1168
  // Implement token balance retrieval logic here
895
- return await EVMVM.getTokenBalance(this.address, tokenAddress, this.connection!)
1169
+ return await getEvmTokenBalance(this.address, tokenAddress, this.connection!);
896
1170
  }
897
1171
 
1172
+ /**
1173
+ * Get ERC-20 token metadata.
1174
+ *
1175
+ * @param tokenAddress - ERC-20 contract address.
1176
+ * @returns Token metadata returned by `getTokenInfo`.
1177
+ */
898
1178
  async getTokenInfo(tokenAddress: string) {
899
1179
  return await EVMVM.getTokenInfo(tokenAddress as Hex, this.connection!)
900
1180
  }
901
1181
 
1182
+ /**
1183
+ * Discover fungible tokens held by this wallet.
1184
+ *
1185
+ * @returns Discovered token balances.
1186
+ */
902
1187
  async discoverToken(): Promise<UserTokenBalance<string>[]> {
903
1188
  // Implement token discovery logic here
904
- return await discoverTokens(this.address, this.config)
1189
+ return await discoverEvmTokens(this.address, this.config);
905
1190
  }
906
1191
 
1192
+ /**
1193
+ * Discover NFTs held by this wallet.
1194
+ *
1195
+ * @returns Discovered NFTs.
1196
+ */
907
1197
  async discoverNFT(): Promise<NFT[]> {
908
1198
  // Implement NFT discovery logic here
909
- return await discoverNFTs(this.address, this.config)
1199
+ return await discoverEvmNFTs(this.address, this.config);
910
1200
  }
911
1201
 
1202
+ /**
1203
+ * Send native tokens to another address.
1204
+ *
1205
+ * @param to - Recipient address.
1206
+ * @param amount - Amount in native token units.
1207
+ * @returns Transaction result.
1208
+ */
912
1209
  async transferNative(to: string, amount: number): Promise<TransactionResult> {
913
1210
  const wallet = this.getWallet();
914
1211
  return await sendNativeToken(wallet, this.connection!, to as Hex, amount.toString(), this.config.confirmationNo || 5);
915
1212
  }
916
1213
 
1214
+ /**
1215
+ * Send ERC-20 tokens to another address.
1216
+ *
1217
+ * @param tokenAddress - Token info containing contract address.
1218
+ * @param to - Recipient address.
1219
+ * @param amount - Token amount to transfer.
1220
+ * @returns Transaction result.
1221
+ */
917
1222
  async transferToken(tokenAddress: TokenInfo, to: string, amount: number): Promise<TransactionResult> {
918
1223
  const wallet = this.getWallet();
919
1224
  return await sendERC20Token(wallet, this.connection!, tokenAddress.address as Hex, to as Hex, BigInt(amount.toString()), this.config.confirmationNo || 5);
920
1225
  }
921
1226
 
1227
+ /**
1228
+ * Get transaction history for this wallet address.
1229
+ *
1230
+ * @returns Parsed transaction history entries.
1231
+ */
922
1232
  async getTransactionHistory(): Promise<EVMTransactionHistoryItem[]> {
923
1233
  const wallet = this.getWallet();
924
1234
  let res: EVMTransactionHistoryItem
925
- try {
926
- return await getEVMTransactionHistory(this.connection!, this.address as Hex);
927
- } catch (error) {
928
- return []
929
- }
1235
+ return await getEvmTransactionHistorySafe(this.connection!, this.address);
930
1236
  }
931
1237
 
1238
+ /**
1239
+ * Fetch prices for token contracts on this wallet's chain.
1240
+ *
1241
+ * @param tokenAddresses - Token contract addresses.
1242
+ * @returns Price response.
1243
+ */
932
1244
  async getPrices(tokenAddresses: string[]): Promise<PriceResponse> {
933
- const result = await fetchPrices({
934
- vm: 'EVM',
935
- chainId: this.config.chainId,
936
- tokenAddresses,
937
- });
938
-
939
- if (result.error) {
940
- throw new Error(result.error.message);
941
- }
942
-
943
- return result.data as PriceResponse;
1245
+ return await getSvmPricesForTokens(this.config, tokenAddresses);
944
1246
  }
945
1247
 
946
1248
  // Updated swap method signature to match base class so created another method to use it inside swap
1249
+ /**
1250
+ * Swap tokens using the chain's swap integration.
1251
+ *
1252
+ * @param tokenAddress - Source token info.
1253
+ * @param to - Destination token or recipient address, depending on integration.
1254
+ * @param amount - Amount to swap.
1255
+ * @param slippage - Slippage tolerance in basis points.
1256
+ * @returns Transaction result.
1257
+ * @throws Error Always throws because this method is not implemented.
1258
+ */
947
1259
  async swap(
948
1260
  tokenAddress: TokenInfo,
949
1261
  to: string,
@@ -958,6 +1270,12 @@ export class EVMChainWallet extends ChainWallet<string, string, PublicClient> {
958
1270
 
959
1271
 
960
1272
  // Helper method for EVMChainWallet class
1273
+ /**
1274
+ * Build a standardized failed swap result.
1275
+ *
1276
+ * @param message - Failure reason.
1277
+ * @returns Failed Debonk swap result.
1278
+ */
961
1279
  private fail(message: string): DebonkSwapResult {
962
1280
  return {
963
1281
  success: false,
@@ -970,6 +1288,17 @@ export class EVMChainWallet extends ChainWallet<string, string, PublicClient> {
970
1288
 
971
1289
 
972
1290
 
1291
+ /**
1292
+ * Approve ERC-20 token allowance for a spender.
1293
+ *
1294
+ * @param params - Approval parameters.
1295
+ * @param params.tokenAddress - ERC-20 contract address.
1296
+ * @param params.spender - Spender address to approve.
1297
+ * @param params.amountRaw - Raw allowance amount.
1298
+ * @param params.confirmations - Confirmation blocks to wait for.
1299
+ * @param params.gasLimit - Optional gas limit (currently unused in this wrapper).
1300
+ * @returns Transaction result.
1301
+ */
973
1302
  async approveToken(params: {
974
1303
  tokenAddress: string
975
1304
  spender: string
@@ -996,6 +1325,13 @@ export class EVMChainWallet extends ChainWallet<string, string, PublicClient> {
996
1325
 
997
1326
 
998
1327
 
1328
+ /**
1329
+ * Sign an arbitrary message with this wallet account.
1330
+ *
1331
+ * @param message - Message to sign.
1332
+ * @returns Hex signature string.
1333
+ * @throws Error if wallet account is unavailable.
1334
+ */
999
1335
  async signMessage(message: string): Promise<string> {
1000
1336
 
1001
1337
  const signer = this.wallet
@@ -1006,260 +1342,4 @@ export class EVMChainWallet extends ChainWallet<string, string, PublicClient> {
1006
1342
  return signer.signMessage({ message, account: signer.account?.address })
1007
1343
  }
1008
1344
 
1009
- // // ============================================
1010
- // // Savings Pocket Methods
1011
- // // ============================================
1012
-
1013
- // /**
1014
- // * Get or create the SavingsManager instance (lazy initialization)
1015
- // * @private
1016
- // */
1017
- // private getSavingsManager(): SavingsManager {
1018
- // if (!this.savingsManager) {
1019
- // // Create a VM instance from the current wallet's seed
1020
- // // We need to get the seed from the privateKey
1021
- // // For now, we'll create an EVMVM from the wallet
1022
- // // Note: This requires access to the seed, which we'll need to handle
1023
- // throw new Error(
1024
- // "SavingsManager requires access to the seed phrase. " +
1025
- // "Please initialize the wallet with a seed phrase or mnemonic to use savings features."
1026
- // );
1027
- // }
1028
- // return this.savingsManager;
1029
- // }
1030
-
1031
- // /**
1032
- // * Initialize savings functionality with a seed phrase
1033
- // *
1034
- // * This must be called before using any savings methods.
1035
- // * The seed is used to derive savings accounts using BIP-44.
1036
- // *
1037
- // * @param seed - The wallet seed (hex string)
1038
- // *
1039
- // * @example
1040
- // * const seed = VM.mnemonicToSeed(mnemonic);
1041
- // * wallet.initializeSavings(seed);
1042
- // */
1043
- // initializeSavings(seed: string): void {
1044
- // const vm = new EVMVM(seed);
1045
- // this.savingsManager = new SavingsManager(vm);
1046
- // }
1047
-
1048
- // /**
1049
- // * Derive a new savings account from BIP-44 account index
1050
- // *
1051
- // * @param accountIndex - The BIP-44 account index (1+ for savings, 0 is main wallet)
1052
- // * @returns SavingsAccount with derived address and private key
1053
- // *
1054
- // * @example
1055
- // * const savingsAccount1 = wallet.deriveSavingsAccount(1); // m/44'/60'/1'/0/0
1056
- // * const savingsAccount2 = wallet.deriveSavingsAccount(2); // m/44'/60'/2'/0/0
1057
- // */
1058
- // deriveSavingsAccount(accountIndex: number): SavingsAccount {
1059
- // return this.getSavingsManager().createSavingsAccount(accountIndex);
1060
- // }
1061
-
1062
- // /**
1063
- // * Transfer native tokens to a savings account
1064
- // *
1065
- // * Security: Always derives the destination address from accountIndex.
1066
- // *
1067
- // * @param accountIndex - Savings account index to deposit to
1068
- // * @param amount - Amount in ether units (e.g., "1.5" for 1.5 ETH)
1069
- // * @param options - Optional security and priority settings
1070
- // * @returns Transaction result
1071
- // *
1072
- // * @example
1073
- // * const result = await wallet.transferToSavings(1, "1.5"); // Send 1.5 ETH to savings account 1
1074
- // */
1075
- // async transferToSavings(
1076
- // accountIndex: number,
1077
- // amount: string,
1078
- // options?: TransferToSavingsOptions
1079
- // ): Promise<TransactionResult> {
1080
- // const manager = this.getSavingsManager();
1081
-
1082
- // // Build transaction using derived address
1083
- // const amountWei = parseEther(amount);
1084
- // const txParams = manager.buildDepositTransaction(accountIndex, amountWei, options);
1085
-
1086
- // // Execute using existing transferNative method
1087
- // return await this.transferNative(txParams.to, Number(amount));
1088
- // }
1089
-
1090
- // // /**
1091
- // // * Withdraw native tokens from a savings account
1092
- // // *
1093
- // // * Security: Uses the derived private key for signing.
1094
- // // *
1095
- // // * @param accountIndex - Savings account index to withdraw from
1096
- // // * @param to - Destination address
1097
- // // * @param amount - Amount in ether units (e.g., "0.5" for 0.5 ETH)
1098
- // // * @param options - Optional security and priority settings
1099
- // // * @returns Transaction result
1100
- // // *
1101
- // // * @example
1102
- // // * const result = await wallet.withdrawFromSavings(1, destinationAddress, "0.5");
1103
- // // */
1104
- // // async withdrawFromSavings(
1105
- // // accountIndex: number,
1106
- // // to: string,
1107
- // // amount: string,
1108
- // // options?: WithdrawFromSavingsOptions
1109
- // // ): Promise<TransactionResult> {
1110
- // // const manager = this.getSavingsManager();
1111
-
1112
- // // // Build withdrawal transaction
1113
- // // const amountWei = parseEther(amount);
1114
- // // const withdrawalParams = manager.buildWithdrawalTransaction(
1115
- // // accountIndex,
1116
- // // to as Hex,
1117
- // // amountWei,
1118
- // // options
1119
- // // );
1120
-
1121
- // // // Create a temporary wallet with the savings account private key
1122
- // // const savingsWallet = new Wallet(withdrawalParams.privateKey, this.connection);
1123
-
1124
- // // // Send transaction using the savings wallet
1125
- // // const tx = await savingsWallet.sendTransaction({
1126
- // // to: withdrawalParams.to,
1127
- // // value: withdrawalParams.value
1128
- // // });
1129
-
1130
- // // const receipt = await tx.wait(this.config.confirmationNo || 1);
1131
-
1132
- // // return {
1133
- // // success: receipt?.status === 1,
1134
- // // hash: receipt?.hash || tx.hash
1135
- // // };
1136
- // // }
1137
-
1138
- // /**
1139
- // * Verify a stored savings address matches the derived address
1140
- // *
1141
- // * Security: Prevents database tampering attacks.
1142
- // *
1143
- // * @param accountIndex - The account index to verify
1144
- // * @param storedAddress - The address from storage/database
1145
- // * @returns Verification result
1146
- // *
1147
- // * @example
1148
- // * const result = wallet.verifySavingsAddress(1, storedAddress);
1149
- // * if (!result.isValid) {
1150
- // * console.error("Security alert: Address tampering detected!");
1151
- // * }
1152
- // */
1153
- // verifySavingsAddress(accountIndex: number, storedAddress: Hex): AddressVerificationResult {
1154
- // return this.getSavingsManager().verifySavingsAddress(accountIndex, storedAddress);
1155
- // }
1156
-
1157
- // /**
1158
- // * Audit multiple savings addresses at once
1159
- // *
1160
- // * @param addresses - Map of accountIndex to stored address
1161
- // * @returns Audit result with summary and details
1162
- // *
1163
- // * @example
1164
- // * const addresses = new Map([[1, "0xabc..."], [2, "0xdef..."]]);
1165
- // * const audit = wallet.auditSavingsAddresses(addresses);
1166
- // * console.log(`Valid: ${audit.valid}/${audit.total}`);
1167
- // */
1168
- // auditSavingsAddresses(addresses: Map<number, Hex>): SavingsAuditResult {
1169
- // return this.getSavingsManager().auditSavingsAddresses(addresses);
1170
- // }
1171
-
1172
- // /**
1173
- // * Get savings account information without exposing private key
1174
- // *
1175
- // * @param accountIndex - The account index
1176
- // * @returns Public account information (address and derivation path)
1177
- // *
1178
- // * @example
1179
- // * const info = wallet.getSavingsAccountInfo(1);
1180
- // * console.log(`Address: ${info.address}`);
1181
- // * console.log(`Path: ${info.derivationPath}`); // m/44'/60'/1'/0/0
1182
- // */
1183
- // getSavingsAccountInfo(accountIndex: number): Omit<SavingsAccount, 'privateKey'> {
1184
- // return this.getSavingsManager().getSavingsAccountInfo(accountIndex);
1185
- // }
1186
-
1187
- // // ============================================
1188
- // // Smart Savings Methods (EIP-7702)
1189
- // // ============================================
1190
-
1191
- // /**
1192
- // * Get or create the SmartSavingsManager instance (lazy initialization)
1193
- // * @private
1194
- // */
1195
- // private getSmartSavingsManager(): SmartSavingsManager {
1196
- // if (!this.smartSavingsManager) {
1197
- // this.smartSavingsManager = new SmartSavingsManager(this.config);
1198
- // }
1199
- // return this.smartSavingsManager;
1200
- // }
1201
-
1202
- // /**
1203
- // * Upgrade a savings account to a smart account with EIP-7702 delegation
1204
- // *
1205
- // * This enables advanced features:
1206
- // * - Lock modules for time-locked savings
1207
- // * - Hooks for spend & save
1208
- // * - Session keys for periodic savings
1209
- // * - Sponsored transactions via paymaster
1210
- // *
1211
- // * @param accountIndex - The savings account index to upgrade
1212
- // * @param options - Optional smart wallet configuration
1213
- // * @param autoInitialize - Whether to initialize the smart wallet (default: false)
1214
- // * @returns SmartSavingsAccount with EVMSmartWallet instance
1215
- // *
1216
- // * @example
1217
- // * // Upgrade without initialization
1218
- // * const smartSavings = await wallet.upgradeSavingsToSmartAccount(1);
1219
- // * await smartSavings.smartWallet.initialize(); // Initialize separately
1220
- // *
1221
- // * @example
1222
- // * // Upgrade and initialize in one step
1223
- // * const smartSavings = await wallet.upgradeSavingsToSmartAccount(1, {}, true);
1224
- // * // Ready to use immediately
1225
- // */
1226
- // async upgradeSavingsToSmartAccount(
1227
- // accountIndex: number,
1228
- // options?: SmartWalletOptions,
1229
- // autoInitialize: boolean = false
1230
- // ): Promise<SmartSavingsAccount> {
1231
- // const manager = this.getSmartSavingsManager();
1232
-
1233
- // // First derive the basic savings account
1234
- // const basicSavings = this.deriveSavingsAccount(accountIndex);
1235
-
1236
- // // Then upgrade to smart account
1237
- // if (autoInitialize) {
1238
- // return await manager.upgradeSavingsAndInitialize(basicSavings, options);
1239
- // } else {
1240
- // return await manager.upgradeSavingsToSmartAccount(basicSavings, options);
1241
- // }
1242
- // }
1243
-
1244
- // /**
1245
- // * Check if smart savings is supported on this chain
1246
- // *
1247
- // * @returns true if chain supports Account Abstraction
1248
- // *
1249
- // * @example
1250
- // * if (wallet.isSmartSavingsSupported()) {
1251
- // * const smartSavings = await wallet.upgradeSavingsToSmartAccount(1);
1252
- // * } else {
1253
- // * console.log("This chain doesn't support smart savings");
1254
- // * }
1255
- // */
1256
- // isSmartSavingsSupported(): boolean {
1257
- // try {
1258
- // const manager = this.getSmartSavingsManager();
1259
- // return manager.canUpgradeToSmartAccount();
1260
- // } catch (error) {
1261
- // return false;
1262
- // }
1263
- // }
1264
1345
  }
1265
-