@sidhujag/sysweb3-keyring 1.0.578 → 1.0.580
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/keyring-manager.js +6 -3
- package/cjs/keyring-manager.js.map +1 -1
- package/cjs/transactions/ethereum.js +153 -94
- package/cjs/transactions/ethereum.js.map +1 -1
- package/cjs/transactions/syscoin.js +0 -2
- package/cjs/transactions/syscoin.js.map +1 -1
- package/cjs/types.js.map +1 -1
- package/package.json +1 -1
- package/types/transactions/ethereum.d.ts +2 -0
- package/types/types.d.ts +6 -0
|
@@ -358,6 +358,29 @@ class EthereumTransactions {
|
|
|
358
358
|
}
|
|
359
359
|
};
|
|
360
360
|
this.toBigNumber = (aBigNumberish) => bignumber_1.BigNumber.from(String(aBigNumberish));
|
|
361
|
+
this.toHex0x = (value, fieldName) => {
|
|
362
|
+
if (value === undefined || value === null)
|
|
363
|
+
return '0x0';
|
|
364
|
+
if (typeof value === 'string') {
|
|
365
|
+
const v = value.trim();
|
|
366
|
+
if (v === '')
|
|
367
|
+
return '0x0';
|
|
368
|
+
if (v.startsWith('0x'))
|
|
369
|
+
return v;
|
|
370
|
+
return bignumber_1.BigNumber.from(v).toHexString();
|
|
371
|
+
}
|
|
372
|
+
if (typeof value === 'number')
|
|
373
|
+
return bignumber_1.BigNumber.from(value).toHexString();
|
|
374
|
+
if (bignumber_1.BigNumber.isBigNumber(value))
|
|
375
|
+
return value.toHexString();
|
|
376
|
+
const maybeHex = value?._hex ?? value?.hex ?? value;
|
|
377
|
+
try {
|
|
378
|
+
return bignumber_1.BigNumber.from(maybeHex).toHexString();
|
|
379
|
+
}
|
|
380
|
+
catch (_e) {
|
|
381
|
+
throw new Error(`Invalid numeric field "${fieldName}" for EVM tx: ${String(value)}`);
|
|
382
|
+
}
|
|
383
|
+
};
|
|
361
384
|
this.getData = ({ contractAddress, receivingAddress, value, }) => {
|
|
362
385
|
const abi = (0, sysweb3_utils_1.getErc20Abi)();
|
|
363
386
|
try {
|
|
@@ -385,7 +408,7 @@ class EthereumTransactions {
|
|
|
385
408
|
maxFeePerGas = gasPrice.mul(120).div(100); // 20% buffer on gas price
|
|
386
409
|
console.log('[zkSync] Fee data:', {
|
|
387
410
|
maxFeePerGas: maxFeePerGas.toString(),
|
|
388
|
-
maxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
411
|
+
maxPriorityFeePerGas: maxPriorityFeePerGas.toString(),
|
|
389
412
|
});
|
|
390
413
|
return { maxFeePerGas, maxPriorityFeePerGas };
|
|
391
414
|
}
|
|
@@ -394,7 +417,7 @@ class EthereumTransactions {
|
|
|
394
417
|
// Fallback for zkSync
|
|
395
418
|
return {
|
|
396
419
|
maxFeePerGas: bignumber_1.BigNumber.from('250000000'), // 0.25 gwei
|
|
397
|
-
maxPriorityFeePerGas: bignumber_1.BigNumber.from('2500000') // 0.0025 gwei
|
|
420
|
+
maxPriorityFeePerGas: bignumber_1.BigNumber.from('2500000'), // 0.0025 gwei
|
|
398
421
|
};
|
|
399
422
|
}
|
|
400
423
|
}
|
|
@@ -408,7 +431,8 @@ class EthereumTransactions {
|
|
|
408
431
|
const ethMaxPriorityFee = await this.web3Provider.send('eth_maxPriorityFeePerGas', []);
|
|
409
432
|
maxPriorityFeePerGas = bignumber_1.BigNumber.from(ethMaxPriorityFee);
|
|
410
433
|
// Apply minimum priority fee override if set
|
|
411
|
-
if (this.gasOverrides.minPriorityFee &&
|
|
434
|
+
if (this.gasOverrides.minPriorityFee &&
|
|
435
|
+
maxPriorityFeePerGas.lt(this.gasOverrides.minPriorityFee)) {
|
|
412
436
|
maxPriorityFeePerGas = this.gasOverrides.minPriorityFee;
|
|
413
437
|
}
|
|
414
438
|
if (maxPriorityFeePerGas.isZero()) {
|
|
@@ -419,9 +443,14 @@ class EthereumTransactions {
|
|
|
419
443
|
const baselineMaxFee = currentGasPrice.mul(120).div(100); // 20% above current gas price
|
|
420
444
|
// Calculate standard maxFeePerGas
|
|
421
445
|
const multiplier = this.gasOverrides.feeMultiplier || 250;
|
|
422
|
-
const calculatedMaxFee = block.baseFeePerGas
|
|
446
|
+
const calculatedMaxFee = block.baseFeePerGas
|
|
447
|
+
.mul(multiplier)
|
|
448
|
+
.div(100)
|
|
449
|
+
.add(maxPriorityFeePerGas);
|
|
423
450
|
// Use the higher of the two to ensure transaction goes through
|
|
424
|
-
maxFeePerGas = calculatedMaxFee.gt(baselineMaxFee)
|
|
451
|
+
maxFeePerGas = calculatedMaxFee.gt(baselineMaxFee)
|
|
452
|
+
? calculatedMaxFee
|
|
453
|
+
: baselineMaxFee;
|
|
425
454
|
}
|
|
426
455
|
catch (e) {
|
|
427
456
|
// Use a more aggressive fallback strategy with higher priority fees
|
|
@@ -430,9 +459,11 @@ class EthereumTransactions {
|
|
|
430
459
|
const feeHistory = await this.web3Provider.send('eth_feeHistory', [
|
|
431
460
|
'0x5', // Last 5 blocks
|
|
432
461
|
'latest',
|
|
433
|
-
[25, 50, 75] // Percentiles for priority fees
|
|
462
|
+
[25, 50, 75], // Percentiles for priority fees
|
|
434
463
|
]);
|
|
435
|
-
if (feeHistory &&
|
|
464
|
+
if (feeHistory &&
|
|
465
|
+
feeHistory.reward &&
|
|
466
|
+
feeHistory.reward.length > 0) {
|
|
436
467
|
// Use median of the 50th percentile from recent blocks
|
|
437
468
|
const recentFees = feeHistory.reward
|
|
438
469
|
.map((r) => r[1]) // Get 50th percentile
|
|
@@ -469,8 +500,13 @@ class EthereumTransactions {
|
|
|
469
500
|
// Calculate maxFeePerGas based on current network conditions
|
|
470
501
|
const currentGasPrice = await this.web3Provider.getGasPrice();
|
|
471
502
|
const baselineMaxFee = currentGasPrice.mul(120).div(100);
|
|
472
|
-
const calculatedMaxFee = block.baseFeePerGas
|
|
473
|
-
|
|
503
|
+
const calculatedMaxFee = block.baseFeePerGas
|
|
504
|
+
.mul(250)
|
|
505
|
+
.div(100)
|
|
506
|
+
.add(maxPriorityFeePerGas);
|
|
507
|
+
maxFeePerGas = calculatedMaxFee.gt(baselineMaxFee)
|
|
508
|
+
? calculatedMaxFee
|
|
509
|
+
: baselineMaxFee;
|
|
474
510
|
}
|
|
475
511
|
// Ensure maxFeePerGas is at least 20% higher than maxPriorityFeePerGas
|
|
476
512
|
const minMaxFee = maxPriorityFeePerGas.mul(120).div(100);
|
|
@@ -482,7 +518,10 @@ class EthereumTransactions {
|
|
|
482
518
|
else if (block && !block.baseFeePerGas) {
|
|
483
519
|
// For non-EIP1559 chains, return zeros to indicate legacy transaction should be used
|
|
484
520
|
console.log('Chain does not support EIP1559, use legacy transactions');
|
|
485
|
-
return {
|
|
521
|
+
return {
|
|
522
|
+
maxFeePerGas: bignumber_1.BigNumber.from(0),
|
|
523
|
+
maxPriorityFeePerGas: bignumber_1.BigNumber.from(0),
|
|
524
|
+
};
|
|
486
525
|
}
|
|
487
526
|
else if (!block)
|
|
488
527
|
throw new Error('Block not found');
|
|
@@ -681,9 +720,9 @@ class EthereumTransactions {
|
|
|
681
720
|
...formattedTx,
|
|
682
721
|
gasLimit: typeof formattedTx.gasLimit === 'string'
|
|
683
722
|
? formattedTx.gasLimit
|
|
684
|
-
: this.
|
|
723
|
+
: this.toHex0x(formattedTx.gasLimit, 'gasLimit'),
|
|
685
724
|
value: '0x0',
|
|
686
|
-
nonce: this.
|
|
725
|
+
nonce: this.toHex0x(formattedTx.nonce, 'nonce'),
|
|
687
726
|
chainId: activeNetwork.chainId,
|
|
688
727
|
type: isLegacy ? 0 : 2, // Need explicit type for hardware wallet serialization
|
|
689
728
|
};
|
|
@@ -691,19 +730,17 @@ class EthereumTransactions {
|
|
|
691
730
|
txFormattedForTrezor.gasPrice =
|
|
692
731
|
typeof formattedTx.gasPrice === 'string'
|
|
693
732
|
? formattedTx.gasPrice
|
|
694
|
-
: this.
|
|
733
|
+
: this.toHex0x(formattedTx.gasPrice, 'gasPrice');
|
|
695
734
|
}
|
|
696
735
|
else {
|
|
697
736
|
txFormattedForTrezor.maxFeePerGas =
|
|
698
737
|
typeof formattedTx.maxFeePerGas === 'string'
|
|
699
738
|
? formattedTx.maxFeePerGas
|
|
700
|
-
:
|
|
701
|
-
formattedTx.maxFeePerGas}`;
|
|
739
|
+
: this.toHex0x(formattedTx.maxFeePerGas, 'maxFeePerGas');
|
|
702
740
|
txFormattedForTrezor.maxPriorityFeePerGas =
|
|
703
741
|
typeof formattedTx.maxPriorityFeePerGas === 'string'
|
|
704
742
|
? formattedTx.maxPriorityFeePerGas
|
|
705
|
-
:
|
|
706
|
-
formattedTx.maxPriorityFeePerGas}`;
|
|
743
|
+
: this.toHex0x(formattedTx.maxPriorityFeePerGas, 'maxPriorityFeePerGas');
|
|
707
744
|
}
|
|
708
745
|
const signature = await this.trezorSigner.signEthTransaction({
|
|
709
746
|
coin: trezorCoin,
|
|
@@ -776,7 +813,8 @@ class EthereumTransactions {
|
|
|
776
813
|
if (this.isZkSyncNetwork) {
|
|
777
814
|
// zkSync uses EIP-712 transactions but we can still use EIP-1559 format
|
|
778
815
|
// Ensure proper gas configuration for zkSync
|
|
779
|
-
if (!params.gasLimit ||
|
|
816
|
+
if (!params.gasLimit ||
|
|
817
|
+
bignumber_1.BigNumber.from(params.gasLimit).lt(bignumber_1.BigNumber.from('500000'))) {
|
|
780
818
|
// zkSync typically needs higher gas limits
|
|
781
819
|
params.gasLimit = bignumber_1.BigNumber.from('1000000'); // 1M gas default for zkSync
|
|
782
820
|
console.log('[zkSync] Setting gas limit to 1M');
|
|
@@ -786,7 +824,9 @@ class EthereumTransactions {
|
|
|
786
824
|
console.log('[zkSync] Converting to EIP-1559 format');
|
|
787
825
|
isLegacy = false;
|
|
788
826
|
// Convert legacy to EIP-1559 for zkSync
|
|
789
|
-
const gasPrice = params.gasPrice
|
|
827
|
+
const gasPrice = params.gasPrice
|
|
828
|
+
? bignumber_1.BigNumber.from(params.gasPrice)
|
|
829
|
+
: await this.web3Provider.getGasPrice();
|
|
790
830
|
params.maxFeePerGas = gasPrice.mul(120).div(100); // 20% buffer
|
|
791
831
|
params.maxPriorityFeePerGas = gasPrice.div(100); // 1% operator tip for zkSync
|
|
792
832
|
delete params.gasPrice;
|
|
@@ -805,7 +845,10 @@ class EthereumTransactions {
|
|
|
805
845
|
}
|
|
806
846
|
// Check if we should force legacy transactions for non-zkSync networks
|
|
807
847
|
// Some networks have issues with EIP-1559 validation
|
|
808
|
-
if (!this.isZkSyncNetwork &&
|
|
848
|
+
if (!this.isZkSyncNetwork &&
|
|
849
|
+
!isLegacy &&
|
|
850
|
+
params.maxFeePerGas &&
|
|
851
|
+
params.maxPriorityFeePerGas) {
|
|
809
852
|
const maxFee = bignumber_1.BigNumber.from(params.maxFeePerGas);
|
|
810
853
|
const priorityFee = bignumber_1.BigNumber.from(params.maxPriorityFeePerGas);
|
|
811
854
|
// If fees are zero or network doesn't support EIP-1559, use legacy
|
|
@@ -829,6 +872,30 @@ class EthereumTransactions {
|
|
|
829
872
|
params.gasLimit = minGasLimit;
|
|
830
873
|
}
|
|
831
874
|
}
|
|
875
|
+
// MAX-send handling (native transfers only): recompute value at send-time
|
|
876
|
+
// using live balance and the final gas parameters we will actually submit.
|
|
877
|
+
// This avoids caller-side rounding/estimation mismatches (e.g. 42k vs 65k min gasLimit,
|
|
878
|
+
// EIP-1559->legacy switching, or fee changes) which otherwise surface as
|
|
879
|
+
// "insufficient funds for gas * price + value".
|
|
880
|
+
if (params.isMaxSend) {
|
|
881
|
+
const data = params.data;
|
|
882
|
+
const isSimpleTransfer = data === undefined ||
|
|
883
|
+
data === null ||
|
|
884
|
+
data === '0x' ||
|
|
885
|
+
(typeof data === 'string' && data.toLowerCase() === '0x');
|
|
886
|
+
if (isSimpleTransfer && params.gasLimit) {
|
|
887
|
+
const liveBalanceWei = await this.web3Provider.getBalance(activeAccount.address);
|
|
888
|
+
const gasLimit = bignumber_1.BigNumber.from(params.gasLimit);
|
|
889
|
+
// Use maxFeePerGas as worst-case for EIP-1559; gasPrice for legacy.
|
|
890
|
+
const feePerGas = isLegacy || params.gasPrice
|
|
891
|
+
? bignumber_1.BigNumber.from(params.gasPrice || 0)
|
|
892
|
+
: bignumber_1.BigNumber.from(params.maxFeePerGas || 0);
|
|
893
|
+
const gasCostWei = gasLimit.mul(feePerGas);
|
|
894
|
+
params.value = liveBalanceWei.gt(gasCostWei)
|
|
895
|
+
? liveBalanceWei.sub(gasCostWei)
|
|
896
|
+
: constants_1.Zero;
|
|
897
|
+
}
|
|
898
|
+
}
|
|
832
899
|
const sendEVMLedgerTransaction = async () => {
|
|
833
900
|
const transactionNonce = await this.getRecommendedNonce(activeAccount.address);
|
|
834
901
|
const formatParams = isLegacy
|
|
@@ -881,65 +948,39 @@ class EthereumTransactions {
|
|
|
881
948
|
case true:
|
|
882
949
|
txFormattedForTrezor = {
|
|
883
950
|
...formatParams,
|
|
884
|
-
gasLimit:
|
|
885
|
-
|
|
886
|
-
: // @ts-ignore
|
|
887
|
-
`${params.gasLimit.hex}`,
|
|
888
|
-
value: typeof formatParams.value === 'string' ||
|
|
889
|
-
typeof formatParams.value === 'number'
|
|
890
|
-
? `${formatParams.value}`
|
|
891
|
-
: // @ts-ignore
|
|
892
|
-
`${params.value.hex}`,
|
|
951
|
+
gasLimit: this.toHex0x(formatParams.gasLimit ?? params.gasLimit, 'gasLimit'),
|
|
952
|
+
value: this.toHex0x(formatParams.value ?? params.value, 'value'),
|
|
893
953
|
nonce: this.toBigNumber(transactionNonce)._hex,
|
|
894
954
|
chainId: activeNetwork.chainId,
|
|
955
|
+
data: formatParams.data ?? '0x',
|
|
895
956
|
};
|
|
896
957
|
break;
|
|
897
958
|
case false:
|
|
898
959
|
txFormattedForTrezor = {
|
|
899
960
|
...formatParams,
|
|
900
|
-
gasLimit:
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
: // @ts-ignore
|
|
907
|
-
`${params.maxFeePerGas.hex}`,
|
|
908
|
-
maxPriorityFeePerGas: typeof formatParams.maxPriorityFeePerGas === 'string'
|
|
909
|
-
? formatParams.maxPriorityFeePerGas
|
|
910
|
-
: // @ts-ignore
|
|
911
|
-
`${params.maxPriorityFeePerGas.hex}`,
|
|
912
|
-
value: typeof formatParams.value === 'string' ||
|
|
913
|
-
typeof formatParams.value === 'number'
|
|
914
|
-
? `${formatParams.value}`
|
|
915
|
-
: // @ts-ignore
|
|
916
|
-
`${params.value.hex}`,
|
|
961
|
+
gasLimit: this.toHex0x(formatParams.gasLimit ?? params.gasLimit, 'gasLimit'),
|
|
962
|
+
maxFeePerGas: this.toHex0x(formatParams.maxFeePerGas ??
|
|
963
|
+
params.maxFeePerGas, 'maxFeePerGas'),
|
|
964
|
+
maxPriorityFeePerGas: this.toHex0x(formatParams.maxPriorityFeePerGas ??
|
|
965
|
+
params.maxPriorityFeePerGas, 'maxPriorityFeePerGas'),
|
|
966
|
+
value: this.toHex0x(formatParams.value ?? params.value, 'value'),
|
|
917
967
|
nonce: this.toBigNumber(transactionNonce)._hex,
|
|
918
968
|
chainId: activeNetwork.chainId,
|
|
969
|
+
data: formatParams.data ?? '0x',
|
|
919
970
|
};
|
|
920
971
|
break;
|
|
921
972
|
default:
|
|
922
973
|
txFormattedForTrezor = {
|
|
923
974
|
...formatParams,
|
|
924
|
-
gasLimit:
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
: // @ts-ignore
|
|
931
|
-
`${params.maxFeePerGas.hex}`,
|
|
932
|
-
maxPriorityFeePerGas: typeof formatParams.maxPriorityFeePerGas === 'string'
|
|
933
|
-
? formatParams.maxPriorityFeePerGas
|
|
934
|
-
: // @ts-ignore
|
|
935
|
-
`${params.maxPriorityFeePerGas.hex}`,
|
|
936
|
-
value: typeof formatParams.value === 'string' ||
|
|
937
|
-
typeof formatParams.value === 'number'
|
|
938
|
-
? `${formatParams.value}`
|
|
939
|
-
: // @ts-ignore
|
|
940
|
-
`${params.value.hex}`,
|
|
975
|
+
gasLimit: this.toHex0x(formatParams.gasLimit ?? params.gasLimit, 'gasLimit'),
|
|
976
|
+
maxFeePerGas: this.toHex0x(formatParams.maxFeePerGas ??
|
|
977
|
+
params.maxFeePerGas, 'maxFeePerGas'),
|
|
978
|
+
maxPriorityFeePerGas: this.toHex0x(formatParams.maxPriorityFeePerGas ??
|
|
979
|
+
params.maxPriorityFeePerGas, 'maxPriorityFeePerGas'),
|
|
980
|
+
value: this.toHex0x(formatParams.value ?? params.value, 'value'),
|
|
941
981
|
nonce: this.toBigNumber(transactionNonce)._hex,
|
|
942
982
|
chainId: activeNetwork.chainId,
|
|
983
|
+
data: formatParams.data ?? '0x',
|
|
943
984
|
};
|
|
944
985
|
break;
|
|
945
986
|
}
|
|
@@ -1224,11 +1265,11 @@ class EthereumTransactions {
|
|
|
1224
1265
|
...formattedTx,
|
|
1225
1266
|
gasLimit: typeof formattedTx.gasLimit === 'string'
|
|
1226
1267
|
? formattedTx.gasLimit
|
|
1227
|
-
: this.
|
|
1268
|
+
: this.toHex0x(formattedTx.gasLimit, 'gasLimit'),
|
|
1228
1269
|
value: typeof formattedTx.value === 'string'
|
|
1229
1270
|
? formattedTx.value
|
|
1230
|
-
: this.
|
|
1231
|
-
nonce: this.
|
|
1271
|
+
: this.toHex0x(formattedTx.value, 'value'),
|
|
1272
|
+
nonce: this.toHex0x(formattedTx.nonce, 'nonce'),
|
|
1232
1273
|
chainId: activeNetwork.chainId,
|
|
1233
1274
|
type: isLegacy ? 0 : 2, // Need explicit type for hardware wallet serialization
|
|
1234
1275
|
};
|
|
@@ -1239,19 +1280,17 @@ class EthereumTransactions {
|
|
|
1239
1280
|
txFormattedForTrezor.gasPrice =
|
|
1240
1281
|
typeof formattedTx.gasPrice === 'string'
|
|
1241
1282
|
? formattedTx.gasPrice
|
|
1242
|
-
: this.
|
|
1283
|
+
: this.toHex0x(formattedTx.gasPrice, 'gasPrice');
|
|
1243
1284
|
}
|
|
1244
1285
|
else {
|
|
1245
1286
|
txFormattedForTrezor.maxFeePerGas =
|
|
1246
1287
|
typeof formattedTx.maxFeePerGas === 'string'
|
|
1247
1288
|
? formattedTx.maxFeePerGas
|
|
1248
|
-
:
|
|
1249
|
-
formattedTx.maxFeePerGas}`;
|
|
1289
|
+
: this.toHex0x(formattedTx.maxFeePerGas, 'maxFeePerGas');
|
|
1250
1290
|
txFormattedForTrezor.maxPriorityFeePerGas =
|
|
1251
1291
|
typeof formattedTx.maxPriorityFeePerGas === 'string'
|
|
1252
1292
|
? formattedTx.maxPriorityFeePerGas
|
|
1253
|
-
:
|
|
1254
|
-
formattedTx.maxPriorityFeePerGas}`;
|
|
1293
|
+
: this.toHex0x(formattedTx.maxPriorityFeePerGas, 'maxPriorityFeePerGas');
|
|
1255
1294
|
}
|
|
1256
1295
|
const signature = await this.trezorSigner.signEthTransaction({
|
|
1257
1296
|
coin: trezorCoin,
|
|
@@ -1996,12 +2035,16 @@ class EthereumTransactions {
|
|
|
1996
2035
|
// zkSync requires special gas estimation
|
|
1997
2036
|
// Use zks_estimateFee for more accurate estimation
|
|
1998
2037
|
try {
|
|
1999
|
-
const zkEstimate = await this.web3Provider.send('zks_estimateFee', [
|
|
2038
|
+
const zkEstimate = await this.web3Provider.send('zks_estimateFee', [
|
|
2039
|
+
{
|
|
2000
2040
|
from: tx.from,
|
|
2001
2041
|
to: tx.to,
|
|
2002
2042
|
data: tx.data || '0x',
|
|
2003
|
-
value: tx.value
|
|
2004
|
-
|
|
2043
|
+
value: tx.value
|
|
2044
|
+
? `0x${bignumber_1.BigNumber.from(tx.value).toHexString().slice(2)}`
|
|
2045
|
+
: '0x0',
|
|
2046
|
+
},
|
|
2047
|
+
]);
|
|
2005
2048
|
if (zkEstimate && zkEstimate.gas_limit) {
|
|
2006
2049
|
const gasLimit = bignumber_1.BigNumber.from(zkEstimate.gas_limit);
|
|
2007
2050
|
// Add 50% buffer for zkSync validation
|
|
@@ -2030,7 +2073,8 @@ class EthereumTransactions {
|
|
|
2030
2073
|
// First attempt: standard estimation
|
|
2031
2074
|
const estimated = await this.web3Provider.estimateGas(tx);
|
|
2032
2075
|
// Apply override if set
|
|
2033
|
-
if (this.gasOverrides.minGasLimit &&
|
|
2076
|
+
if (this.gasOverrides.minGasLimit &&
|
|
2077
|
+
estimated.lt(this.gasOverrides.minGasLimit)) {
|
|
2034
2078
|
return this.gasOverrides.minGasLimit;
|
|
2035
2079
|
}
|
|
2036
2080
|
// Add 20% buffer to the estimated gas
|
|
@@ -2046,7 +2090,7 @@ class EthereumTransactions {
|
|
|
2046
2090
|
const simpleEstimate = await this.web3Provider.estimateGas({
|
|
2047
2091
|
to: tx.to,
|
|
2048
2092
|
from: tx.from,
|
|
2049
|
-
value: tx.value || '0x0'
|
|
2093
|
+
value: tx.value || '0x0',
|
|
2050
2094
|
});
|
|
2051
2095
|
const withBuffer = simpleEstimate.mul(150).div(100); // 50% buffer for failed estimations
|
|
2052
2096
|
const minGas = this.gasOverrides.minGasLimit || bignumber_1.BigNumber.from('100000');
|
|
@@ -2108,28 +2152,30 @@ class EthereumTransactions {
|
|
|
2108
2152
|
return {
|
|
2109
2153
|
gasPrice: bufferedGasPrice,
|
|
2110
2154
|
maxFeePerGas: undefined,
|
|
2111
|
-
maxPriorityFeePerGas: undefined
|
|
2155
|
+
maxPriorityFeePerGas: undefined,
|
|
2112
2156
|
};
|
|
2113
2157
|
}
|
|
2114
2158
|
try {
|
|
2115
2159
|
// Try EIP-1559 fees first
|
|
2116
2160
|
const feeData = await this.getFeeDataWithDynamicMaxPriorityFeePerGas();
|
|
2117
2161
|
// If fees are zero or too low, fallback to legacy
|
|
2118
|
-
if (!feeData.maxFeePerGas ||
|
|
2119
|
-
|
|
2162
|
+
if (!feeData.maxFeePerGas ||
|
|
2163
|
+
feeData.maxFeePerGas.isZero() ||
|
|
2164
|
+
!feeData.maxPriorityFeePerGas ||
|
|
2165
|
+
feeData.maxPriorityFeePerGas.isZero()) {
|
|
2120
2166
|
console.log('EIP-1559 fees invalid, falling back to legacy gas price');
|
|
2121
2167
|
const gasPrice = await this.web3Provider.getGasPrice();
|
|
2122
2168
|
const bufferedGasPrice = gasPrice.mul(110).div(100);
|
|
2123
2169
|
return {
|
|
2124
2170
|
gasPrice: bufferedGasPrice,
|
|
2125
2171
|
maxFeePerGas: undefined,
|
|
2126
|
-
maxPriorityFeePerGas: undefined
|
|
2172
|
+
maxPriorityFeePerGas: undefined,
|
|
2127
2173
|
};
|
|
2128
2174
|
}
|
|
2129
2175
|
return {
|
|
2130
2176
|
gasPrice: undefined,
|
|
2131
2177
|
maxFeePerGas: feeData.maxFeePerGas,
|
|
2132
|
-
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas
|
|
2178
|
+
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
|
|
2133
2179
|
};
|
|
2134
2180
|
}
|
|
2135
2181
|
catch (error) {
|
|
@@ -2139,7 +2185,7 @@ class EthereumTransactions {
|
|
|
2139
2185
|
return {
|
|
2140
2186
|
gasPrice: bufferedGasPrice,
|
|
2141
2187
|
maxFeePerGas: undefined,
|
|
2142
|
-
maxPriorityFeePerGas: undefined
|
|
2188
|
+
maxPriorityFeePerGas: undefined,
|
|
2143
2189
|
};
|
|
2144
2190
|
}
|
|
2145
2191
|
};
|
|
@@ -2159,17 +2205,24 @@ class EthereumTransactions {
|
|
|
2159
2205
|
}
|
|
2160
2206
|
// Helper method to ensure providers are initialized when first needed
|
|
2161
2207
|
ensureProvidersInitialized() {
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2208
|
+
// Keep provider in sync with current network selection.
|
|
2209
|
+
// Hardware-wallet signing (e.g., Trezor) commits to a chainId; if the provider points at a different
|
|
2210
|
+
// RPC/network than `activeNetwork`, nodes will reject broadcasts with chain-id mismatch errors.
|
|
2211
|
+
try {
|
|
2212
|
+
const currentNetwork = this.getNetwork();
|
|
2213
|
+
const currentUrl = currentNetwork?.url;
|
|
2214
|
+
const currentKey = `${currentNetwork?.chainId ?? 'unknown'}|${currentUrl ?? ''}`;
|
|
2215
|
+
const needsInit = !this._web3Provider ||
|
|
2216
|
+
!this._web3ProviderKey ||
|
|
2217
|
+
(currentUrl && this._web3ProviderKey !== currentKey);
|
|
2218
|
+
if (needsInit) {
|
|
2166
2219
|
this.setWeb3Provider(currentNetwork);
|
|
2167
2220
|
}
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2221
|
+
}
|
|
2222
|
+
catch (error) {
|
|
2223
|
+
// If vault state not available yet, providers will be initialized later
|
|
2224
|
+
// when setWeb3Provider is called explicitly
|
|
2225
|
+
console.log('[EthereumTransactions] Deferring provider initialization:', error?.message || error);
|
|
2173
2226
|
}
|
|
2174
2227
|
}
|
|
2175
2228
|
// Helper method to detect UTXO networks
|
|
@@ -2208,17 +2261,23 @@ class EthereumTransactions {
|
|
|
2208
2261
|
console.log('[EthereumTransactions] setWeb3Provider: Skipping web3Provider creation for UTXO network:', network.url);
|
|
2209
2262
|
// Clear any existing providers for UTXO networks
|
|
2210
2263
|
this._web3Provider = undefined;
|
|
2264
|
+
this._web3ProviderKey = undefined;
|
|
2211
2265
|
}
|
|
2212
2266
|
else {
|
|
2213
2267
|
this._web3Provider = new providers_1.CustomJsonRpcProvider(this.abortController.signal, network.url);
|
|
2268
|
+
this._web3ProviderKey = `${network.chainId}|${network.url ?? ''}`;
|
|
2214
2269
|
}
|
|
2215
2270
|
}
|
|
2216
2271
|
// Method to configure gas overrides for networks with validation issues
|
|
2217
2272
|
setGasOverrides(overrides) {
|
|
2218
2273
|
this.gasOverrides = {
|
|
2219
|
-
minGasLimit: overrides.minGasLimit
|
|
2220
|
-
|
|
2221
|
-
|
|
2274
|
+
minGasLimit: overrides.minGasLimit
|
|
2275
|
+
? bignumber_1.BigNumber.from(overrides.minGasLimit)
|
|
2276
|
+
: undefined,
|
|
2277
|
+
minPriorityFee: overrides.minPriorityFee
|
|
2278
|
+
? bignumber_1.BigNumber.from(overrides.minPriorityFee)
|
|
2279
|
+
: undefined,
|
|
2280
|
+
feeMultiplier: overrides.feeMultiplier,
|
|
2222
2281
|
};
|
|
2223
2282
|
}
|
|
2224
2283
|
// Get the current gas overrides
|