@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.
@@ -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 && maxPriorityFeePerGas.lt(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.mul(multiplier).div(100).add(maxPriorityFeePerGas);
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) ? calculatedMaxFee : 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 && feeHistory.reward && feeHistory.reward.length > 0) {
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.mul(250).div(100).add(maxPriorityFeePerGas);
473
- maxFeePerGas = calculatedMaxFee.gt(baselineMaxFee) ? calculatedMaxFee : baselineMaxFee;
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 { maxFeePerGas: bignumber_1.BigNumber.from(0), maxPriorityFeePerGas: bignumber_1.BigNumber.from(0) };
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.toBigNumber(String(formattedTx.gasLimit || 0))._hex,
723
+ : this.toHex0x(formattedTx.gasLimit, 'gasLimit'),
685
724
  value: '0x0',
686
- nonce: this.toBigNumber(String(formattedTx.nonce || 0))._hex,
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.toBigNumber(String(formattedTx.gasPrice || 0))._hex;
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
- : `${formattedTx.maxFeePerGas?._hex ||
701
- formattedTx.maxFeePerGas}`;
739
+ : this.toHex0x(formattedTx.maxFeePerGas, 'maxFeePerGas');
702
740
  txFormattedForTrezor.maxPriorityFeePerGas =
703
741
  typeof formattedTx.maxPriorityFeePerGas === 'string'
704
742
  ? formattedTx.maxPriorityFeePerGas
705
- : `${formattedTx.maxPriorityFeePerGas?._hex ||
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 || bignumber_1.BigNumber.from(params.gasLimit).lt(bignumber_1.BigNumber.from('500000'))) {
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 ? bignumber_1.BigNumber.from(params.gasPrice) : await this.web3Provider.getGasPrice();
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 && !isLegacy && params.maxFeePerGas && params.maxPriorityFeePerGas) {
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: typeof formatParams.gasLimit === 'string'
885
- ? formatParams.gasLimit
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: typeof formatParams.gasLimit === 'string'
901
- ? formatParams.gasLimit
902
- : // @ts-ignore
903
- `${params.gasLimit.hex}`,
904
- maxFeePerGas: typeof formatParams.maxFeePerGas === 'string'
905
- ? formatParams.maxFeePerGas
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: typeof formatParams.gasLimit === 'string'
925
- ? formatParams.gasLimit
926
- : // @ts-ignore
927
- `${params.gasLimit.hex}`,
928
- maxFeePerGas: typeof formatParams.maxFeePerGas === 'string'
929
- ? formatParams.maxFeePerGas
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.toBigNumber(String(formattedTx.gasLimit || 0))._hex,
1268
+ : this.toHex0x(formattedTx.gasLimit, 'gasLimit'),
1228
1269
  value: typeof formattedTx.value === 'string'
1229
1270
  ? formattedTx.value
1230
- : this.toBigNumber(String(formattedTx.value || 0))._hex,
1231
- nonce: this.toBigNumber(String(formattedTx.nonce || 0))._hex,
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.toBigNumber(String(formattedTx.gasPrice || 0))._hex;
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
- : `${formattedTx.maxFeePerGas?._hex ||
1249
- formattedTx.maxFeePerGas}`;
1289
+ : this.toHex0x(formattedTx.maxFeePerGas, 'maxFeePerGas');
1250
1290
  txFormattedForTrezor.maxPriorityFeePerGas =
1251
1291
  typeof formattedTx.maxPriorityFeePerGas === 'string'
1252
1292
  ? formattedTx.maxPriorityFeePerGas
1253
- : `${formattedTx.maxPriorityFeePerGas?._hex ||
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 ? `0x${bignumber_1.BigNumber.from(tx.value).toHexString().slice(2)}` : '0x0'
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 && estimated.lt(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 || feeData.maxFeePerGas.isZero() ||
2119
- !feeData.maxPriorityFeePerGas || feeData.maxPriorityFeePerGas.isZero()) {
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
- if (!this._web3Provider) {
2163
- // Providers not initialized yet, initialize them now
2164
- try {
2165
- const currentNetwork = this.getNetwork();
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
- catch (error) {
2169
- // If vault state not available yet, providers will be initialized later
2170
- // when setWeb3Provider is called explicitly
2171
- console.log('[EthereumTransactions] Deferring provider initialization:', error.message);
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 ? bignumber_1.BigNumber.from(overrides.minGasLimit) : undefined,
2220
- minPriorityFee: overrides.minPriorityFee ? bignumber_1.BigNumber.from(overrides.minPriorityFee) : undefined,
2221
- feeMultiplier: overrides.feeMultiplier
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