@metamask-previews/transaction-controller 9.1.0-preview.04c2e62 → 9.2.0-preview.a8d97a1
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 +7 -1
- package/dist/EtherscanRemoteTransactionSource.d.ts +1 -1
- package/dist/EtherscanRemoteTransactionSource.d.ts.map +1 -1
- package/dist/EtherscanRemoteTransactionSource.js +9 -9
- package/dist/EtherscanRemoteTransactionSource.js.map +1 -1
- package/dist/IncomingTransactionHelper.d.ts.map +1 -1
- package/dist/IncomingTransactionHelper.js +2 -7
- package/dist/IncomingTransactionHelper.js.map +1 -1
- package/dist/TransactionController.d.ts +54 -6
- package/dist/TransactionController.d.ts.map +1 -1
- package/dist/TransactionController.js +195 -65
- package/dist/TransactionController.js.map +1 -1
- package/dist/constants.d.ts +0 -19
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +0 -19
- package/dist/constants.js.map +1 -1
- package/dist/external-transactions.d.ts +10 -0
- package/dist/external-transactions.d.ts.map +1 -0
- package/dist/external-transactions.js +36 -0
- package/dist/external-transactions.js.map +1 -0
- package/dist/types.d.ts +32 -9
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/dist/utils.d.ts +5 -6
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +7 -8
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
|
@@ -26,6 +26,7 @@ const events_1 = require("events");
|
|
|
26
26
|
const nonce_tracker_1 = __importDefault(require("nonce-tracker"));
|
|
27
27
|
const uuid_1 = require("uuid");
|
|
28
28
|
const EtherscanRemoteTransactionSource_1 = require("./EtherscanRemoteTransactionSource");
|
|
29
|
+
const external_transactions_1 = require("./external-transactions");
|
|
29
30
|
const IncomingTransactionHelper_1 = require("./IncomingTransactionHelper");
|
|
30
31
|
const types_1 = require("./types");
|
|
31
32
|
const utils_1 = require("./utils");
|
|
@@ -176,22 +177,24 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
176
177
|
*
|
|
177
178
|
* @param transaction - The transaction object to add.
|
|
178
179
|
* @param opts - Additional options to control how the transaction is added.
|
|
180
|
+
* @param opts.actionId - Unique ID to prevent duplicate requests.
|
|
179
181
|
* @param opts.deviceConfirmedOn - An enum to indicate what device confirmed the transaction.
|
|
180
182
|
* @param opts.origin - The origin of the transaction request, such as a dApp hostname.
|
|
181
183
|
* @param opts.requireApproval - Whether the transaction requires approval by the user, defaults to true unless explicitly disabled.
|
|
182
184
|
* @param opts.securityAlertResponse - Response from security validator.
|
|
183
185
|
* @returns Object containing a promise resolving to the transaction hash if approved.
|
|
184
186
|
*/
|
|
185
|
-
addTransaction(transaction, { deviceConfirmedOn, origin, requireApproval, securityAlertResponse, } = {}) {
|
|
187
|
+
addTransaction(transaction, { actionId, deviceConfirmedOn, origin, requireApproval, securityAlertResponse, } = {}) {
|
|
186
188
|
return __awaiter(this, void 0, void 0, function* () {
|
|
187
|
-
const
|
|
189
|
+
const chainId = this.getChainId();
|
|
188
190
|
const { transactions } = this.state;
|
|
189
191
|
transaction = (0, utils_1.normalizeTransaction)(transaction);
|
|
190
192
|
(0, utils_1.validateTransaction)(transaction);
|
|
191
193
|
const dappSuggestedGasFees = this.generateDappSuggestedGasFees(transaction, origin);
|
|
192
|
-
const
|
|
194
|
+
const existingTransactionMeta = this.getTransactionWithActionId(actionId);
|
|
195
|
+
// If a request to add a transaction with the same actionId is submitted again, a new transaction will not be created for it.
|
|
196
|
+
const transactionMeta = existingTransactionMeta || {
|
|
193
197
|
id: (0, uuid_1.v1)(),
|
|
194
|
-
networkID: networkId !== null && networkId !== void 0 ? networkId : undefined,
|
|
195
198
|
chainId,
|
|
196
199
|
origin,
|
|
197
200
|
status: types_1.TransactionStatus.unapproved,
|
|
@@ -201,6 +204,8 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
201
204
|
verifiedOnBlockchain: false,
|
|
202
205
|
dappSuggestedGasFees,
|
|
203
206
|
securityAlertResponse,
|
|
207
|
+
// Add actionId to txMeta to check if same actionId is seen again
|
|
208
|
+
actionId,
|
|
204
209
|
};
|
|
205
210
|
try {
|
|
206
211
|
const { gas, estimateGasError } = yield this.estimateGas(transaction);
|
|
@@ -211,11 +216,17 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
211
216
|
this.failTransaction(transactionMeta, error);
|
|
212
217
|
return Promise.reject(error);
|
|
213
218
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
219
|
+
// Checks if a transaction already exists with a given actionId
|
|
220
|
+
if (!existingTransactionMeta) {
|
|
221
|
+
transactions.push(transactionMeta);
|
|
222
|
+
this.update({
|
|
223
|
+
transactions: this.trimTransactionsForState(transactions),
|
|
224
|
+
});
|
|
225
|
+
this.hub.emit(`unapprovedTransaction`, transactionMeta);
|
|
226
|
+
}
|
|
217
227
|
return {
|
|
218
228
|
result: this.processApproval(transactionMeta, {
|
|
229
|
+
isExisting: Boolean(existingTransactionMeta),
|
|
219
230
|
requireApproval,
|
|
220
231
|
}),
|
|
221
232
|
transactionMeta,
|
|
@@ -237,9 +248,9 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
237
248
|
* Creates approvals for all unapproved transactions persisted.
|
|
238
249
|
*/
|
|
239
250
|
initApprovals() {
|
|
240
|
-
const
|
|
251
|
+
const chainId = this.getChainId();
|
|
241
252
|
const unapprovedTxs = this.state.transactions.filter((transaction) => transaction.status === types_1.TransactionStatus.unapproved &&
|
|
242
|
-
(0, utils_1.
|
|
253
|
+
(0, utils_1.transactionMatchesChainId)(transaction, chainId));
|
|
243
254
|
for (const txMeta of unapprovedTxs) {
|
|
244
255
|
this.processApproval(txMeta, {
|
|
245
256
|
shouldShowRequest: false,
|
|
@@ -255,8 +266,10 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
255
266
|
*
|
|
256
267
|
* @param transactionID - The ID of the transaction to cancel.
|
|
257
268
|
* @param gasValues - The gas values to use for the cancellation transaction.
|
|
269
|
+
* @param options - The options for the cancellation transaction.
|
|
270
|
+
* @param options.estimatedBaseFee - The estimated base fee of the transaction.
|
|
258
271
|
*/
|
|
259
|
-
stopTransaction(transactionID, gasValues) {
|
|
272
|
+
stopTransaction(transactionID, gasValues, { estimatedBaseFee } = {}) {
|
|
260
273
|
var _a, _b;
|
|
261
274
|
return __awaiter(this, void 0, void 0, function* () {
|
|
262
275
|
if (gasValues) {
|
|
@@ -310,8 +323,9 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
310
323
|
};
|
|
311
324
|
const unsignedEthTx = this.prepareUnsignedEthTx(txParams);
|
|
312
325
|
const signedTx = yield this.sign(unsignedEthTx, transactionMeta.transaction.from);
|
|
313
|
-
const
|
|
314
|
-
yield (0, controller_utils_1.query)(this.ethQuery, 'sendRawTransaction', [
|
|
326
|
+
const rawTx = (0, ethereumjs_util_1.bufferToHex)(signedTx.serialize());
|
|
327
|
+
yield (0, controller_utils_1.query)(this.ethQuery, 'sendRawTransaction', [rawTx]);
|
|
328
|
+
transactionMeta.estimatedBaseFee = estimatedBaseFee;
|
|
315
329
|
transactionMeta.status = types_1.TransactionStatus.cancelled;
|
|
316
330
|
this.hub.emit(`${transactionMeta.id}:finished`, transactionMeta);
|
|
317
331
|
});
|
|
@@ -320,11 +334,18 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
320
334
|
* Attempts to speed up a transaction increasing transaction gasPrice by ten percent.
|
|
321
335
|
*
|
|
322
336
|
* @param transactionID - The ID of the transaction to speed up.
|
|
323
|
-
* @param gasValues - The gas values to use for the speed up
|
|
337
|
+
* @param gasValues - The gas values to use for the speed up transaction.
|
|
338
|
+
* @param options - The options for the speed up transaction.
|
|
339
|
+
* @param options.actionId - Unique ID to prevent duplicate requests
|
|
340
|
+
* @param options.estimatedBaseFee - The estimated base fee of the transaction.
|
|
324
341
|
*/
|
|
325
|
-
speedUpTransaction(transactionID, gasValues) {
|
|
342
|
+
speedUpTransaction(transactionID, gasValues, { actionId, estimatedBaseFee, } = {}) {
|
|
326
343
|
var _a, _b;
|
|
327
344
|
return __awaiter(this, void 0, void 0, function* () {
|
|
345
|
+
// If transaction is found for same action id, do not create a new speed up transaction.
|
|
346
|
+
if (this.getTransactionWithActionId(actionId)) {
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
328
349
|
if (gasValues) {
|
|
329
350
|
(0, utils_1.validateGasValues)(gasValues);
|
|
330
351
|
}
|
|
@@ -362,11 +383,12 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
362
383
|
? Object.assign(Object.assign({}, transactionMeta.transaction), { gasLimit: transactionMeta.transaction.gas, maxFeePerGas: newMaxFeePerGas, maxPriorityFeePerGas: newMaxPriorityFeePerGas, type: 2 }) : Object.assign(Object.assign({}, transactionMeta.transaction), { gasLimit: transactionMeta.transaction.gas, gasPrice: newGasPrice });
|
|
363
384
|
const unsignedEthTx = this.prepareUnsignedEthTx(txParams);
|
|
364
385
|
const signedTx = yield this.sign(unsignedEthTx, transactionMeta.transaction.from);
|
|
365
|
-
const
|
|
386
|
+
const rawTx = (0, ethereumjs_util_1.bufferToHex)(signedTx.serialize());
|
|
366
387
|
const transactionHash = yield (0, controller_utils_1.query)(this.ethQuery, 'sendRawTransaction', [
|
|
367
|
-
|
|
388
|
+
rawTx,
|
|
368
389
|
]);
|
|
369
|
-
const baseTransactionMeta = Object.assign(Object.assign({}, transactionMeta), { id: (0, uuid_1.v1)(), time: Date.now(), transactionHash
|
|
390
|
+
const baseTransactionMeta = Object.assign(Object.assign({}, transactionMeta), { estimatedBaseFee, id: (0, uuid_1.v1)(), time: Date.now(), transactionHash,
|
|
391
|
+
actionId });
|
|
370
392
|
const newTransactionMeta = newMaxFeePerGas && newMaxPriorityFeePerGas
|
|
371
393
|
? Object.assign(Object.assign({}, baseTransactionMeta), { transaction: Object.assign(Object.assign({}, transactionMeta.transaction), { maxFeePerGas: newMaxFeePerGas, maxPriorityFeePerGas: newMaxPriorityFeePerGas }) }) : Object.assign(Object.assign({}, baseTransactionMeta), { transaction: Object.assign(Object.assign({}, transactionMeta.transaction), { gasPrice: newGasPrice }) });
|
|
372
394
|
transactions.push(newTransactionMeta);
|
|
@@ -452,14 +474,11 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
452
474
|
queryTransactionStatuses() {
|
|
453
475
|
return __awaiter(this, void 0, void 0, function* () {
|
|
454
476
|
const { transactions } = this.state;
|
|
455
|
-
const
|
|
477
|
+
const currentChainId = this.getChainId();
|
|
456
478
|
let gotUpdates = false;
|
|
457
479
|
yield (0, controller_utils_1.safelyExecute)(() => Promise.all(transactions.map((meta, index) => __awaiter(this, void 0, void 0, function* () {
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
const txBelongsToCurrentChain = meta.chainId === currentChainId ||
|
|
461
|
-
(!meta.chainId && meta.networkID === currentNetworkID);
|
|
462
|
-
if (!meta.verifiedOnBlockchain && txBelongsToCurrentChain) {
|
|
480
|
+
if (!meta.verifiedOnBlockchain &&
|
|
481
|
+
(0, utils_1.transactionMatchesChainId)(meta, currentChainId)) {
|
|
463
482
|
const [reconciledTx, updateRequired] = yield this.blockchainTransactionStateReconciler(meta);
|
|
464
483
|
if (updateRequired) {
|
|
465
484
|
transactions[index] = reconciledTx;
|
|
@@ -502,13 +521,10 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
502
521
|
this.update({ transactions: [] });
|
|
503
522
|
return;
|
|
504
523
|
}
|
|
505
|
-
const
|
|
506
|
-
const newTransactions = this.state.transactions.filter(({
|
|
524
|
+
const currentChainId = this.getChainId();
|
|
525
|
+
const newTransactions = this.state.transactions.filter(({ chainId, transaction }) => {
|
|
507
526
|
var _a;
|
|
508
|
-
|
|
509
|
-
const isMatchingNetwork = ignoreNetwork ||
|
|
510
|
-
chainId === currentChainId ||
|
|
511
|
-
(!chainId && networkID === currentNetworkID);
|
|
527
|
+
const isMatchingNetwork = ignoreNetwork || chainId === currentChainId;
|
|
512
528
|
if (!isMatchingNetwork) {
|
|
513
529
|
return true;
|
|
514
530
|
}
|
|
@@ -525,35 +541,70 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
525
541
|
stopIncomingTransactionProcessing() {
|
|
526
542
|
this.incomingTransactionHelper.stop();
|
|
527
543
|
}
|
|
528
|
-
|
|
544
|
+
/**
|
|
545
|
+
* Adds external provided transaction to state as confirmed transaction.
|
|
546
|
+
*
|
|
547
|
+
* @param transactionMeta - TransactionMeta to add transactions.
|
|
548
|
+
* @param transactionReceipt - TransactionReceipt of the external transaction.
|
|
549
|
+
* @param baseFeePerGas - Base fee per gas of the external transaction.
|
|
550
|
+
*/
|
|
551
|
+
confirmExternalTransaction(transactionMeta, transactionReceipt, baseFeePerGas) {
|
|
529
552
|
return __awaiter(this, void 0, void 0, function* () {
|
|
530
|
-
|
|
531
|
-
|
|
553
|
+
// Run validation and add external transaction to state.
|
|
554
|
+
this.addExternalTransaction(transactionMeta);
|
|
532
555
|
try {
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
const { meta, isCompleted } = this.isTransactionCompleted(transactionId);
|
|
540
|
-
if (meta && !isCompleted) {
|
|
541
|
-
yield this.approveTransaction(transactionId);
|
|
556
|
+
const transactionId = transactionMeta.id;
|
|
557
|
+
// Make sure status is confirmed and define gasUsed as in receipt.
|
|
558
|
+
transactionMeta.status = types_1.TransactionStatus.confirmed;
|
|
559
|
+
transactionMeta.txReceipt = transactionReceipt;
|
|
560
|
+
if (baseFeePerGas) {
|
|
561
|
+
transactionMeta.baseFeePerGas = baseFeePerGas;
|
|
542
562
|
}
|
|
563
|
+
// Update same nonce local transactions as dropped and define replacedBy properties.
|
|
564
|
+
this.markNonceDuplicatesDropped(transactionId);
|
|
565
|
+
// Update external provided transaction with updated gas values and confirmed status.
|
|
566
|
+
this.updateTransaction(transactionMeta);
|
|
543
567
|
}
|
|
544
568
|
catch (error) {
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
569
|
+
console.error(error);
|
|
570
|
+
}
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
processApproval(transactionMeta, { isExisting = false, requireApproval, shouldShowRequest = true, }) {
|
|
574
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
575
|
+
const transactionId = transactionMeta.id;
|
|
576
|
+
let resultCallbacks;
|
|
577
|
+
const { meta, isCompleted } = this.isTransactionCompleted(transactionId);
|
|
578
|
+
const finishedPromise = isCompleted
|
|
579
|
+
? Promise.resolve(meta)
|
|
580
|
+
: this.waitForTransactionFinished(transactionId);
|
|
581
|
+
if (meta && !isExisting && !isCompleted) {
|
|
582
|
+
try {
|
|
583
|
+
if (requireApproval !== false) {
|
|
584
|
+
const acceptResult = yield this.requestApproval(transactionMeta, {
|
|
585
|
+
shouldShowRequest,
|
|
586
|
+
});
|
|
587
|
+
resultCallbacks = acceptResult.resultCallbacks;
|
|
550
588
|
}
|
|
551
|
-
|
|
552
|
-
|
|
589
|
+
const { isCompleted: isTxCompleted } = this.isTransactionCompleted(transactionId);
|
|
590
|
+
if (!isTxCompleted) {
|
|
591
|
+
yield this.approveTransaction(transactionId);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
catch (error) {
|
|
595
|
+
const { isCompleted: isTxCompleted } = this.isTransactionCompleted(transactionId);
|
|
596
|
+
if (!isTxCompleted) {
|
|
597
|
+
if (error.code === eth_rpc_errors_1.errorCodes.provider.userRejectedRequest) {
|
|
598
|
+
this.cancelTransaction(transactionId);
|
|
599
|
+
throw eth_rpc_errors_1.ethErrors.provider.userRejectedRequest('User rejected the transaction');
|
|
600
|
+
}
|
|
601
|
+
else {
|
|
602
|
+
this.failTransaction(meta, error);
|
|
603
|
+
}
|
|
553
604
|
}
|
|
554
605
|
}
|
|
555
606
|
}
|
|
556
|
-
const finalMeta =
|
|
607
|
+
const finalMeta = yield finishedPromise;
|
|
557
608
|
switch (finalMeta === null || finalMeta === void 0 ? void 0 : finalMeta.status) {
|
|
558
609
|
case types_1.TransactionStatus.failed:
|
|
559
610
|
resultCallbacks === null || resultCallbacks === void 0 ? void 0 : resultCallbacks.error(finalMeta.error);
|
|
@@ -584,7 +635,7 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
584
635
|
return __awaiter(this, void 0, void 0, function* () {
|
|
585
636
|
const { transactions } = this.state;
|
|
586
637
|
const releaseLock = yield this.mutex.acquire();
|
|
587
|
-
const
|
|
638
|
+
const chainId = this.getChainId();
|
|
588
639
|
const index = transactions.findIndex(({ id }) => transactionID === id);
|
|
589
640
|
const transactionMeta = transactions[index];
|
|
590
641
|
const { transaction: { nonce, from }, } = transactionMeta;
|
|
@@ -625,14 +676,15 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
625
676
|
const signedTx = yield this.sign(unsignedEthTx, from);
|
|
626
677
|
transactionMeta.status = types_1.TransactionStatus.signed;
|
|
627
678
|
this.updateTransaction(transactionMeta);
|
|
628
|
-
const
|
|
629
|
-
transactionMeta.
|
|
679
|
+
const rawTx = (0, ethereumjs_util_1.bufferToHex)(signedTx.serialize());
|
|
680
|
+
transactionMeta.rawTx = rawTx;
|
|
630
681
|
this.updateTransaction(transactionMeta);
|
|
631
682
|
const transactionHash = yield (0, controller_utils_1.query)(this.ethQuery, 'sendRawTransaction', [
|
|
632
|
-
|
|
683
|
+
rawTx,
|
|
633
684
|
]);
|
|
634
685
|
transactionMeta.transactionHash = transactionHash;
|
|
635
686
|
transactionMeta.status = types_1.TransactionStatus.submitted;
|
|
687
|
+
transactionMeta.submittedTime = new Date().getTime();
|
|
636
688
|
this.updateTransaction(transactionMeta);
|
|
637
689
|
this.hub.emit(`${transactionMeta.id}:finished`, transactionMeta);
|
|
638
690
|
}
|
|
@@ -681,9 +733,9 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
681
733
|
trimTransactionsForState(transactions) {
|
|
682
734
|
const nonceNetworkSet = new Set();
|
|
683
735
|
const txsToKeep = transactions.reverse().filter((tx) => {
|
|
684
|
-
const { chainId,
|
|
736
|
+
const { chainId, status, transaction, time } = tx;
|
|
685
737
|
if (transaction) {
|
|
686
|
-
const key = `${transaction.nonce}-${chainId
|
|
738
|
+
const key = `${transaction.nonce}-${chainId}-${new Date(time).toDateString()}`;
|
|
687
739
|
if (nonceNetworkSet.has(key)) {
|
|
688
740
|
return true;
|
|
689
741
|
}
|
|
@@ -819,25 +871,24 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
819
871
|
}, shouldShowRequest));
|
|
820
872
|
});
|
|
821
873
|
}
|
|
822
|
-
getTransaction(
|
|
874
|
+
getTransaction(transactionId) {
|
|
823
875
|
const { transactions } = this.state;
|
|
824
|
-
return transactions.find(({ id }) => id ===
|
|
876
|
+
return transactions.find(({ id }) => id === transactionId);
|
|
825
877
|
}
|
|
826
878
|
getApprovalId(txMeta) {
|
|
827
879
|
return String(txMeta.id);
|
|
828
880
|
}
|
|
829
|
-
isTransactionCompleted(
|
|
830
|
-
const transaction = this.getTransaction(
|
|
881
|
+
isTransactionCompleted(transactionId) {
|
|
882
|
+
const transaction = this.getTransaction(transactionId);
|
|
831
883
|
if (!transaction) {
|
|
832
884
|
return { meta: undefined, isCompleted: false };
|
|
833
885
|
}
|
|
834
886
|
const isCompleted = this.isLocalFinalState(transaction.status);
|
|
835
887
|
return { meta: transaction, isCompleted };
|
|
836
888
|
}
|
|
837
|
-
|
|
838
|
-
const {
|
|
839
|
-
|
|
840
|
-
return { networkId, chainId };
|
|
889
|
+
getChainId() {
|
|
890
|
+
const { providerConfig } = this.getNetworkState();
|
|
891
|
+
return providerConfig.chainId;
|
|
841
892
|
}
|
|
842
893
|
prepareUnsignedEthTx(txParams) {
|
|
843
894
|
return tx_1.TransactionFactory.fromTxData(txParams, {
|
|
@@ -855,7 +906,7 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
855
906
|
* @returns common configuration object
|
|
856
907
|
*/
|
|
857
908
|
getCommonConfiguration() {
|
|
858
|
-
const {
|
|
909
|
+
const { providerConfig: { type: chain, chainId, nickname: name }, } = this.getNetworkState();
|
|
859
910
|
if (chain !== controller_utils_1.RPC &&
|
|
860
911
|
chain !== controller_utils_1.NetworkType['linea-goerli'] &&
|
|
861
912
|
chain !== controller_utils_1.NetworkType['linea-mainnet']) {
|
|
@@ -864,7 +915,6 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
864
915
|
const customChainParams = {
|
|
865
916
|
name,
|
|
866
917
|
chainId: parseInt(chainId, 16),
|
|
867
|
-
networkId: networkId === null ? NaN : parseInt(networkId, undefined),
|
|
868
918
|
defaultHardfork: exports.HARDFORK,
|
|
869
919
|
};
|
|
870
920
|
return common_1.Common.custom(customChainParams);
|
|
@@ -911,6 +961,86 @@ class TransactionController extends base_controller_1.BaseController {
|
|
|
911
961
|
}
|
|
912
962
|
return dappSuggestedGasFees;
|
|
913
963
|
}
|
|
964
|
+
/**
|
|
965
|
+
* Validates and adds external provided transaction to state.
|
|
966
|
+
*
|
|
967
|
+
* @param transactionMeta - Nominated external transaction to be added to state.
|
|
968
|
+
*/
|
|
969
|
+
addExternalTransaction(transactionMeta) {
|
|
970
|
+
var _a;
|
|
971
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
972
|
+
const chainId = this.getChainId();
|
|
973
|
+
const { transactions } = this.state;
|
|
974
|
+
const fromAddress = (_a = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.transaction) === null || _a === void 0 ? void 0 : _a.from;
|
|
975
|
+
const sameFromAndNetworkTransactions = transactions.filter((transaction) => transaction.transaction.from === fromAddress &&
|
|
976
|
+
(0, utils_1.transactionMatchesChainId)(transaction, chainId));
|
|
977
|
+
const confirmedTxs = sameFromAndNetworkTransactions.filter((transaction) => transaction.status === types_1.TransactionStatus.confirmed);
|
|
978
|
+
const pendingTxs = sameFromAndNetworkTransactions.filter((transaction) => transaction.status === types_1.TransactionStatus.submitted);
|
|
979
|
+
(0, external_transactions_1.validateConfirmedExternalTransaction)(transactionMeta, confirmedTxs, pendingTxs);
|
|
980
|
+
const updatedTransactions = [...transactions, transactionMeta];
|
|
981
|
+
this.update({
|
|
982
|
+
transactions: this.trimTransactionsForState(updatedTransactions),
|
|
983
|
+
});
|
|
984
|
+
});
|
|
985
|
+
}
|
|
986
|
+
/**
|
|
987
|
+
* Sets other txMeta statuses to dropped if the txMeta that has been confirmed has other transactions
|
|
988
|
+
* in the transactions have the same nonce.
|
|
989
|
+
*
|
|
990
|
+
* @param transactionId - Used to identify original transaction.
|
|
991
|
+
*/
|
|
992
|
+
markNonceDuplicatesDropped(transactionId) {
|
|
993
|
+
var _a, _b;
|
|
994
|
+
const chainId = this.getChainId();
|
|
995
|
+
const transactionMeta = this.getTransaction(transactionId);
|
|
996
|
+
const nonce = (_a = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.transaction) === null || _a === void 0 ? void 0 : _a.nonce;
|
|
997
|
+
const from = (_b = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.transaction) === null || _b === void 0 ? void 0 : _b.from;
|
|
998
|
+
const sameNonceTxs = this.state.transactions.filter((transaction) => transaction.transaction.from === from &&
|
|
999
|
+
transaction.transaction.nonce === nonce &&
|
|
1000
|
+
(0, utils_1.transactionMatchesChainId)(transaction, chainId));
|
|
1001
|
+
if (!sameNonceTxs.length) {
|
|
1002
|
+
return;
|
|
1003
|
+
}
|
|
1004
|
+
// Mark all same nonce transactions as dropped and give it a replacedBy hash
|
|
1005
|
+
for (const transaction of sameNonceTxs) {
|
|
1006
|
+
if (transaction.id === transactionId) {
|
|
1007
|
+
continue;
|
|
1008
|
+
}
|
|
1009
|
+
transaction.replacedBy = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.hash;
|
|
1010
|
+
transaction.replacedById = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.id;
|
|
1011
|
+
// Drop any transaction that wasn't previously failed (off chain failure)
|
|
1012
|
+
if (transaction.status !== types_1.TransactionStatus.failed) {
|
|
1013
|
+
this.setTransactionStatusDropped(transaction);
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
/**
|
|
1018
|
+
* Method to set transaction status to dropped.
|
|
1019
|
+
*
|
|
1020
|
+
* @param transactionMeta - TransactionMeta of transaction to be marked as dropped.
|
|
1021
|
+
*/
|
|
1022
|
+
setTransactionStatusDropped(transactionMeta) {
|
|
1023
|
+
transactionMeta.status = types_1.TransactionStatus.dropped;
|
|
1024
|
+
this.updateTransaction(transactionMeta);
|
|
1025
|
+
}
|
|
1026
|
+
/**
|
|
1027
|
+
* Get transaction with provided actionId.
|
|
1028
|
+
*
|
|
1029
|
+
* @param actionId - Unique ID to prevent duplicate requests
|
|
1030
|
+
* @returns the filtered transaction
|
|
1031
|
+
*/
|
|
1032
|
+
getTransactionWithActionId(actionId) {
|
|
1033
|
+
return this.state.transactions.find((transaction) => actionId && transaction.actionId === actionId);
|
|
1034
|
+
}
|
|
1035
|
+
waitForTransactionFinished(transactionId) {
|
|
1036
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1037
|
+
return new Promise((resolve) => {
|
|
1038
|
+
this.hub.once(`${transactionId}:finished`, (txMeta) => {
|
|
1039
|
+
resolve(txMeta);
|
|
1040
|
+
});
|
|
1041
|
+
});
|
|
1042
|
+
});
|
|
1043
|
+
}
|
|
914
1044
|
}
|
|
915
1045
|
exports.TransactionController = TransactionController;
|
|
916
1046
|
exports.default = TransactionController;
|