@sidhujag/sysweb3-keyring 1.0.613 → 1.0.615
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/CHANGELOG.md +61 -0
- package/cjs/hardware-wallet-manager.js +3 -1
- package/cjs/hardware-wallet-manager.js.map +1 -1
- package/cjs/keyring-manager.js +3 -2
- package/cjs/keyring-manager.js.map +1 -1
- package/cjs/transactions/ethereum.js +174 -114
- package/cjs/transactions/ethereum.js.map +1 -1
- package/cjs/transactions/evm-local-signer.js +2 -1
- package/cjs/transactions/evm-local-signer.js.map +1 -1
- package/cjs/types.js.map +1 -1
- package/package.json +1 -1
- package/types/transactions/ethereum.d.ts +7 -4
- package/types/transactions/evm-local-signer.d.ts +1 -1
- package/types/types.d.ts +18 -2
|
@@ -7,6 +7,7 @@ exports.EthereumTransactions = void 0;
|
|
|
7
7
|
const eth_sig_util_1 = require("@metamask/eth-sig-util");
|
|
8
8
|
const sysweb3_network_1 = require("@sidhujag/sysweb3-network");
|
|
9
9
|
const sysweb3_utils_1 = require("@sidhujag/sysweb3-utils");
|
|
10
|
+
const transaction_1 = require("ethers/transaction");
|
|
10
11
|
const omit_1 = __importDefault(require("lodash/omit"));
|
|
11
12
|
const ethers_v6_1 = require("../ethers-v6");
|
|
12
13
|
const providers_1 = require("../providers");
|
|
@@ -427,18 +428,18 @@ class EthereumTransactions {
|
|
|
427
428
|
throw error;
|
|
428
429
|
}
|
|
429
430
|
};
|
|
430
|
-
this.getFeeDataWithDynamicMaxPriorityFeePerGas = async () => {
|
|
431
|
+
this.getFeeDataWithDynamicMaxPriorityFeePerGas = async (provider = this.web3Provider) => {
|
|
431
432
|
let maxFeePerGas = this.toBigNumber(0);
|
|
432
433
|
let maxPriorityFeePerGas = this.toBigNumber(0);
|
|
433
434
|
try {
|
|
434
435
|
// First, try to get the current gas price as a baseline
|
|
435
|
-
const currentGasPrice = await
|
|
436
|
-
const block = await
|
|
436
|
+
const currentGasPrice = await provider.getGasPrice();
|
|
437
|
+
const block = await provider.getBlock('latest');
|
|
437
438
|
if (block && block.baseFeePerGas != null) {
|
|
438
439
|
const baseFeePerGas = ethers_v6_1.BigNumber.from(block.baseFeePerGas);
|
|
439
440
|
try {
|
|
440
441
|
// Some networks don't support this RPC method
|
|
441
|
-
const ethMaxPriorityFee = await
|
|
442
|
+
const ethMaxPriorityFee = await provider.send('eth_maxPriorityFeePerGas', []);
|
|
442
443
|
maxPriorityFeePerGas = ethers_v6_1.BigNumber.from(ethMaxPriorityFee);
|
|
443
444
|
// Apply minimum priority fee override if set
|
|
444
445
|
if (this.gasOverrides.minPriorityFee &&
|
|
@@ -466,7 +467,7 @@ class EthereumTransactions {
|
|
|
466
467
|
// Use a more aggressive fallback strategy with higher priority fees
|
|
467
468
|
// Check if we can get fee history for better estimation
|
|
468
469
|
try {
|
|
469
|
-
const feeHistory = await
|
|
470
|
+
const feeHistory = await provider.send('eth_feeHistory', [
|
|
470
471
|
'0x5', // Last 5 blocks
|
|
471
472
|
'latest',
|
|
472
473
|
[25, 50, 75], // Percentiles for priority fees
|
|
@@ -499,7 +500,7 @@ class EthereumTransactions {
|
|
|
499
500
|
// If fee history fails, use current gas price as reference
|
|
500
501
|
console.warn('Fee history not available, using gas price based estimation');
|
|
501
502
|
// Use 10% of current gas price as priority fee
|
|
502
|
-
const currentGasPrice = await
|
|
503
|
+
const currentGasPrice = await provider.getGasPrice();
|
|
503
504
|
maxPriorityFeePerGas = currentGasPrice.mul(10).div(100);
|
|
504
505
|
// Ensure minimum of 1 gwei
|
|
505
506
|
const minPriority = ethers_v6_1.BigNumber.from('1000000000');
|
|
@@ -508,7 +509,7 @@ class EthereumTransactions {
|
|
|
508
509
|
}
|
|
509
510
|
}
|
|
510
511
|
// Calculate maxFeePerGas based on current network conditions
|
|
511
|
-
const currentGasPrice = await
|
|
512
|
+
const currentGasPrice = await provider.getGasPrice();
|
|
512
513
|
const baselineMaxFee = currentGasPrice.mul(120).div(100);
|
|
513
514
|
const calculatedMaxFee = baseFeePerGas
|
|
514
515
|
.mul(250)
|
|
@@ -1060,13 +1061,101 @@ class EthereumTransactions {
|
|
|
1060
1061
|
return await sendEVMTransaction();
|
|
1061
1062
|
}
|
|
1062
1063
|
};
|
|
1063
|
-
this.sendTransactionWithEditedFee = async (txHash, isLegacy) => {
|
|
1064
|
-
|
|
1064
|
+
this.sendTransactionWithEditedFee = async (txHash, isLegacy = false, options = {}) => {
|
|
1065
|
+
const { assertCurrentContext, validateOriginal, beforeBroadcast, approvedMaximumFee, } = options;
|
|
1066
|
+
const previewOnly = options.previewOnly === true;
|
|
1067
|
+
if (!previewOnly &&
|
|
1068
|
+
(typeof approvedMaximumFee !== 'string' ||
|
|
1069
|
+
!/^\d{1,78}$/.test(approvedMaximumFee))) {
|
|
1070
|
+
throw new Error('Replacement fee approval required');
|
|
1071
|
+
}
|
|
1072
|
+
const assertCurrent = () => assertCurrentContext?.();
|
|
1073
|
+
const assertBeforeBroadcast = () => {
|
|
1074
|
+
assertCurrent();
|
|
1075
|
+
beforeBroadcast?.();
|
|
1076
|
+
assertCurrent();
|
|
1077
|
+
};
|
|
1078
|
+
const assertSignedSender = (signedTx) => {
|
|
1079
|
+
if (transaction_1.Transaction.from(signedTx).from?.toLowerCase() !== expectedSender) {
|
|
1080
|
+
throw new Error('Replacement signature does not match account');
|
|
1081
|
+
}
|
|
1082
|
+
};
|
|
1083
|
+
assertCurrent();
|
|
1084
|
+
const state = this.getState();
|
|
1085
|
+
const activeAccountType = options.targetAccount?.type ?? state.activeAccountType;
|
|
1086
|
+
const activeAccountId = options.targetAccount?.id ?? state.activeAccountId;
|
|
1087
|
+
const targetAccount = options.targetAccount
|
|
1088
|
+
? { type: activeAccountType, id: activeAccountId }
|
|
1089
|
+
: undefined;
|
|
1090
|
+
const activeAccount = {
|
|
1091
|
+
...state.accounts?.[activeAccountType]?.[activeAccountId],
|
|
1092
|
+
};
|
|
1093
|
+
const activeNetwork = { ...state.activeNetwork };
|
|
1094
|
+
if (!activeAccount.address ||
|
|
1095
|
+
(targetAccount && activeAccountType === types_1.KeyringAccountType.SmartAccount)) {
|
|
1096
|
+
throw new Error('Replacement signing account is unavailable');
|
|
1097
|
+
}
|
|
1098
|
+
const expectedSender = activeAccount.address.toLowerCase();
|
|
1099
|
+
const requestedHash = txHash.toLowerCase();
|
|
1100
|
+
const provider = this.web3Provider;
|
|
1101
|
+
assertCurrent();
|
|
1102
|
+
const validateLookup = (transaction) => {
|
|
1103
|
+
assertCurrent();
|
|
1104
|
+
if (!transaction)
|
|
1105
|
+
return null;
|
|
1106
|
+
const fields = (0, ethers_v6_1.normalizeTransactionRequest)(transaction);
|
|
1107
|
+
if (fields.hash != null)
|
|
1108
|
+
fields.hash = fields.hash.toLowerCase();
|
|
1109
|
+
const type = fields.type ??
|
|
1110
|
+
(fields.maxFeePerGas != null ? 2 : fields.accessList != null ? 1 : 0);
|
|
1111
|
+
if (![0, 1, 2].includes(type)) {
|
|
1112
|
+
throw new Error('Unsupported replacement transaction type');
|
|
1113
|
+
}
|
|
1114
|
+
fields.signature = fields.signature ?? {
|
|
1115
|
+
r: fields.r,
|
|
1116
|
+
s: fields.s,
|
|
1117
|
+
v: fields.v ?? fields.yParity,
|
|
1118
|
+
};
|
|
1119
|
+
fields.type = type;
|
|
1120
|
+
fields.data = fields.data ?? fields.input ?? '0x';
|
|
1121
|
+
if (type === 2)
|
|
1122
|
+
delete fields.gasPrice; // Effective RPC gas price is not signed in type 2.
|
|
1123
|
+
const original = transaction_1.Transaction.from(fields);
|
|
1124
|
+
if (!original.signature ||
|
|
1125
|
+
original.hash !== requestedHash ||
|
|
1126
|
+
original.from?.toLowerCase() !== expectedSender ||
|
|
1127
|
+
original.chainId !== BigInt(activeNetwork.chainId)) {
|
|
1128
|
+
throw new Error('Original transaction is not authenticated');
|
|
1129
|
+
}
|
|
1130
|
+
if (type !== 1)
|
|
1131
|
+
isLegacy = type === 0;
|
|
1132
|
+
if (isLegacy &&
|
|
1133
|
+
type === 1 &&
|
|
1134
|
+
activeAccountType === types_1.KeyringAccountType.Trezor) {
|
|
1135
|
+
throw new Error('Trezor does not support type 1 replacement signing');
|
|
1136
|
+
}
|
|
1137
|
+
// Read only detached, authenticated signed fields after asynchronous work.
|
|
1138
|
+
const authenticated = (0, providers_1.wrapTransactionResponse)({
|
|
1139
|
+
...original.toJSON(),
|
|
1140
|
+
hash: original.hash,
|
|
1141
|
+
from: original.from,
|
|
1142
|
+
gasPrice: original.gasPrice ?? 0,
|
|
1143
|
+
maxFeePerGas: original.maxFeePerGas ?? 0,
|
|
1144
|
+
maxPriorityFeePerGas: original.maxPriorityFeePerGas ?? 0,
|
|
1145
|
+
signature: original.signature,
|
|
1146
|
+
blockNumber: transaction.blockNumber,
|
|
1147
|
+
});
|
|
1148
|
+
validateOriginal?.(authenticated);
|
|
1149
|
+
assertCurrent();
|
|
1150
|
+
return authenticated;
|
|
1151
|
+
};
|
|
1152
|
+
let tx = validateLookup(await provider.getTransaction(txHash));
|
|
1065
1153
|
if (!tx) {
|
|
1066
1154
|
// Retry a couple of times in case the node hasn't indexed the pending tx yet
|
|
1067
1155
|
for (let attempt = 0; attempt < 2 && !tx; attempt++) {
|
|
1068
1156
|
await new Promise((resolve) => setTimeout(resolve, 500 * (attempt + 1)));
|
|
1069
|
-
|
|
1157
|
+
assertCurrent();
|
|
1158
|
+
tx = validateLookup(await provider.getTransaction(txHash));
|
|
1070
1159
|
}
|
|
1071
1160
|
if (!tx) {
|
|
1072
1161
|
return {
|
|
@@ -1077,17 +1166,17 @@ class EthereumTransactions {
|
|
|
1077
1166
|
};
|
|
1078
1167
|
}
|
|
1079
1168
|
}
|
|
1080
|
-
const { activeAccountType, activeAccountId, accounts, activeNetwork } = this.getState();
|
|
1081
|
-
const activeAccount = accounts[activeAccountType][activeAccountId];
|
|
1082
1169
|
// Check if this might be a max send transaction by comparing total cost to balance
|
|
1083
|
-
const currentBalance = await
|
|
1170
|
+
const currentBalance = await provider.getBalance(activeAccount.address);
|
|
1171
|
+
assertCurrent();
|
|
1084
1172
|
// Ensure all transaction values are resolved from promises
|
|
1085
1173
|
const gasLimit = await Promise.resolve(tx.gasLimit);
|
|
1086
1174
|
const gasPrice = await Promise.resolve(tx.gasPrice || 0);
|
|
1087
|
-
const maxFeePerGas = await Promise.resolve(tx.
|
|
1088
|
-
const maxPriorityFeePerGas = await Promise.resolve(tx.
|
|
1175
|
+
const maxFeePerGas = await Promise.resolve(tx.type === 1 ? tx.gasPrice : tx.maxFeePerGas);
|
|
1176
|
+
const maxPriorityFeePerGas = await Promise.resolve(tx.type === 1 ? tx.gasPrice : tx.maxPriorityFeePerGas);
|
|
1089
1177
|
const txValue = await Promise.resolve(tx.value);
|
|
1090
1178
|
const txData = await Promise.resolve(tx.data || '0x');
|
|
1179
|
+
assertCurrent();
|
|
1091
1180
|
// Check if this is a contract call (has data)
|
|
1092
1181
|
const isContractCall = txData && txData !== '0x' && txData.length > 2;
|
|
1093
1182
|
const originalGasCost = isLegacy
|
|
@@ -1097,113 +1186,73 @@ class EthereumTransactions {
|
|
|
1097
1186
|
// If original transaction used >95% of balance, it's likely a max send
|
|
1098
1187
|
const balanceThreshold = currentBalance.mul(95).div(100);
|
|
1099
1188
|
const isLikelyMaxSend = originalTotalCost.gt(balanceThreshold);
|
|
1100
|
-
let txWithEditedFee;
|
|
1101
|
-
// If the original tx has 0 or very low gas price, fetch current network gas prices
|
|
1102
1189
|
const oldTxsGasValues = {
|
|
1103
1190
|
maxFeePerGas: maxFeePerGas,
|
|
1104
1191
|
maxPriorityFeePerGas: maxPriorityFeePerGas,
|
|
1105
1192
|
gasPrice: gasPrice,
|
|
1106
1193
|
gasLimit: gasLimit,
|
|
1107
1194
|
};
|
|
1108
|
-
//
|
|
1109
|
-
//
|
|
1110
|
-
if (isLegacy) {
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1195
|
+
// A zero-fee original may need a current estimate; the preview shows it
|
|
1196
|
+
// and the final candidate must stay within the user's approved ceiling.
|
|
1197
|
+
if (isLegacy && oldTxsGasValues.gasPrice.isZero()) {
|
|
1198
|
+
oldTxsGasValues.gasPrice = await provider.getGasPrice();
|
|
1199
|
+
assertCurrent();
|
|
1200
|
+
}
|
|
1201
|
+
else if (!isLegacy && oldTxsGasValues.maxFeePerGas.isZero()) {
|
|
1202
|
+
const feeData = await this.getFeeDataWithDynamicMaxPriorityFeePerGas(provider);
|
|
1203
|
+
assertCurrent();
|
|
1204
|
+
oldTxsGasValues.maxFeePerGas = ethers_v6_1.BigNumber.from(feeData.maxFeePerGas || 0);
|
|
1205
|
+
oldTxsGasValues.maxPriorityFeePerGas = ethers_v6_1.BigNumber.from(feeData.maxPriorityFeePerGas || 0);
|
|
1206
|
+
}
|
|
1207
|
+
const newGasValues = this.calculateNewGasValues(oldTxsGasValues, false, isLegacy);
|
|
1208
|
+
if (!newGasValues.gasLimit.gt(0))
|
|
1209
|
+
throw new Error('Invalid replacement gas limit');
|
|
1210
|
+
if (!isLegacy &&
|
|
1211
|
+
newGasValues.maxPriorityFeePerGas.gt(newGasValues.maxFeePerGas))
|
|
1212
|
+
throw new Error('Invalid replacement fee');
|
|
1213
|
+
const maximumFee = newGasValues.gasLimit.mul(isLegacy ? newGasValues.gasPrice : newGasValues.maxFeePerGas);
|
|
1214
|
+
let adjustedValue = txValue;
|
|
1215
|
+
if (isLikelyMaxSend && txValue.add(maximumFee).gt(currentBalance)) {
|
|
1216
|
+
if (isContractCall) {
|
|
1217
|
+
console.error('[SpeedUp] Cannot adjust value for contract call - rejecting speedup');
|
|
1218
|
+
return {
|
|
1219
|
+
isSpeedUp: false,
|
|
1220
|
+
error: true,
|
|
1221
|
+
code: 'CONTRACT_CALL_MAX_SEND',
|
|
1222
|
+
message: 'Cannot speed up a likely max-send contract call; value cannot be adjusted to fit new gas',
|
|
1223
|
+
};
|
|
1125
1224
|
}
|
|
1225
|
+
adjustedValue = currentBalance.gt(maximumFee)
|
|
1226
|
+
? currentBalance.sub(maximumFee)
|
|
1227
|
+
: ethers_v6_1.Zero;
|
|
1126
1228
|
}
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
// For non-contract calls, reduce value to fit within balance (clamp at zero)
|
|
1148
|
-
adjustedValue = currentBalance.gt(newGasCost)
|
|
1149
|
-
? currentBalance.sub(newGasCost)
|
|
1150
|
-
: ethers_v6_1.Zero;
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
|
-
txWithEditedFee = {
|
|
1154
|
-
from: tx.from,
|
|
1155
|
-
to: tx.to,
|
|
1156
|
-
nonce: tx.nonce,
|
|
1157
|
-
value: adjustedValue,
|
|
1158
|
-
data: txData,
|
|
1159
|
-
maxFeePerGas: newGasValues.maxFeePerGas,
|
|
1160
|
-
maxPriorityFeePerGas: newGasValues.maxPriorityFeePerGas,
|
|
1161
|
-
gasLimit: newGasValues.gasLimit,
|
|
1162
|
-
// Don't set type - let ethers auto-detect for EIP-1559
|
|
1163
|
-
};
|
|
1164
|
-
}
|
|
1165
|
-
else {
|
|
1166
|
-
const newGasValues = this.calculateNewGasValues(oldTxsGasValues, false, true);
|
|
1167
|
-
let adjustedValue = txValue;
|
|
1168
|
-
// For likely max sends, check if we need to adjust value
|
|
1169
|
-
if (isLikelyMaxSend && newGasValues.gasLimit && newGasValues.gasPrice) {
|
|
1170
|
-
const newGasCost = newGasValues.gasLimit.mul(newGasValues.gasPrice);
|
|
1171
|
-
const newTotalCost = txValue.add(newGasCost);
|
|
1172
|
-
if (newTotalCost.gt(currentBalance)) {
|
|
1173
|
-
// If this is a contract call, we cannot adjust the value
|
|
1174
|
-
if (isContractCall) {
|
|
1175
|
-
console.error('[SpeedUp] Cannot adjust value for contract call - rejecting speedup');
|
|
1176
|
-
return {
|
|
1177
|
-
isSpeedUp: false,
|
|
1178
|
-
error: true,
|
|
1179
|
-
code: 'CONTRACT_CALL_MAX_SEND',
|
|
1180
|
-
message: 'Cannot speed up a likely max-send contract call; value cannot be adjusted to fit new gas',
|
|
1181
|
-
};
|
|
1182
|
-
}
|
|
1183
|
-
// For non-contract calls, reduce value to fit within balance (clamp at zero)
|
|
1184
|
-
adjustedValue = currentBalance.gt(newGasCost)
|
|
1185
|
-
? currentBalance.sub(newGasCost)
|
|
1186
|
-
: ethers_v6_1.Zero;
|
|
1187
|
-
}
|
|
1188
|
-
}
|
|
1189
|
-
txWithEditedFee = {
|
|
1190
|
-
from: tx.from,
|
|
1191
|
-
to: tx.to,
|
|
1192
|
-
nonce: tx.nonce,
|
|
1193
|
-
value: adjustedValue,
|
|
1194
|
-
data: txData,
|
|
1195
|
-
gasLimit: newGasValues.gasLimit,
|
|
1196
|
-
gasPrice: newGasValues.gasPrice,
|
|
1197
|
-
type: 0, // Force Type 0 for legacy speedup
|
|
1198
|
-
};
|
|
1199
|
-
}
|
|
1229
|
+
const txWithEditedFee = {
|
|
1230
|
+
chainId: activeNetwork.chainId,
|
|
1231
|
+
from: tx.from,
|
|
1232
|
+
to: tx.to,
|
|
1233
|
+
nonce: tx.nonce,
|
|
1234
|
+
value: adjustedValue,
|
|
1235
|
+
data: txData,
|
|
1236
|
+
gasLimit: newGasValues.gasLimit,
|
|
1237
|
+
...(tx.accessList != null ? { accessList: tx.accessList } : {}),
|
|
1238
|
+
...(isLegacy
|
|
1239
|
+
? { gasPrice: newGasValues.gasPrice, type: tx.type === 1 ? 1 : 0 }
|
|
1240
|
+
: {
|
|
1241
|
+
maxFeePerGas: newGasValues.maxFeePerGas,
|
|
1242
|
+
maxPriorityFeePerGas: newGasValues.maxPriorityFeePerGas,
|
|
1243
|
+
}),
|
|
1244
|
+
};
|
|
1245
|
+
if (previewOnly)
|
|
1246
|
+
return { isSpeedUp: false, maximumFee: maximumFee.toString() };
|
|
1247
|
+
if (maximumFee.gt(approvedMaximumFee))
|
|
1248
|
+
throw new Error('Replacement fee exceeds approval');
|
|
1200
1249
|
// Ledger speedup handler
|
|
1201
1250
|
const speedUpWithLedger = async () => {
|
|
1202
1251
|
try {
|
|
1203
1252
|
const resolvedParams = await (0, ethers_v6_1.resolveProperties)((0, omit_1.default)(txWithEditedFee, 'from'));
|
|
1204
1253
|
const formatParams = {
|
|
1205
1254
|
...resolvedParams,
|
|
1206
|
-
nonce: resolvedParams.nonce
|
|
1255
|
+
nonce: resolvedParams.nonce != null
|
|
1207
1256
|
? Number(resolvedParams.nonce.toString())
|
|
1208
1257
|
: undefined,
|
|
1209
1258
|
};
|
|
@@ -1211,7 +1260,7 @@ class EthereumTransactions {
|
|
|
1211
1260
|
? {
|
|
1212
1261
|
...formatParams,
|
|
1213
1262
|
chainId: activeNetwork.chainId,
|
|
1214
|
-
type:
|
|
1263
|
+
type: txWithEditedFee.type,
|
|
1215
1264
|
}
|
|
1216
1265
|
: {
|
|
1217
1266
|
...formatParams,
|
|
@@ -1219,6 +1268,7 @@ class EthereumTransactions {
|
|
|
1219
1268
|
type: 2, // Need explicit type for hardware wallet serialization
|
|
1220
1269
|
};
|
|
1221
1270
|
const rawTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers);
|
|
1271
|
+
assertCurrent();
|
|
1222
1272
|
const signature = await this.ledgerSigner.evm.signEVMTransaction({
|
|
1223
1273
|
rawTx: rawTx.replace('0x', ''),
|
|
1224
1274
|
accountIndex: activeAccountId,
|
|
@@ -1230,7 +1280,9 @@ class EthereumTransactions {
|
|
|
1230
1280
|
};
|
|
1231
1281
|
if (signature) {
|
|
1232
1282
|
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForEthers, formattedSignature);
|
|
1233
|
-
|
|
1283
|
+
assertSignedSender(signedTx);
|
|
1284
|
+
assertBeforeBroadcast();
|
|
1285
|
+
const transactionResponse = await provider.sendTransaction(signedTx);
|
|
1234
1286
|
return {
|
|
1235
1287
|
isSpeedUp: true,
|
|
1236
1288
|
transaction: transactionResponse,
|
|
@@ -1276,7 +1328,7 @@ class EthereumTransactions {
|
|
|
1276
1328
|
: this.toHex0x(formattedTx.value, 'value'),
|
|
1277
1329
|
nonce: this.toHex0x(formattedTx.nonce, 'nonce'),
|
|
1278
1330
|
chainId: activeNetwork.chainId,
|
|
1279
|
-
type: isLegacy ?
|
|
1331
|
+
type: isLegacy ? txWithEditedFee.type : 2,
|
|
1280
1332
|
};
|
|
1281
1333
|
if (formattedTx.data && formattedTx.data !== '0x') {
|
|
1282
1334
|
txFormattedForTrezor.data = formattedTx.data;
|
|
@@ -1297,6 +1349,7 @@ class EthereumTransactions {
|
|
|
1297
1349
|
? formattedTx.maxPriorityFeePerGas
|
|
1298
1350
|
: this.toHex0x(formattedTx.maxPriorityFeePerGas, 'maxPriorityFeePerGas');
|
|
1299
1351
|
}
|
|
1352
|
+
assertCurrent();
|
|
1300
1353
|
const signature = await this.trezorSigner.signEthTransaction({
|
|
1301
1354
|
coin: trezorCoin,
|
|
1302
1355
|
tx: txFormattedForTrezor,
|
|
@@ -1305,7 +1358,9 @@ class EthereumTransactions {
|
|
|
1305
1358
|
});
|
|
1306
1359
|
if (signature.success) {
|
|
1307
1360
|
const signedTx = (0, ethers_v6_1.serializeTransaction)(txFormattedForTrezor, signature.payload);
|
|
1308
|
-
|
|
1361
|
+
assertSignedSender(signedTx);
|
|
1362
|
+
assertBeforeBroadcast();
|
|
1363
|
+
const transactionResponse = await provider.sendTransaction(signedTx);
|
|
1309
1364
|
return {
|
|
1310
1365
|
isSpeedUp: true,
|
|
1311
1366
|
transaction: transactionResponse,
|
|
@@ -1339,8 +1394,13 @@ class EthereumTransactions {
|
|
|
1339
1394
|
// Regular wallet speedup handler
|
|
1340
1395
|
const speedUpWithPrivateKey = async () => {
|
|
1341
1396
|
try {
|
|
1342
|
-
|
|
1343
|
-
const
|
|
1397
|
+
assertCurrent();
|
|
1398
|
+
const { address, decryptedPrivateKey } = this.getDecryptedPrivateKey(targetAccount);
|
|
1399
|
+
assertCurrent();
|
|
1400
|
+
if (address.toLowerCase() !== expectedSender) {
|
|
1401
|
+
throw new Error('Replacement signing account changed');
|
|
1402
|
+
}
|
|
1403
|
+
const transactionResponse = await (0, evm_local_signer_1.sendLocalEvmTransaction)(provider, decryptedPrivateKey, txWithEditedFee, assertBeforeBroadcast, assertCurrent);
|
|
1344
1404
|
if (transactionResponse) {
|
|
1345
1405
|
return {
|
|
1346
1406
|
isSpeedUp: true,
|