@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.
- package/dist/IChainWallet.d.ts +1 -0
- package/dist/IChainWallet.js.map +1 -1
- package/dist/evm/evm.d.ts +12 -174
- package/dist/evm/evm.js +33 -506
- package/dist/evm/evm.js.map +1 -1
- package/dist/evm/transaction.utils.d.ts +3 -3
- package/dist/evm/utils.d.ts +115 -80
- package/dist/evm/utils.js +272 -497
- package/dist/evm/utils.js.map +1 -1
- package/dist/helpers/index.d.ts +1 -0
- package/dist/helpers/index.js +5 -0
- package/dist/helpers/index.js.map +1 -1
- package/dist/savings/index.d.ts +0 -0
- package/dist/savings/index.js +3 -0
- package/dist/savings/index.js.map +1 -0
- package/dist/savings/saving-actions.d.ts +0 -0
- package/dist/savings/saving-actions.js +78 -0
- package/dist/savings/saving-actions.js.map +1 -0
- package/dist/savings/savings-manager.d.ts +1 -1
- package/dist/savings/savings-manager.js +3 -3
- package/dist/savings/savings-manager.js.map +1 -1
- package/dist/svm/svm.d.ts +2 -0
- package/dist/svm/svm.js +6 -0
- package/dist/svm/svm.js.map +1 -1
- package/dist/test.js +7 -7
- package/dist/test.js.map +1 -1
- package/dist/utils.d.ts +2 -1
- package/dist/utils.js +20 -0
- package/dist/utils.js.map +1 -1
- package/dist/vm.js.map +1 -1
- package/package.json +1 -1
- package/utils/IChainWallet.ts +2 -0
- package/utils/evm/evm.ts +321 -683
- package/utils/evm/utils.ts +438 -662
- package/utils/helpers/index.ts +6 -0
- package/utils/savings/index.ts +1 -0
- package/utils/savings/saving-actions.ts +92 -0
- package/utils/savings/savings-manager.ts +1 -1
- package/utils/svm/svm.ts +8 -0
- package/utils/test.ts +11 -3
- package/utils/utils.ts +19 -2
- 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 =
|
|
98
|
-
|
|
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
|
|
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(),
|
|
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(),
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
585
|
-
|
|
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;
|