@sidhujag/sysweb3-keyring 1.0.597 → 1.0.599
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/cjs/ethers-v6.js +224 -0
- package/cjs/ethers-v6.js.map +1 -0
- package/cjs/keyring-manager.js +12 -15
- package/cjs/keyring-manager.js.map +1 -1
- package/cjs/providers.js +159 -41
- package/cjs/providers.js.map +1 -1
- package/cjs/transactions/ethereum.js +184 -170
- package/cjs/transactions/ethereum.js.map +1 -1
- package/cjs/transactions/evm-local-signer.js +202 -0
- package/cjs/transactions/evm-local-signer.js.map +1 -0
- package/cjs/trezor/index.js +2 -2
- package/cjs/trezor/index.js.map +1 -1
- package/cjs/types.js.map +1 -1
- package/cjs/utils.js +30 -12
- package/cjs/utils.js.map +1 -1
- package/package.json +8 -17
- package/types/ethers-v6.d.ts +66 -0
- package/types/keyring-manager.d.ts +2 -3
- package/types/providers.d.ts +12 -3
- package/types/transactions/ethereum.d.ts +5 -7
- package/types/transactions/evm-local-signer.d.ts +24 -0
- package/types/types.d.ts +11 -6
|
@@ -4,21 +4,31 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.EthereumTransactions = void 0;
|
|
7
|
-
const bignumber_1 = require("@ethersproject/bignumber");
|
|
8
|
-
const bytes_1 = require("@ethersproject/bytes");
|
|
9
|
-
const constants_1 = require("@ethersproject/constants");
|
|
10
|
-
const contracts_1 = require("@ethersproject/contracts");
|
|
11
|
-
const properties_1 = require("@ethersproject/properties");
|
|
12
|
-
const transactions_1 = require("@ethersproject/transactions");
|
|
13
|
-
const units_1 = require("@ethersproject/units");
|
|
14
|
-
const wallet_1 = require("@ethersproject/wallet");
|
|
15
7
|
const eth_sig_util_1 = require("@metamask/eth-sig-util");
|
|
16
8
|
const sysweb3_network_1 = require("@sidhujag/sysweb3-network");
|
|
17
9
|
const sysweb3_utils_1 = require("@sidhujag/sysweb3-utils");
|
|
18
|
-
const ethereumjs_util_1 = require("ethereumjs-util");
|
|
19
10
|
const omit_1 = __importDefault(require("lodash/omit"));
|
|
11
|
+
const ethers_v6_1 = require("../ethers-v6");
|
|
20
12
|
const providers_1 = require("../providers");
|
|
21
13
|
const types_1 = require("../types");
|
|
14
|
+
const evm_local_signer_1 = require("./evm-local-signer");
|
|
15
|
+
const derivation_paths_1 = require("../utils/derivation-paths");
|
|
16
|
+
const stripHexPrefix = (value) => value.startsWith('0x') || value.startsWith('0X') ? value.slice(2) : value;
|
|
17
|
+
const normalizeEthersOverrideValue = (value) => ethers_v6_1.BigNumber.isBigNumber(value) ? ethers_v6_1.BigNumber.from(value).toBigInt() : value;
|
|
18
|
+
const normalizeEthersOverrides = (overrides) => {
|
|
19
|
+
const normalized = { ...overrides };
|
|
20
|
+
for (const field of [
|
|
21
|
+
'gasLimit',
|
|
22
|
+
'gasPrice',
|
|
23
|
+
'maxFeePerGas',
|
|
24
|
+
'maxPriorityFeePerGas',
|
|
25
|
+
]) {
|
|
26
|
+
if (normalized[field] != null) {
|
|
27
|
+
normalized[field] = normalizeEthersOverrideValue(normalized[field]);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return normalized;
|
|
31
|
+
};
|
|
22
32
|
class EthereumTransactions {
|
|
23
33
|
constructor(getNetwork, getDecryptedPrivateKey, getState, ledgerSigner, trezorSigner) {
|
|
24
34
|
// Allow manual override of gas parameters when automatic estimation fails
|
|
@@ -38,7 +48,7 @@ class EthereumTransactions {
|
|
|
38
48
|
throw {
|
|
39
49
|
message: 'Decrypting for wrong address, change activeAccount maybe',
|
|
40
50
|
};
|
|
41
|
-
const privKey = Buffer.from(
|
|
51
|
+
const privKey = Buffer.from(stripHexPrefix(decryptedPrivateKey), 'hex');
|
|
42
52
|
return (0, eth_sig_util_1.signTypedData)({
|
|
43
53
|
privateKey: privKey,
|
|
44
54
|
data: typedData,
|
|
@@ -111,17 +121,16 @@ class EthereumTransactions {
|
|
|
111
121
|
let msg = '';
|
|
112
122
|
//Comparisions do not need to care for checksum address
|
|
113
123
|
if (params[0].toLowerCase() === address.toLowerCase()) {
|
|
114
|
-
msg =
|
|
124
|
+
msg = stripHexPrefix(params[1]);
|
|
115
125
|
}
|
|
116
126
|
else if (params[1].toLowerCase() === address.toLowerCase()) {
|
|
117
|
-
msg =
|
|
127
|
+
msg = stripHexPrefix(params[0]);
|
|
118
128
|
}
|
|
119
129
|
else {
|
|
120
130
|
throw new Error('Signing for wrong address');
|
|
121
131
|
}
|
|
122
132
|
const sign = () => {
|
|
123
133
|
try {
|
|
124
|
-
const bufPriv = (0, ethereumjs_util_1.toBuffer)(decryptedPrivateKey);
|
|
125
134
|
// Validate and prepare the message for eth_sign
|
|
126
135
|
let msgHash;
|
|
127
136
|
// Check if message is a valid 32-byte hex string
|
|
@@ -135,9 +144,7 @@ class EthereumTransactions {
|
|
|
135
144
|
`Got message of length ${msg.length}: "${msg.substring(0, 50)}${msg.length > 50 ? '...' : ''}". ` +
|
|
136
145
|
`For signing arbitrary text, use personal_sign instead of eth_sign.`);
|
|
137
146
|
}
|
|
138
|
-
|
|
139
|
-
const resp = (0, eth_sig_util_1.concatSig)((0, ethereumjs_util_1.toBuffer)(sig.v), sig.r, sig.s);
|
|
140
|
-
return resp;
|
|
147
|
+
return (0, evm_local_signer_1.signDigestHex)(msgHash, decryptedPrivateKey);
|
|
141
148
|
}
|
|
142
149
|
catch (error) {
|
|
143
150
|
throw error;
|
|
@@ -203,16 +210,16 @@ class EthereumTransactions {
|
|
|
203
210
|
}
|
|
204
211
|
const signPersonalMessageWithDefaultWallet = () => {
|
|
205
212
|
try {
|
|
206
|
-
const privateKey = (0, ethereumjs_util_1.toBuffer)(decryptedPrivateKey);
|
|
207
213
|
// Handle both hex-encoded and plain text messages for personal_sign
|
|
208
214
|
let message;
|
|
209
215
|
if (msg.startsWith('0x')) {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
216
|
+
const rawHex = stripHexPrefix(msg);
|
|
217
|
+
if (rawHex.length % 2 === 0 && (0, ethers_v6_1.isHexString)(msg)) {
|
|
218
|
+
// Message is valid hex-encoded bytes.
|
|
219
|
+
message = Buffer.from(rawHex, 'hex');
|
|
213
220
|
}
|
|
214
|
-
|
|
215
|
-
//
|
|
221
|
+
else {
|
|
222
|
+
// Malformed 0x-prefixed strings are literal text, not lossy hex.
|
|
216
223
|
message = Buffer.from(msg, 'utf8');
|
|
217
224
|
}
|
|
218
225
|
}
|
|
@@ -220,10 +227,7 @@ class EthereumTransactions {
|
|
|
220
227
|
// Message is plain text
|
|
221
228
|
message = Buffer.from(msg, 'utf8');
|
|
222
229
|
}
|
|
223
|
-
|
|
224
|
-
const sig = (0, ethereumjs_util_1.ecsign)(msgHash, privateKey);
|
|
225
|
-
const serialized = (0, eth_sig_util_1.concatSig)((0, ethereumjs_util_1.toBuffer)(sig.v), sig.r, sig.s);
|
|
226
|
-
return serialized;
|
|
230
|
+
return (0, evm_local_signer_1.signPersonalMessage)(message, decryptedPrivateKey);
|
|
227
231
|
}
|
|
228
232
|
catch (error) {
|
|
229
233
|
throw error;
|
|
@@ -289,7 +293,7 @@ class EthereumTransactions {
|
|
|
289
293
|
};
|
|
290
294
|
this.parsePersonalMessage = (hexMsg) => {
|
|
291
295
|
try {
|
|
292
|
-
return (0,
|
|
296
|
+
return (0, evm_local_signer_1.parsePersonalMessage)(hexMsg);
|
|
293
297
|
}
|
|
294
298
|
catch (error) {
|
|
295
299
|
throw error;
|
|
@@ -316,7 +320,7 @@ class EthereumTransactions {
|
|
|
316
320
|
}
|
|
317
321
|
const { decryptedPrivateKey } = this.getDecryptedPrivateKey();
|
|
318
322
|
try {
|
|
319
|
-
return (0, eth_sig_util_1.getEncryptionPublicKey)(
|
|
323
|
+
return (0, eth_sig_util_1.getEncryptionPublicKey)(stripHexPrefix(decryptedPrivateKey));
|
|
320
324
|
}
|
|
321
325
|
catch (error) {
|
|
322
326
|
throw error;
|
|
@@ -341,13 +345,13 @@ class EthereumTransactions {
|
|
|
341
345
|
else {
|
|
342
346
|
throw new Error('Decrypting for wrong receiver');
|
|
343
347
|
}
|
|
344
|
-
encryptedData =
|
|
348
|
+
encryptedData = stripHexPrefix(encryptedData);
|
|
345
349
|
try {
|
|
346
350
|
const buff = Buffer.from(encryptedData, 'hex');
|
|
347
351
|
const cleanData = JSON.parse(buff.toString('utf8'));
|
|
348
352
|
const sig = (0, eth_sig_util_1.decrypt)({
|
|
349
353
|
encryptedData: cleanData,
|
|
350
|
-
privateKey:
|
|
354
|
+
privateKey: stripHexPrefix(decryptedPrivateKey),
|
|
351
355
|
});
|
|
352
356
|
return sig;
|
|
353
357
|
}
|
|
@@ -355,7 +359,7 @@ class EthereumTransactions {
|
|
|
355
359
|
throw error;
|
|
356
360
|
}
|
|
357
361
|
};
|
|
358
|
-
this.toBigNumber = (aBigNumberish) =>
|
|
362
|
+
this.toBigNumber = (aBigNumberish) => ethers_v6_1.BigNumber.from(String(aBigNumberish));
|
|
359
363
|
this.toHex0x = (value, fieldName) => {
|
|
360
364
|
if (value === undefined || value === null)
|
|
361
365
|
return '0x0';
|
|
@@ -365,15 +369,15 @@ class EthereumTransactions {
|
|
|
365
369
|
return '0x0';
|
|
366
370
|
if (v.startsWith('0x'))
|
|
367
371
|
return v;
|
|
368
|
-
return
|
|
372
|
+
return ethers_v6_1.BigNumber.from(v).toHexString();
|
|
369
373
|
}
|
|
370
374
|
if (typeof value === 'number')
|
|
371
|
-
return
|
|
372
|
-
if (
|
|
375
|
+
return ethers_v6_1.BigNumber.from(value).toHexString();
|
|
376
|
+
if (ethers_v6_1.BigNumber.isBigNumber(value))
|
|
373
377
|
return value.toHexString();
|
|
374
378
|
const maybeHex = value?._hex ?? value?.hex ?? value;
|
|
375
379
|
try {
|
|
376
|
-
return
|
|
380
|
+
return ethers_v6_1.BigNumber.from(maybeHex).toHexString();
|
|
377
381
|
}
|
|
378
382
|
catch (_e) {
|
|
379
383
|
throw new Error(`Invalid numeric field "${fieldName}" for EVM tx: ${String(value)}`);
|
|
@@ -383,9 +387,10 @@ class EthereumTransactions {
|
|
|
383
387
|
const abi = (0, sysweb3_utils_1.getErc20Abi)();
|
|
384
388
|
try {
|
|
385
389
|
const contract = (0, sysweb3_utils_1.createContractUsingAbi)(abi, contractAddress, this.web3Provider);
|
|
386
|
-
const data = contract.
|
|
387
|
-
|
|
388
|
-
|
|
390
|
+
const data = contract.interface.encodeFunctionData('transfer', [
|
|
391
|
+
receivingAddress,
|
|
392
|
+
value,
|
|
393
|
+
]);
|
|
389
394
|
return data;
|
|
390
395
|
}
|
|
391
396
|
catch (error) {
|
|
@@ -399,11 +404,12 @@ class EthereumTransactions {
|
|
|
399
404
|
// First, try to get the current gas price as a baseline
|
|
400
405
|
const currentGasPrice = await this.web3Provider.getGasPrice();
|
|
401
406
|
const block = await this.web3Provider.getBlock('latest');
|
|
402
|
-
if (block && block.baseFeePerGas) {
|
|
407
|
+
if (block && block.baseFeePerGas != null) {
|
|
408
|
+
const baseFeePerGas = ethers_v6_1.BigNumber.from(block.baseFeePerGas);
|
|
403
409
|
try {
|
|
404
410
|
// Some networks don't support this RPC method
|
|
405
411
|
const ethMaxPriorityFee = await this.web3Provider.send('eth_maxPriorityFeePerGas', []);
|
|
406
|
-
maxPriorityFeePerGas =
|
|
412
|
+
maxPriorityFeePerGas = ethers_v6_1.BigNumber.from(ethMaxPriorityFee);
|
|
407
413
|
// Apply minimum priority fee override if set
|
|
408
414
|
if (this.gasOverrides.minPriorityFee &&
|
|
409
415
|
maxPriorityFeePerGas.lt(this.gasOverrides.minPriorityFee)) {
|
|
@@ -417,7 +423,7 @@ class EthereumTransactions {
|
|
|
417
423
|
const baselineMaxFee = currentGasPrice.mul(120).div(100); // 20% above current gas price
|
|
418
424
|
// Calculate standard maxFeePerGas
|
|
419
425
|
const multiplier = this.gasOverrides.feeMultiplier || 250;
|
|
420
|
-
const calculatedMaxFee =
|
|
426
|
+
const calculatedMaxFee = baseFeePerGas
|
|
421
427
|
.mul(multiplier)
|
|
422
428
|
.div(100)
|
|
423
429
|
.add(maxPriorityFeePerGas);
|
|
@@ -442,7 +448,7 @@ class EthereumTransactions {
|
|
|
442
448
|
const recentFees = feeHistory.reward
|
|
443
449
|
.map((r) => r[1]) // Get 50th percentile
|
|
444
450
|
.filter((f) => f && f !== '0x0')
|
|
445
|
-
.map((f) =>
|
|
451
|
+
.map((f) => ethers_v6_1.BigNumber.from(f));
|
|
446
452
|
if (recentFees.length > 0) {
|
|
447
453
|
// Use the median value with a 50% buffer for better reliability
|
|
448
454
|
const sortedFees = recentFees.sort((a, b) => a.sub(b).isNegative() ? -1 : 1);
|
|
@@ -451,12 +457,12 @@ class EthereumTransactions {
|
|
|
451
457
|
}
|
|
452
458
|
else {
|
|
453
459
|
// Fallback with higher default (5 gwei for better validation)
|
|
454
|
-
maxPriorityFeePerGas =
|
|
460
|
+
maxPriorityFeePerGas = ethers_v6_1.BigNumber.from('5000000000');
|
|
455
461
|
}
|
|
456
462
|
}
|
|
457
463
|
else {
|
|
458
464
|
// Fallback with higher default (5 gwei for better validation)
|
|
459
|
-
maxPriorityFeePerGas =
|
|
465
|
+
maxPriorityFeePerGas = ethers_v6_1.BigNumber.from('5000000000');
|
|
460
466
|
}
|
|
461
467
|
}
|
|
462
468
|
catch (feeHistoryError) {
|
|
@@ -466,7 +472,7 @@ class EthereumTransactions {
|
|
|
466
472
|
const currentGasPrice = await this.web3Provider.getGasPrice();
|
|
467
473
|
maxPriorityFeePerGas = currentGasPrice.mul(10).div(100);
|
|
468
474
|
// Ensure minimum of 1 gwei
|
|
469
|
-
const minPriority =
|
|
475
|
+
const minPriority = ethers_v6_1.BigNumber.from('1000000000');
|
|
470
476
|
if (maxPriorityFeePerGas.lt(minPriority)) {
|
|
471
477
|
maxPriorityFeePerGas = minPriority;
|
|
472
478
|
}
|
|
@@ -474,7 +480,7 @@ class EthereumTransactions {
|
|
|
474
480
|
// Calculate maxFeePerGas based on current network conditions
|
|
475
481
|
const currentGasPrice = await this.web3Provider.getGasPrice();
|
|
476
482
|
const baselineMaxFee = currentGasPrice.mul(120).div(100);
|
|
477
|
-
const calculatedMaxFee =
|
|
483
|
+
const calculatedMaxFee = baseFeePerGas
|
|
478
484
|
.mul(250)
|
|
479
485
|
.div(100)
|
|
480
486
|
.add(maxPriorityFeePerGas);
|
|
@@ -489,12 +495,12 @@ class EthereumTransactions {
|
|
|
489
495
|
}
|
|
490
496
|
return { maxFeePerGas, maxPriorityFeePerGas };
|
|
491
497
|
}
|
|
492
|
-
else if (block &&
|
|
498
|
+
else if (block && block.baseFeePerGas == null) {
|
|
493
499
|
// For non-EIP1559 chains, return zeros to indicate legacy transaction should be used
|
|
494
500
|
console.log('Chain does not support EIP1559, use legacy transactions');
|
|
495
501
|
return {
|
|
496
|
-
maxFeePerGas:
|
|
497
|
-
maxPriorityFeePerGas:
|
|
502
|
+
maxFeePerGas: ethers_v6_1.BigNumber.from(0),
|
|
503
|
+
maxPriorityFeePerGas: ethers_v6_1.BigNumber.from(0),
|
|
498
504
|
};
|
|
499
505
|
}
|
|
500
506
|
else if (!block)
|
|
@@ -519,7 +525,7 @@ class EthereumTransactions {
|
|
|
519
525
|
const newValue = feeValue * multiplierToUse;
|
|
520
526
|
const calculateValue = String(newValue);
|
|
521
527
|
const convertValueToHex = '0x' + parseInt(calculateValue, 10).toString(16);
|
|
522
|
-
return
|
|
528
|
+
return ethers_v6_1.BigNumber.from(convertValueToHex);
|
|
523
529
|
};
|
|
524
530
|
const maxFeePerGasToNumber = maxFeePerGas?.toNumber();
|
|
525
531
|
const maxPriorityFeePerGasToNumber = maxPriorityFeePerGas?.toNumber();
|
|
@@ -537,7 +543,7 @@ class EthereumTransactions {
|
|
|
537
543
|
if (isForCancel) {
|
|
538
544
|
const DEFAULT_GAS_LIMIT_VALUE = '42000';
|
|
539
545
|
const convertToHex = '0x' + parseInt(DEFAULT_GAS_LIMIT_VALUE, 10).toString(16);
|
|
540
|
-
newGasValues.gasLimit =
|
|
546
|
+
newGasValues.gasLimit = ethers_v6_1.BigNumber.from(convertToHex);
|
|
541
547
|
}
|
|
542
548
|
if (!isForCancel) {
|
|
543
549
|
newGasValues.gasLimit = calculateAndConvertNewValue(gasLimitToNumber);
|
|
@@ -557,10 +563,10 @@ class EthereumTransactions {
|
|
|
557
563
|
tx = {
|
|
558
564
|
from: activeAccount.address,
|
|
559
565
|
to: activeAccount.address,
|
|
560
|
-
value:
|
|
566
|
+
value: ethers_v6_1.Zero,
|
|
561
567
|
nonce: fallbackNonce,
|
|
562
568
|
gasPrice: currentGasPrice,
|
|
563
|
-
gasLimit:
|
|
569
|
+
gasLimit: ethers_v6_1.BigNumber.from(42000),
|
|
564
570
|
data: '0x',
|
|
565
571
|
};
|
|
566
572
|
}
|
|
@@ -569,11 +575,11 @@ class EthereumTransactions {
|
|
|
569
575
|
tx = {
|
|
570
576
|
from: activeAccount.address,
|
|
571
577
|
to: activeAccount.address,
|
|
572
|
-
value:
|
|
578
|
+
value: ethers_v6_1.Zero,
|
|
573
579
|
nonce: fallbackNonce,
|
|
574
|
-
maxFeePerGas:
|
|
575
|
-
maxPriorityFeePerGas:
|
|
576
|
-
gasLimit:
|
|
580
|
+
maxFeePerGas: ethers_v6_1.BigNumber.from(feeData.maxFeePerGas || 0),
|
|
581
|
+
maxPriorityFeePerGas: ethers_v6_1.BigNumber.from(feeData.maxPriorityFeePerGas || 0),
|
|
582
|
+
gasLimit: ethers_v6_1.BigNumber.from(42000),
|
|
577
583
|
data: '0x',
|
|
578
584
|
};
|
|
579
585
|
}
|
|
@@ -607,8 +613,8 @@ class EthereumTransactions {
|
|
|
607
613
|
oldTxsGasValues.maxFeePerGas.isZero()) {
|
|
608
614
|
// Fetch current network fee data for replacement
|
|
609
615
|
const feeData = await this.getFeeDataWithDynamicMaxPriorityFeePerGas();
|
|
610
|
-
oldTxsGasValues.maxFeePerGas =
|
|
611
|
-
oldTxsGasValues.maxPriorityFeePerGas =
|
|
616
|
+
oldTxsGasValues.maxFeePerGas = ethers_v6_1.BigNumber.from(feeData.maxFeePerGas || 0);
|
|
617
|
+
oldTxsGasValues.maxPriorityFeePerGas = ethers_v6_1.BigNumber.from(feeData.maxPriorityFeePerGas || 0);
|
|
612
618
|
}
|
|
613
619
|
}
|
|
614
620
|
const newGasValues = this.calculateNewGasValues(oldTxsGasValues, true, isLegacy || false);
|
|
@@ -617,7 +623,7 @@ class EthereumTransactions {
|
|
|
617
623
|
nonce: tx.nonce,
|
|
618
624
|
from: activeAccount.address,
|
|
619
625
|
to: activeAccount.address,
|
|
620
|
-
value:
|
|
626
|
+
value: ethers_v6_1.Zero,
|
|
621
627
|
gasLimit: newGasValues.gasLimit,
|
|
622
628
|
};
|
|
623
629
|
const changedTxToCancel = isLegacy
|
|
@@ -635,7 +641,7 @@ class EthereumTransactions {
|
|
|
635
641
|
// Ledger cancel handler
|
|
636
642
|
const cancelWithLedger = async () => {
|
|
637
643
|
try {
|
|
638
|
-
const resolvedParams = await (0,
|
|
644
|
+
const resolvedParams = await (0, ethers_v6_1.resolveProperties)((0, omit_1.default)(changedTxToCancel, 'from'));
|
|
639
645
|
const formatParams = {
|
|
640
646
|
...resolvedParams,
|
|
641
647
|
nonce: resolvedParams.nonce
|
|
@@ -653,7 +659,7 @@ class EthereumTransactions {
|
|
|
653
659
|
chainId: activeNetwork.chainId,
|
|
654
660
|
type: 2, // Need explicit type for hardware wallet serialization
|
|
655
661
|
};
|
|
656
|
-
const rawTx = (0,
|
|
662
|
+
const rawTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers);
|
|
657
663
|
const signature = await this.ledgerSigner.evm.signEVMTransaction({
|
|
658
664
|
rawTx: rawTx.replace('0x', ''),
|
|
659
665
|
accountIndex: activeAccountId,
|
|
@@ -664,7 +670,7 @@ class EthereumTransactions {
|
|
|
664
670
|
v: parseInt(signature.v, 16),
|
|
665
671
|
};
|
|
666
672
|
if (signature) {
|
|
667
|
-
const signedTx = (0,
|
|
673
|
+
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, formattedSignature);
|
|
668
674
|
const transactionResponse = await this.web3Provider.sendTransaction(signedTx);
|
|
669
675
|
return {
|
|
670
676
|
isCanceled: true,
|
|
@@ -689,7 +695,7 @@ class EthereumTransactions {
|
|
|
689
695
|
const cancelWithTrezor = async () => {
|
|
690
696
|
try {
|
|
691
697
|
const trezorCoin = activeNetwork.slip44 === 60 ? 'eth' : activeNetwork.currency;
|
|
692
|
-
const formattedTx = await (0,
|
|
698
|
+
const formattedTx = await (0, ethers_v6_1.resolveProperties)((0, omit_1.default)(changedTxToCancel, 'from'));
|
|
693
699
|
const txFormattedForTrezor = {
|
|
694
700
|
...formattedTx,
|
|
695
701
|
gasLimit: typeof formattedTx.gasLimit === 'string'
|
|
@@ -723,7 +729,7 @@ class EthereumTransactions {
|
|
|
723
729
|
slip44: activeNetwork.slip44,
|
|
724
730
|
});
|
|
725
731
|
if (signature.success) {
|
|
726
|
-
const signedTx = (0,
|
|
732
|
+
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForTrezor, signature.payload);
|
|
727
733
|
const transactionResponse = await this.web3Provider.sendTransaction(signedTx);
|
|
728
734
|
return {
|
|
729
735
|
isCanceled: true,
|
|
@@ -748,8 +754,7 @@ class EthereumTransactions {
|
|
|
748
754
|
const cancelWithPrivateKey = async () => {
|
|
749
755
|
try {
|
|
750
756
|
const { decryptedPrivateKey } = this.getDecryptedPrivateKey();
|
|
751
|
-
const
|
|
752
|
-
const transactionResponse = await wallet.sendTransaction(changedTxToCancel);
|
|
757
|
+
const transactionResponse = await (0, evm_local_signer_1.sendLocalEvmTransaction)(this.web3Provider, decryptedPrivateKey, changedTxToCancel);
|
|
753
758
|
if (transactionResponse) {
|
|
754
759
|
return {
|
|
755
760
|
isCanceled: true,
|
|
@@ -786,8 +791,8 @@ class EthereumTransactions {
|
|
|
786
791
|
// Check if we should force legacy transactions for networks with EIP-1559 issues
|
|
787
792
|
// Some networks have issues with EIP-1559 validation
|
|
788
793
|
if (!isLegacy && params.maxFeePerGas && params.maxPriorityFeePerGas) {
|
|
789
|
-
const maxFee =
|
|
790
|
-
const priorityFee =
|
|
794
|
+
const maxFee = ethers_v6_1.BigNumber.from(params.maxFeePerGas);
|
|
795
|
+
const priorityFee = ethers_v6_1.BigNumber.from(params.maxPriorityFeePerGas);
|
|
791
796
|
// If fees are zero or network doesn't support EIP-1559, use legacy
|
|
792
797
|
if (maxFee.isZero() || priorityFee.isZero()) {
|
|
793
798
|
console.log('Switching to legacy transaction due to zero fees');
|
|
@@ -801,10 +806,11 @@ class EthereumTransactions {
|
|
|
801
806
|
delete params.maxPriorityFeePerGas;
|
|
802
807
|
}
|
|
803
808
|
}
|
|
804
|
-
//
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
const
|
|
809
|
+
// Only apply a minimum gas limit when a network-specific override is set.
|
|
810
|
+
// Otherwise keep the user/dapp-approved gas limit unchanged.
|
|
811
|
+
if (params.gasLimit && this.gasOverrides.minGasLimit) {
|
|
812
|
+
const minGasLimit = this.gasOverrides.minGasLimit;
|
|
813
|
+
const currentGasLimit = ethers_v6_1.BigNumber.from(params.gasLimit);
|
|
808
814
|
if (currentGasLimit.lt(minGasLimit)) {
|
|
809
815
|
params.gasLimit = minGasLimit;
|
|
810
816
|
}
|
|
@@ -827,7 +833,7 @@ class EthereumTransactions {
|
|
|
827
833
|
chainId: activeNetwork.chainId,
|
|
828
834
|
type: 2, // Need explicit type for hardware wallet serialization
|
|
829
835
|
};
|
|
830
|
-
const rawTx = (0,
|
|
836
|
+
const rawTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers);
|
|
831
837
|
const signature = await this.ledgerSigner.evm.signEVMTransaction({
|
|
832
838
|
rawTx: rawTx.replace('0x', ''),
|
|
833
839
|
accountIndex: activeAccountId,
|
|
@@ -839,7 +845,7 @@ class EthereumTransactions {
|
|
|
839
845
|
};
|
|
840
846
|
if (signature) {
|
|
841
847
|
try {
|
|
842
|
-
const signedTx = (0,
|
|
848
|
+
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, formattedSignature);
|
|
843
849
|
const finalTx = await this.web3Provider.sendTransaction(signedTx);
|
|
844
850
|
return finalTx;
|
|
845
851
|
}
|
|
@@ -919,7 +925,7 @@ class EthereumTransactions {
|
|
|
919
925
|
type: 2, // Need explicit type for hardware wallet serialization
|
|
920
926
|
};
|
|
921
927
|
signature.payload.v = parseInt(signature.payload.v, 16); //v parameter must be a number by ethers standards
|
|
922
|
-
const signedTx = (0,
|
|
928
|
+
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, signature.payload);
|
|
923
929
|
const finalTx = await this.web3Provider.sendTransaction(signedTx);
|
|
924
930
|
return finalTx;
|
|
925
931
|
}
|
|
@@ -943,9 +949,8 @@ class EthereumTransactions {
|
|
|
943
949
|
const tx = isLegacy
|
|
944
950
|
? { ...params, type: 0 } // Force Type 0 for legacy transactions
|
|
945
951
|
: (0, omit_1.default)(params, ['gasPrice']); // Strip gasPrice for EIP-1559
|
|
946
|
-
const wallet = new wallet_1.Wallet(decryptedPrivateKey, this.web3Provider);
|
|
947
952
|
try {
|
|
948
|
-
const transaction = await
|
|
953
|
+
const transaction = await (0, evm_local_signer_1.sendLocalEvmTransaction)(this.web3Provider, decryptedPrivateKey, tx);
|
|
949
954
|
const response = await this.web3Provider.getTransaction(transaction.hash);
|
|
950
955
|
//TODO: more precisely on this lines
|
|
951
956
|
if (!response) {
|
|
@@ -1028,8 +1033,8 @@ class EthereumTransactions {
|
|
|
1028
1033
|
oldTxsGasValues.maxFeePerGas.isZero()) {
|
|
1029
1034
|
// Fetch current network fee data for replacement
|
|
1030
1035
|
const feeData = await this.getFeeDataWithDynamicMaxPriorityFeePerGas();
|
|
1031
|
-
oldTxsGasValues.maxFeePerGas =
|
|
1032
|
-
oldTxsGasValues.maxPriorityFeePerGas =
|
|
1036
|
+
oldTxsGasValues.maxFeePerGas = ethers_v6_1.BigNumber.from(feeData.maxFeePerGas || 0);
|
|
1037
|
+
oldTxsGasValues.maxPriorityFeePerGas = ethers_v6_1.BigNumber.from(feeData.maxPriorityFeePerGas || 0);
|
|
1033
1038
|
}
|
|
1034
1039
|
}
|
|
1035
1040
|
if (!isLegacy) {
|
|
@@ -1055,7 +1060,7 @@ class EthereumTransactions {
|
|
|
1055
1060
|
// For non-contract calls, reduce value to fit within balance (clamp at zero)
|
|
1056
1061
|
adjustedValue = currentBalance.gt(newGasCost)
|
|
1057
1062
|
? currentBalance.sub(newGasCost)
|
|
1058
|
-
:
|
|
1063
|
+
: ethers_v6_1.Zero;
|
|
1059
1064
|
}
|
|
1060
1065
|
}
|
|
1061
1066
|
txWithEditedFee = {
|
|
@@ -1091,7 +1096,7 @@ class EthereumTransactions {
|
|
|
1091
1096
|
// For non-contract calls, reduce value to fit within balance (clamp at zero)
|
|
1092
1097
|
adjustedValue = currentBalance.gt(newGasCost)
|
|
1093
1098
|
? currentBalance.sub(newGasCost)
|
|
1094
|
-
:
|
|
1099
|
+
: ethers_v6_1.Zero;
|
|
1095
1100
|
}
|
|
1096
1101
|
}
|
|
1097
1102
|
txWithEditedFee = {
|
|
@@ -1108,7 +1113,7 @@ class EthereumTransactions {
|
|
|
1108
1113
|
// Ledger speedup handler
|
|
1109
1114
|
const speedUpWithLedger = async () => {
|
|
1110
1115
|
try {
|
|
1111
|
-
const resolvedParams = await (0,
|
|
1116
|
+
const resolvedParams = await (0, ethers_v6_1.resolveProperties)((0, omit_1.default)(txWithEditedFee, 'from'));
|
|
1112
1117
|
const formatParams = {
|
|
1113
1118
|
...resolvedParams,
|
|
1114
1119
|
nonce: resolvedParams.nonce
|
|
@@ -1126,7 +1131,7 @@ class EthereumTransactions {
|
|
|
1126
1131
|
chainId: activeNetwork.chainId,
|
|
1127
1132
|
type: 2, // Need explicit type for hardware wallet serialization
|
|
1128
1133
|
};
|
|
1129
|
-
const rawTx = (0,
|
|
1134
|
+
const rawTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers);
|
|
1130
1135
|
const signature = await this.ledgerSigner.evm.signEVMTransaction({
|
|
1131
1136
|
rawTx: rawTx.replace('0x', ''),
|
|
1132
1137
|
accountIndex: activeAccountId,
|
|
@@ -1137,7 +1142,7 @@ class EthereumTransactions {
|
|
|
1137
1142
|
v: parseInt(signature.v, 16),
|
|
1138
1143
|
};
|
|
1139
1144
|
if (signature) {
|
|
1140
|
-
const signedTx = (0,
|
|
1145
|
+
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, formattedSignature);
|
|
1141
1146
|
const transactionResponse = await this.web3Provider.sendTransaction(signedTx);
|
|
1142
1147
|
return {
|
|
1143
1148
|
isSpeedUp: true,
|
|
@@ -1173,7 +1178,7 @@ class EthereumTransactions {
|
|
|
1173
1178
|
const speedUpWithTrezor = async () => {
|
|
1174
1179
|
try {
|
|
1175
1180
|
const trezorCoin = activeNetwork.slip44 === 60 ? 'eth' : activeNetwork.currency;
|
|
1176
|
-
const formattedTx = await (0,
|
|
1181
|
+
const formattedTx = await (0, ethers_v6_1.resolveProperties)((0, omit_1.default)(txWithEditedFee, 'from'));
|
|
1177
1182
|
const txFormattedForTrezor = {
|
|
1178
1183
|
...formattedTx,
|
|
1179
1184
|
gasLimit: typeof formattedTx.gasLimit === 'string'
|
|
@@ -1212,7 +1217,7 @@ class EthereumTransactions {
|
|
|
1212
1217
|
slip44: activeNetwork.slip44,
|
|
1213
1218
|
});
|
|
1214
1219
|
if (signature.success) {
|
|
1215
|
-
const signedTx = (0,
|
|
1220
|
+
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForTrezor, signature.payload);
|
|
1216
1221
|
const transactionResponse = await this.web3Provider.sendTransaction(signedTx);
|
|
1217
1222
|
return {
|
|
1218
1223
|
isSpeedUp: true,
|
|
@@ -1248,9 +1253,7 @@ class EthereumTransactions {
|
|
|
1248
1253
|
const speedUpWithPrivateKey = async () => {
|
|
1249
1254
|
try {
|
|
1250
1255
|
const { decryptedPrivateKey } = this.getDecryptedPrivateKey();
|
|
1251
|
-
const
|
|
1252
|
-
// Type already set in txWithEditedFee
|
|
1253
|
-
const transactionResponse = await wallet.sendTransaction(txWithEditedFee);
|
|
1256
|
+
const transactionResponse = await (0, evm_local_signer_1.sendLocalEvmTransaction)(this.web3Provider, decryptedPrivateKey, txWithEditedFee);
|
|
1254
1257
|
if (transactionResponse) {
|
|
1255
1258
|
return {
|
|
1256
1259
|
isSpeedUp: true,
|
|
@@ -1298,45 +1301,47 @@ class EthereumTransactions {
|
|
|
1298
1301
|
const { accounts, activeAccountType, activeAccountId, activeNetwork } = this.getState();
|
|
1299
1302
|
const { address: activeAccountAddress } = accounts[activeAccountType][activeAccountId];
|
|
1300
1303
|
const sendERC20Token = async () => {
|
|
1301
|
-
const currentWallet = new wallet_1.Wallet(decryptedPrivateKey);
|
|
1302
|
-
const walletSigned = currentWallet.connect(this.web3Provider);
|
|
1303
1304
|
try {
|
|
1304
|
-
const _contract = new
|
|
1305
|
+
const _contract = new ethers_v6_1.Contract(tokenAddress, (0, sysweb3_utils_1.getErc20Abi)(), this.web3Provider);
|
|
1305
1306
|
// Preserve zero-decimal tokens: use provided decimals when defined (including 0).
|
|
1306
1307
|
const resolvedDecimals = decimals === undefined || decimals === null ? 18 : Number(decimals);
|
|
1307
|
-
const calculatedTokenAmount = (0,
|
|
1308
|
+
const calculatedTokenAmount = (0, ethers_v6_1.parseUnits)(tokenAmount, resolvedDecimals).toBigInt();
|
|
1308
1309
|
let transferMethod;
|
|
1309
1310
|
if (isLegacy) {
|
|
1310
1311
|
const overrides = {
|
|
1311
|
-
nonce: await this.web3Provider.getTransactionCount(
|
|
1312
|
+
nonce: await this.web3Provider.getTransactionCount(activeAccountAddress, 'pending'),
|
|
1312
1313
|
gasPrice,
|
|
1313
1314
|
...(gasLimit && { gasLimit }),
|
|
1314
1315
|
type: 0, // Explicitly set Type 0 for legacy token transfers
|
|
1315
1316
|
};
|
|
1316
|
-
transferMethod = await _contract.transfer(receiver, calculatedTokenAmount, overrides);
|
|
1317
|
+
transferMethod = await _contract.transfer.populateTransaction(receiver, calculatedTokenAmount, normalizeEthersOverrides(overrides));
|
|
1317
1318
|
}
|
|
1318
1319
|
else {
|
|
1319
1320
|
const overrides = {
|
|
1320
|
-
nonce: await this.web3Provider.getTransactionCount(
|
|
1321
|
+
nonce: await this.web3Provider.getTransactionCount(activeAccountAddress, 'pending'),
|
|
1321
1322
|
maxPriorityFeePerGas,
|
|
1322
1323
|
maxFeePerGas,
|
|
1323
1324
|
...(gasLimit && { gasLimit }),
|
|
1324
1325
|
};
|
|
1325
|
-
transferMethod = await _contract.transfer(receiver, calculatedTokenAmount, overrides);
|
|
1326
|
+
transferMethod = await _contract.transfer.populateTransaction(receiver, calculatedTokenAmount, normalizeEthersOverrides(overrides));
|
|
1326
1327
|
}
|
|
1327
|
-
return
|
|
1328
|
+
return await (0, evm_local_signer_1.sendLocalEvmTransaction)(this.web3Provider, decryptedPrivateKey, {
|
|
1329
|
+
...transferMethod,
|
|
1330
|
+
chainId: activeNetwork.chainId,
|
|
1331
|
+
from: activeAccountAddress,
|
|
1332
|
+
value: '0x0',
|
|
1333
|
+
});
|
|
1328
1334
|
}
|
|
1329
1335
|
catch (error) {
|
|
1330
1336
|
throw error;
|
|
1331
1337
|
}
|
|
1332
1338
|
};
|
|
1333
1339
|
const sendERC20TokenOnLedger = async () => {
|
|
1334
|
-
const signer = this.web3Provider.getSigner(activeAccountAddress);
|
|
1335
1340
|
const transactionNonce = await this.getRecommendedNonce(activeAccountAddress);
|
|
1336
1341
|
try {
|
|
1337
|
-
const _contract = new
|
|
1342
|
+
const _contract = new ethers_v6_1.Contract(tokenAddress, (0, sysweb3_utils_1.getErc20Abi)(), this.web3Provider);
|
|
1338
1343
|
const resolvedDecimals = decimals === undefined || decimals === null ? 18 : Number(decimals);
|
|
1339
|
-
const calculatedTokenAmount = (0,
|
|
1344
|
+
const calculatedTokenAmount = (0, ethers_v6_1.parseUnits)(tokenAmount, resolvedDecimals).toBigInt();
|
|
1340
1345
|
const txData = _contract.interface.encodeFunctionData('transfer', [
|
|
1341
1346
|
receiver,
|
|
1342
1347
|
calculatedTokenAmount,
|
|
@@ -1369,7 +1374,7 @@ class EthereumTransactions {
|
|
|
1369
1374
|
type: 2, // Need explicit type for hardware wallet serialization
|
|
1370
1375
|
};
|
|
1371
1376
|
}
|
|
1372
|
-
const rawTx = (0,
|
|
1377
|
+
const rawTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers);
|
|
1373
1378
|
const signature = await this.ledgerSigner.evm.signEVMTransaction({
|
|
1374
1379
|
rawTx: rawTx.replace('0x', ''),
|
|
1375
1380
|
accountIndex: activeAccountId,
|
|
@@ -1381,7 +1386,7 @@ class EthereumTransactions {
|
|
|
1381
1386
|
};
|
|
1382
1387
|
if (signature) {
|
|
1383
1388
|
try {
|
|
1384
|
-
const signedTx = (0,
|
|
1389
|
+
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, formattedSignature);
|
|
1385
1390
|
const finalTx = await this.web3Provider.sendTransaction(signedTx);
|
|
1386
1391
|
saveTrezorTx && saveTrezorTx(finalTx);
|
|
1387
1392
|
return finalTx;
|
|
@@ -1399,12 +1404,11 @@ class EthereumTransactions {
|
|
|
1399
1404
|
}
|
|
1400
1405
|
};
|
|
1401
1406
|
const sendERC20TokenOnTrezor = async () => {
|
|
1402
|
-
const signer = this.web3Provider.getSigner(activeAccountAddress);
|
|
1403
1407
|
const transactionNonce = await this.getRecommendedNonce(activeAccountAddress);
|
|
1404
1408
|
try {
|
|
1405
|
-
const _contract = new
|
|
1409
|
+
const _contract = new ethers_v6_1.Contract(tokenAddress, (0, sysweb3_utils_1.getErc20Abi)(), this.web3Provider);
|
|
1406
1410
|
const resolvedDecimals = decimals === undefined || decimals === null ? 18 : Number(decimals);
|
|
1407
|
-
const calculatedTokenAmount = (0,
|
|
1411
|
+
const calculatedTokenAmount = (0, ethers_v6_1.parseUnits)(tokenAmount, resolvedDecimals).toBigInt();
|
|
1408
1412
|
const txData = _contract.interface.encodeFunctionData('transfer', [
|
|
1409
1413
|
receiver,
|
|
1410
1414
|
calculatedTokenAmount,
|
|
@@ -1475,7 +1479,7 @@ class EthereumTransactions {
|
|
|
1475
1479
|
};
|
|
1476
1480
|
}
|
|
1477
1481
|
signature.payload.v = parseInt(signature.payload.v, 16); //v parameter must be a number by ethers standards
|
|
1478
|
-
const signedTx = (0,
|
|
1482
|
+
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, signature.payload);
|
|
1479
1483
|
const finalTx = await this.web3Provider.sendTransaction(signedTx);
|
|
1480
1484
|
saveTrezorTx && saveTrezorTx(finalTx);
|
|
1481
1485
|
return finalTx;
|
|
@@ -1498,7 +1502,7 @@ class EthereumTransactions {
|
|
|
1498
1502
|
case types_1.KeyringAccountType.Ledger:
|
|
1499
1503
|
return await sendERC20TokenOnLedger();
|
|
1500
1504
|
default:
|
|
1501
|
-
return await sendERC20Token();
|
|
1505
|
+
return (await sendERC20Token());
|
|
1502
1506
|
}
|
|
1503
1507
|
};
|
|
1504
1508
|
this.sendSignedErc721Transaction = async ({ receiver, tokenAddress, tokenId, isLegacy, maxPriorityFeePerGas, maxFeePerGas, gasPrice, gasLimit, }) => {
|
|
@@ -1506,40 +1510,42 @@ class EthereumTransactions {
|
|
|
1506
1510
|
const { accounts, activeAccountType, activeAccountId, activeNetwork } = this.getState();
|
|
1507
1511
|
const { address: activeAccountAddress } = accounts[activeAccountType][activeAccountId];
|
|
1508
1512
|
const sendERC721Token = async () => {
|
|
1509
|
-
const currentWallet = new wallet_1.Wallet(decryptedPrivateKey);
|
|
1510
|
-
const walletSigned = currentWallet.connect(this.web3Provider);
|
|
1511
1513
|
let transferMethod;
|
|
1512
1514
|
try {
|
|
1513
|
-
const _contract = new
|
|
1515
|
+
const _contract = new ethers_v6_1.Contract(tokenAddress, (0, sysweb3_utils_1.getErc21Abi)(), this.web3Provider);
|
|
1514
1516
|
if (isLegacy) {
|
|
1515
1517
|
const overrides = {
|
|
1516
|
-
nonce: await this.web3Provider.getTransactionCount(
|
|
1518
|
+
nonce: await this.web3Provider.getTransactionCount(activeAccountAddress, 'pending'),
|
|
1517
1519
|
gasPrice,
|
|
1518
1520
|
...(gasLimit && { gasLimit }),
|
|
1519
1521
|
type: 0, // Explicitly set Type 0 for legacy NFT transfers
|
|
1520
1522
|
};
|
|
1521
|
-
transferMethod = await _contract.transferFrom(
|
|
1523
|
+
transferMethod = await _contract.transferFrom.populateTransaction(activeAccountAddress, receiver, tokenId, normalizeEthersOverrides(overrides));
|
|
1522
1524
|
}
|
|
1523
1525
|
else {
|
|
1524
1526
|
const overrides = {
|
|
1525
|
-
nonce: await this.web3Provider.getTransactionCount(
|
|
1527
|
+
nonce: await this.web3Provider.getTransactionCount(activeAccountAddress, 'pending'),
|
|
1526
1528
|
maxPriorityFeePerGas,
|
|
1527
1529
|
maxFeePerGas,
|
|
1528
1530
|
...(gasLimit && { gasLimit }),
|
|
1529
1531
|
};
|
|
1530
|
-
transferMethod = await _contract.transferFrom(
|
|
1532
|
+
transferMethod = await _contract.transferFrom.populateTransaction(activeAccountAddress, receiver, tokenId, normalizeEthersOverrides(overrides));
|
|
1531
1533
|
}
|
|
1532
|
-
return
|
|
1534
|
+
return await (0, evm_local_signer_1.sendLocalEvmTransaction)(this.web3Provider, decryptedPrivateKey, {
|
|
1535
|
+
...transferMethod,
|
|
1536
|
+
chainId: activeNetwork.chainId,
|
|
1537
|
+
from: activeAccountAddress,
|
|
1538
|
+
value: '0x0',
|
|
1539
|
+
});
|
|
1533
1540
|
}
|
|
1534
1541
|
catch (error) {
|
|
1535
1542
|
throw error;
|
|
1536
1543
|
}
|
|
1537
1544
|
};
|
|
1538
1545
|
const sendERC721TokenOnLedger = async () => {
|
|
1539
|
-
const signer = this.web3Provider.getSigner(activeAccountAddress);
|
|
1540
1546
|
const transactionNonce = await this.getRecommendedNonce(activeAccountAddress);
|
|
1541
1547
|
try {
|
|
1542
|
-
const _contract = new
|
|
1548
|
+
const _contract = new ethers_v6_1.Contract(tokenAddress, (0, sysweb3_utils_1.getErc21Abi)(), this.web3Provider);
|
|
1543
1549
|
const txData = _contract.interface.encodeFunctionData('transferFrom', [
|
|
1544
1550
|
activeAccountAddress,
|
|
1545
1551
|
receiver,
|
|
@@ -1573,7 +1579,7 @@ class EthereumTransactions {
|
|
|
1573
1579
|
type: 2, // Need explicit type for hardware wallet serialization
|
|
1574
1580
|
};
|
|
1575
1581
|
}
|
|
1576
|
-
const rawTx = (0,
|
|
1582
|
+
const rawTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers);
|
|
1577
1583
|
const signature = await this.ledgerSigner.evm.signEVMTransaction({
|
|
1578
1584
|
rawTx: rawTx.replace('0x', ''),
|
|
1579
1585
|
accountIndex: activeAccountId,
|
|
@@ -1585,7 +1591,7 @@ class EthereumTransactions {
|
|
|
1585
1591
|
};
|
|
1586
1592
|
if (signature) {
|
|
1587
1593
|
try {
|
|
1588
|
-
const signedTx = (0,
|
|
1594
|
+
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, formattedSignature);
|
|
1589
1595
|
const finalTx = await this.web3Provider.sendTransaction(signedTx);
|
|
1590
1596
|
return finalTx;
|
|
1591
1597
|
}
|
|
@@ -1602,10 +1608,9 @@ class EthereumTransactions {
|
|
|
1602
1608
|
}
|
|
1603
1609
|
};
|
|
1604
1610
|
const sendERC721TokenOnTrezor = async () => {
|
|
1605
|
-
const signer = this.web3Provider.getSigner(activeAccountAddress);
|
|
1606
1611
|
const transactionNonce = await this.getRecommendedNonce(activeAccountAddress);
|
|
1607
1612
|
try {
|
|
1608
|
-
const _contract = new
|
|
1613
|
+
const _contract = new ethers_v6_1.Contract(tokenAddress, (0, sysweb3_utils_1.getErc21Abi)(), this.web3Provider);
|
|
1609
1614
|
const txData = _contract.interface.encodeFunctionData('transferFrom', [
|
|
1610
1615
|
activeAccountAddress,
|
|
1611
1616
|
receiver,
|
|
@@ -1680,7 +1685,7 @@ class EthereumTransactions {
|
|
|
1680
1685
|
};
|
|
1681
1686
|
}
|
|
1682
1687
|
signature.payload.v = parseInt(signature.payload.v, 16); //v parameter must be a number by ethers standards
|
|
1683
|
-
const signedTx = (0,
|
|
1688
|
+
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, signature.payload);
|
|
1684
1689
|
const finalTx = await this.web3Provider.sendTransaction(signedTx);
|
|
1685
1690
|
return finalTx;
|
|
1686
1691
|
}
|
|
@@ -1704,7 +1709,7 @@ class EthereumTransactions {
|
|
|
1704
1709
|
case types_1.KeyringAccountType.Ledger:
|
|
1705
1710
|
return await sendERC721TokenOnLedger();
|
|
1706
1711
|
default:
|
|
1707
|
-
return await sendERC721Token();
|
|
1712
|
+
return (await sendERC721Token());
|
|
1708
1713
|
}
|
|
1709
1714
|
};
|
|
1710
1715
|
this.sendSignedErc1155Transaction = async ({ receiver, tokenAddress, tokenId, tokenAmount, isLegacy, maxPriorityFeePerGas, maxFeePerGas, gasPrice, gasLimit, }) => {
|
|
@@ -1712,17 +1717,15 @@ class EthereumTransactions {
|
|
|
1712
1717
|
const { accounts, activeAccountType, activeAccountId, activeNetwork } = this.getState();
|
|
1713
1718
|
const { address: activeAccountAddress } = accounts[activeAccountType][activeAccountId];
|
|
1714
1719
|
const sendERC1155Token = async () => {
|
|
1715
|
-
const currentWallet = new wallet_1.Wallet(decryptedPrivateKey);
|
|
1716
|
-
const walletSigned = currentWallet.connect(this.web3Provider);
|
|
1717
1720
|
let transferMethod;
|
|
1718
1721
|
try {
|
|
1719
|
-
const _contract = new
|
|
1722
|
+
const _contract = new ethers_v6_1.Contract(tokenAddress, (0, sysweb3_utils_1.getErc55Abi)(), this.web3Provider);
|
|
1720
1723
|
// Use BigNumber to avoid JS number overflow/precision loss
|
|
1721
|
-
const amount =
|
|
1724
|
+
const amount = ethers_v6_1.BigNumber.from(tokenAmount ?? '1');
|
|
1722
1725
|
let overrides;
|
|
1723
1726
|
if (isLegacy) {
|
|
1724
1727
|
overrides = {
|
|
1725
|
-
nonce: await this.web3Provider.getTransactionCount(
|
|
1728
|
+
nonce: await this.web3Provider.getTransactionCount(activeAccountAddress, 'pending'),
|
|
1726
1729
|
gasPrice,
|
|
1727
1730
|
...(gasLimit && { gasLimit }),
|
|
1728
1731
|
type: 0, // Explicitly set Type 0 for legacy ERC1155 transfers
|
|
@@ -1730,26 +1733,30 @@ class EthereumTransactions {
|
|
|
1730
1733
|
}
|
|
1731
1734
|
else {
|
|
1732
1735
|
overrides = {
|
|
1733
|
-
nonce: await this.web3Provider.getTransactionCount(
|
|
1736
|
+
nonce: await this.web3Provider.getTransactionCount(activeAccountAddress, 'pending'),
|
|
1734
1737
|
maxPriorityFeePerGas,
|
|
1735
1738
|
maxFeePerGas,
|
|
1736
1739
|
...(gasLimit && { gasLimit }),
|
|
1737
1740
|
};
|
|
1738
1741
|
}
|
|
1739
|
-
transferMethod = await _contract.safeTransferFrom(
|
|
1740
|
-
return
|
|
1742
|
+
transferMethod = await _contract.safeTransferFrom.populateTransaction(activeAccountAddress, receiver, tokenId, amount.toBigInt(), [], normalizeEthersOverrides(overrides));
|
|
1743
|
+
return await (0, evm_local_signer_1.sendLocalEvmTransaction)(this.web3Provider, decryptedPrivateKey, {
|
|
1744
|
+
...transferMethod,
|
|
1745
|
+
chainId: activeNetwork.chainId,
|
|
1746
|
+
from: activeAccountAddress,
|
|
1747
|
+
value: '0x0',
|
|
1748
|
+
});
|
|
1741
1749
|
}
|
|
1742
1750
|
catch (error) {
|
|
1743
1751
|
throw error;
|
|
1744
1752
|
}
|
|
1745
1753
|
};
|
|
1746
1754
|
const sendERC1155TokenOnLedger = async () => {
|
|
1747
|
-
const signer = this.web3Provider.getSigner(activeAccountAddress);
|
|
1748
1755
|
const transactionNonce = await this.getRecommendedNonce(activeAccountAddress);
|
|
1749
1756
|
try {
|
|
1750
|
-
const _contract = new
|
|
1751
|
-
const amount =
|
|
1752
|
-
const txData = _contract.interface.encodeFunctionData('safeTransferFrom', [activeAccountAddress, receiver, tokenId, amount, []]);
|
|
1757
|
+
const _contract = new ethers_v6_1.Contract(tokenAddress, (0, sysweb3_utils_1.getErc55Abi)(), this.web3Provider);
|
|
1758
|
+
const amount = ethers_v6_1.BigNumber.from(tokenAmount ?? '1');
|
|
1759
|
+
const txData = _contract.interface.encodeFunctionData('safeTransferFrom', [activeAccountAddress, receiver, tokenId, amount.toBigInt(), []]);
|
|
1753
1760
|
// Use fallback gas limit if not provided (for auto-estimation)
|
|
1754
1761
|
const effectiveGasLimit = gasLimit || this.toBigNumber('200000'); // ERC1155 fallback
|
|
1755
1762
|
let txFormattedForEthers;
|
|
@@ -1778,7 +1785,7 @@ class EthereumTransactions {
|
|
|
1778
1785
|
type: 2, // Need explicit type for hardware wallet serialization
|
|
1779
1786
|
};
|
|
1780
1787
|
}
|
|
1781
|
-
const rawTx = (0,
|
|
1788
|
+
const rawTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers);
|
|
1782
1789
|
const signature = await this.ledgerSigner.evm.signEVMTransaction({
|
|
1783
1790
|
rawTx: rawTx.replace('0x', ''),
|
|
1784
1791
|
accountIndex: activeAccountId,
|
|
@@ -1790,7 +1797,7 @@ class EthereumTransactions {
|
|
|
1790
1797
|
};
|
|
1791
1798
|
if (signature) {
|
|
1792
1799
|
try {
|
|
1793
|
-
const signedTx = (0,
|
|
1800
|
+
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, formattedSignature);
|
|
1794
1801
|
const finalTx = await this.web3Provider.sendTransaction(signedTx);
|
|
1795
1802
|
return finalTx;
|
|
1796
1803
|
}
|
|
@@ -1807,12 +1814,11 @@ class EthereumTransactions {
|
|
|
1807
1814
|
}
|
|
1808
1815
|
};
|
|
1809
1816
|
const sendERC1155TokenOnTrezor = async () => {
|
|
1810
|
-
const signer = this.web3Provider.getSigner(activeAccountAddress);
|
|
1811
1817
|
const transactionNonce = await this.getRecommendedNonce(activeAccountAddress);
|
|
1812
1818
|
try {
|
|
1813
|
-
const _contract = new
|
|
1814
|
-
const amount =
|
|
1815
|
-
const txData = _contract.interface.encodeFunctionData('safeTransferFrom', [activeAccountAddress, receiver, tokenId, amount, []]);
|
|
1819
|
+
const _contract = new ethers_v6_1.Contract(tokenAddress, (0, sysweb3_utils_1.getErc55Abi)(), this.web3Provider);
|
|
1820
|
+
const amount = ethers_v6_1.BigNumber.from(tokenAmount ?? '1');
|
|
1821
|
+
const txData = _contract.interface.encodeFunctionData('safeTransferFrom', [activeAccountAddress, receiver, tokenId, amount.toBigInt(), []]);
|
|
1816
1822
|
// Use fallback gas limit if not provided (for auto-estimation)
|
|
1817
1823
|
const effectiveGasLimit = gasLimit || this.toBigNumber('200000'); // ERC1155 fallback
|
|
1818
1824
|
let txToBeSignedByTrezor;
|
|
@@ -1879,7 +1885,7 @@ class EthereumTransactions {
|
|
|
1879
1885
|
};
|
|
1880
1886
|
}
|
|
1881
1887
|
signature.payload.v = parseInt(signature.payload.v, 16); //v parameter must be a number by ethers standards
|
|
1882
|
-
const signedTx = (0,
|
|
1888
|
+
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, signature.payload);
|
|
1883
1889
|
const finalTx = await this.web3Provider.sendTransaction(signedTx);
|
|
1884
1890
|
return finalTx;
|
|
1885
1891
|
}
|
|
@@ -1903,7 +1909,7 @@ class EthereumTransactions {
|
|
|
1903
1909
|
case types_1.KeyringAccountType.Ledger:
|
|
1904
1910
|
return await sendERC1155TokenOnLedger();
|
|
1905
1911
|
default:
|
|
1906
|
-
return await sendERC1155Token();
|
|
1912
|
+
return (await sendERC1155Token());
|
|
1907
1913
|
}
|
|
1908
1914
|
};
|
|
1909
1915
|
this.getRecommendedNonce = async (address) => {
|
|
@@ -1917,12 +1923,12 @@ class EthereumTransactions {
|
|
|
1917
1923
|
this.getFeeByType = async (type) => {
|
|
1918
1924
|
const gasPrice = (await this.getRecommendedGasPrice(false));
|
|
1919
1925
|
const low = this.toBigNumber(gasPrice)
|
|
1920
|
-
.mul(
|
|
1921
|
-
.div(
|
|
1926
|
+
.mul(ethers_v6_1.BigNumber.from('8'))
|
|
1927
|
+
.div(ethers_v6_1.BigNumber.from('10'))
|
|
1922
1928
|
.toString();
|
|
1923
1929
|
const high = this.toBigNumber(gasPrice)
|
|
1924
|
-
.mul(
|
|
1925
|
-
.div(
|
|
1930
|
+
.mul(ethers_v6_1.BigNumber.from('11'))
|
|
1931
|
+
.div(ethers_v6_1.BigNumber.from('10'))
|
|
1926
1932
|
.toString();
|
|
1927
1933
|
if (type === 'low')
|
|
1928
1934
|
return low;
|
|
@@ -1935,29 +1941,36 @@ class EthereumTransactions {
|
|
|
1935
1941
|
const estimated = await this.web3Provider.estimateGas({
|
|
1936
1942
|
to: toAddress,
|
|
1937
1943
|
});
|
|
1938
|
-
return Number((0,
|
|
1944
|
+
return Number((0, ethers_v6_1.formatUnits)(estimated, 'gwei'));
|
|
1939
1945
|
}
|
|
1940
1946
|
catch (error) {
|
|
1941
1947
|
throw error;
|
|
1942
1948
|
}
|
|
1943
1949
|
};
|
|
1944
1950
|
this.getTxGasLimit = async (tx) => {
|
|
1951
|
+
const hasCalldata = Boolean(tx.data && tx.data !== '0x' && tx.data !== '0x0');
|
|
1945
1952
|
try {
|
|
1946
1953
|
// First attempt: standard estimation
|
|
1947
1954
|
const estimated = await this.web3Provider.estimateGas(tx);
|
|
1948
|
-
//
|
|
1955
|
+
// Add 20% buffer to the estimated gas
|
|
1956
|
+
const withBuffer = estimated.mul(120).div(100);
|
|
1957
|
+
// Apply an explicit per-network floor only when configured.
|
|
1949
1958
|
if (this.gasOverrides.minGasLimit &&
|
|
1950
|
-
|
|
1959
|
+
withBuffer.lt(this.gasOverrides.minGasLimit)) {
|
|
1951
1960
|
return this.gasOverrides.minGasLimit;
|
|
1952
1961
|
}
|
|
1953
|
-
|
|
1954
|
-
const withBuffer = estimated.mul(120).div(100);
|
|
1955
|
-
// Ensure minimum of 65k for validation
|
|
1956
|
-
const minGas = bignumber_1.BigNumber.from('65000');
|
|
1957
|
-
return withBuffer.gt(minGas) ? withBuffer : minGas;
|
|
1962
|
+
return withBuffer;
|
|
1958
1963
|
}
|
|
1959
1964
|
catch (error) {
|
|
1960
1965
|
console.warn('Gas estimation failed:', error);
|
|
1966
|
+
if (hasCalldata) {
|
|
1967
|
+
const calldataFallback = ethers_v6_1.BigNumber.from('100000');
|
|
1968
|
+
if (this.gasOverrides.minGasLimit &&
|
|
1969
|
+
calldataFallback.lt(this.gasOverrides.minGasLimit)) {
|
|
1970
|
+
return this.gasOverrides.minGasLimit;
|
|
1971
|
+
}
|
|
1972
|
+
return calldataFallback;
|
|
1973
|
+
}
|
|
1961
1974
|
// Try a simpler estimation for basic transfers
|
|
1962
1975
|
try {
|
|
1963
1976
|
const simpleEstimate = await this.web3Provider.estimateGas({
|
|
@@ -1966,13 +1979,16 @@ class EthereumTransactions {
|
|
|
1966
1979
|
value: tx.value || '0x0',
|
|
1967
1980
|
});
|
|
1968
1981
|
const withBuffer = simpleEstimate.mul(150).div(100); // 50% buffer for failed estimations
|
|
1969
|
-
|
|
1970
|
-
|
|
1982
|
+
if (this.gasOverrides.minGasLimit &&
|
|
1983
|
+
withBuffer.lt(this.gasOverrides.minGasLimit)) {
|
|
1984
|
+
return this.gasOverrides.minGasLimit;
|
|
1985
|
+
}
|
|
1986
|
+
return withBuffer;
|
|
1971
1987
|
}
|
|
1972
1988
|
catch (secondError) {
|
|
1973
1989
|
// Ultimate fallback
|
|
1974
1990
|
console.warn('Simple estimation also failed, using default', secondError);
|
|
1975
|
-
return this.gasOverrides.minGasLimit ||
|
|
1991
|
+
return this.gasOverrides.minGasLimit || ethers_v6_1.BigNumber.from('100000');
|
|
1976
1992
|
}
|
|
1977
1993
|
}
|
|
1978
1994
|
};
|
|
@@ -1981,8 +1997,8 @@ class EthereumTransactions {
|
|
|
1981
1997
|
const gasPriceBN = await this.web3Provider.getGasPrice();
|
|
1982
1998
|
if (formatted) {
|
|
1983
1999
|
return {
|
|
1984
|
-
gwei: Number((0,
|
|
1985
|
-
ethers: (0,
|
|
2000
|
+
gwei: Number((0, ethers_v6_1.formatUnits)(gasPriceBN, 'gwei')).toFixed(2),
|
|
2001
|
+
ethers: (0, ethers_v6_1.formatEther)(gasPriceBN),
|
|
1986
2002
|
};
|
|
1987
2003
|
}
|
|
1988
2004
|
return gasPriceBN.toString();
|
|
@@ -1994,7 +2010,7 @@ class EthereumTransactions {
|
|
|
1994
2010
|
this.getBalance = async (address) => {
|
|
1995
2011
|
try {
|
|
1996
2012
|
const balance = await this.web3Provider.getBalance(address);
|
|
1997
|
-
const formattedBalance = (0,
|
|
2013
|
+
const formattedBalance = (0, ethers_v6_1.formatEther)(balance);
|
|
1998
2014
|
return parseFloat(formattedBalance); // Return full precision
|
|
1999
2015
|
}
|
|
2000
2016
|
catch (error) {
|
|
@@ -2009,12 +2025,10 @@ class EthereumTransactions {
|
|
|
2009
2025
|
};
|
|
2010
2026
|
};
|
|
2011
2027
|
this.importAccount = (mnemonicOrPrivKey) => {
|
|
2012
|
-
if ((0,
|
|
2013
|
-
return
|
|
2028
|
+
if ((0, ethers_v6_1.isHexString)(mnemonicOrPrivKey)) {
|
|
2029
|
+
return (0, evm_local_signer_1.privateKeyToAccount)(mnemonicOrPrivKey);
|
|
2014
2030
|
}
|
|
2015
|
-
|
|
2016
|
-
const account = new wallet_1.Wallet(privateKey);
|
|
2017
|
-
return account;
|
|
2031
|
+
return (0, evm_local_signer_1.deriveEvmAccountFromMnemonic)(mnemonicOrPrivKey, (0, derivation_paths_1.getAddressDerivationPath)('eth', 60, 0, false, 0));
|
|
2018
2032
|
};
|
|
2019
2033
|
// Method to get safe fee data that works around network-specific validation issues
|
|
2020
2034
|
this.getSafeFeeData = async (forceLegacy = false) => {
|
|
@@ -2128,10 +2142,10 @@ class EthereumTransactions {
|
|
|
2128
2142
|
setGasOverrides(overrides) {
|
|
2129
2143
|
this.gasOverrides = {
|
|
2130
2144
|
minGasLimit: overrides.minGasLimit
|
|
2131
|
-
?
|
|
2145
|
+
? ethers_v6_1.BigNumber.from(overrides.minGasLimit)
|
|
2132
2146
|
: undefined,
|
|
2133
2147
|
minPriorityFee: overrides.minPriorityFee
|
|
2134
|
-
?
|
|
2148
|
+
? ethers_v6_1.BigNumber.from(overrides.minPriorityFee)
|
|
2135
2149
|
: undefined,
|
|
2136
2150
|
feeMultiplier: overrides.feeMultiplier,
|
|
2137
2151
|
};
|