@metamask-previews/transaction-controller 23.1.0-preview.bf56dac → 24.0.0-preview.53232c55
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 +17 -1
- package/dist/TransactionController.d.ts +232 -46
- package/dist/TransactionController.d.ts.map +1 -1
- package/dist/TransactionController.js +278 -192
- package/dist/TransactionController.js.map +1 -1
- package/dist/constants.d.ts +3 -3
- package/dist/constants.js +4 -4
- package/dist/constants.js.map +1 -1
- package/dist/helpers/GasFeePoller.d.ts.map +1 -1
- package/dist/helpers/GasFeePoller.js +4 -5
- package/dist/helpers/GasFeePoller.js.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.d.ts.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.js +1 -2
- package/dist/helpers/IncomingTransactionHelper.js.map +1 -1
- package/dist/helpers/PendingTransactionTracker.d.ts.map +1 -1
- package/dist/helpers/PendingTransactionTracker.js +18 -22
- package/dist/helpers/PendingTransactionTracker.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -19
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +24 -65
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/history.d.ts +9 -4
- package/dist/utils/history.d.ts.map +1 -1
- package/dist/utils/history.js +12 -7
- package/dist/utils/history.js.map +1 -1
- package/dist/utils/swaps.d.ts +8 -5
- package/dist/utils/swaps.d.ts.map +1 -1
- package/dist/utils/swaps.js +47 -41
- package/dist/utils/swaps.js.map +1 -1
- package/dist/utils/utils.d.ts +9 -1
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +35 -6
- package/dist/utils/utils.js.map +1 -1
- package/package.json +6 -5
|
@@ -22,9 +22,9 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
22
22
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
23
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
24
|
};
|
|
25
|
-
var _TransactionController_instances, _TransactionController_incomingTransactionOptions, _TransactionController_pendingTransactionOptions, _TransactionController_multichainTrackingHelper, _TransactionController_createNonceTracker, _TransactionController_createIncomingTransactionHelper, _TransactionController_createPendingTransactionTracker, _TransactionController_checkForPendingTransactionAndStartPolling, _TransactionController_stopAllTracking, _TransactionController_removeIncomingTransactionHelperListeners, _TransactionController_addIncomingTransactionHelperListeners, _TransactionController_removePendingTransactionTrackerListeners, _TransactionController_addPendingTransactionTrackerListeners, _TransactionController_getNonceTrackerPendingTransactions, _TransactionController_getGasFeeFlows, _TransactionController_updateTransactionInternal;
|
|
25
|
+
var _TransactionController_instances, _TransactionController_internalEvents, _TransactionController_incomingTransactionOptions, _TransactionController_pendingTransactionOptions, _TransactionController_transactionHistoryLimit, _TransactionController_multichainTrackingHelper, _TransactionController_createNonceTracker, _TransactionController_createIncomingTransactionHelper, _TransactionController_createPendingTransactionTracker, _TransactionController_checkForPendingTransactionAndStartPolling, _TransactionController_stopAllTracking, _TransactionController_removeIncomingTransactionHelperListeners, _TransactionController_addIncomingTransactionHelperListeners, _TransactionController_removePendingTransactionTrackerListeners, _TransactionController_addPendingTransactionTrackerListeners, _TransactionController_getNonceTrackerPendingTransactions, _TransactionController_getGasFeeFlows, _TransactionController_updateTransactionInternal;
|
|
26
26
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
-
exports.TransactionController = exports.SPEED_UP_RATE = exports.CANCEL_RATE = exports.HARDFORK = void 0;
|
|
27
|
+
exports.TransactionController = exports.ApprovalState = exports.SPEED_UP_RATE = exports.CANCEL_RATE = exports.HARDFORK = void 0;
|
|
28
28
|
const common_1 = require("@ethereumjs/common");
|
|
29
29
|
const tx_1 = require("@ethereumjs/tx");
|
|
30
30
|
const util_1 = require("@ethereumjs/util");
|
|
@@ -58,6 +58,24 @@ const swaps_1 = require("./utils/swaps");
|
|
|
58
58
|
const transaction_type_1 = require("./utils/transaction-type");
|
|
59
59
|
const utils_2 = require("./utils/utils");
|
|
60
60
|
const validation_1 = require("./utils/validation");
|
|
61
|
+
/**
|
|
62
|
+
* Metadata for the TransactionController state, describing how to "anonymize"
|
|
63
|
+
* the state and which parts should be persisted.
|
|
64
|
+
*/
|
|
65
|
+
const metadata = {
|
|
66
|
+
transactions: {
|
|
67
|
+
persist: true,
|
|
68
|
+
anonymous: false,
|
|
69
|
+
},
|
|
70
|
+
methodData: {
|
|
71
|
+
persist: true,
|
|
72
|
+
anonymous: false,
|
|
73
|
+
},
|
|
74
|
+
lastFetchedBlockNumbers: {
|
|
75
|
+
persist: true,
|
|
76
|
+
anonymous: false,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
61
79
|
exports.HARDFORK = common_1.Hardfork.London;
|
|
62
80
|
/**
|
|
63
81
|
* Multiplier used to determine a transaction's increased gas fee during cancellation
|
|
@@ -71,42 +89,82 @@ exports.SPEED_UP_RATE = 1.1;
|
|
|
71
89
|
* The name of the {@link TransactionController}.
|
|
72
90
|
*/
|
|
73
91
|
const controllerName = 'TransactionController';
|
|
92
|
+
/**
|
|
93
|
+
* Possible states of the approve transaction step.
|
|
94
|
+
*/
|
|
95
|
+
var ApprovalState;
|
|
96
|
+
(function (ApprovalState) {
|
|
97
|
+
ApprovalState["Approved"] = "approved";
|
|
98
|
+
ApprovalState["NotApproved"] = "not-approved";
|
|
99
|
+
ApprovalState["SkippedViaBeforePublishHook"] = "skipped-via-before-publish-hook";
|
|
100
|
+
})(ApprovalState = exports.ApprovalState || (exports.ApprovalState = {}));
|
|
101
|
+
/**
|
|
102
|
+
* Get the default TransactionsController state.
|
|
103
|
+
*
|
|
104
|
+
* @returns The default TransactionsController state.
|
|
105
|
+
*/
|
|
106
|
+
function getDefaultTransactionControllerState() {
|
|
107
|
+
return {
|
|
108
|
+
methodData: {},
|
|
109
|
+
transactions: [],
|
|
110
|
+
lastFetchedBlockNumbers: {},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
74
113
|
/**
|
|
75
114
|
* Controller responsible for submitting and managing transactions.
|
|
76
115
|
*/
|
|
77
|
-
class TransactionController extends base_controller_1.
|
|
78
|
-
|
|
116
|
+
class TransactionController extends base_controller_1.BaseController {
|
|
117
|
+
/**
|
|
118
|
+
* Constructs a TransactionController.
|
|
119
|
+
*
|
|
120
|
+
* @param options - The controller options.
|
|
121
|
+
* @param options.blockTracker - The block tracker used to poll for new blocks data.
|
|
122
|
+
* @param options.disableHistory - Whether to disable storing history in transaction metadata.
|
|
123
|
+
* @param options.disableSendFlowHistory - Explicitly disable transaction metadata history.
|
|
124
|
+
* @param options.disableSwaps - Whether to disable additional processing on swaps transactions.
|
|
125
|
+
* @param options.getCurrentAccountEIP1559Compatibility - Whether or not the account supports EIP-1559.
|
|
126
|
+
* @param options.getCurrentNetworkEIP1559Compatibility - Whether or not the network supports EIP-1559.
|
|
127
|
+
* @param options.getExternalPendingTransactions - Callback to retrieve pending transactions from external sources.
|
|
128
|
+
* @param options.getGasFeeEstimates - Callback to retrieve gas fee estimates.
|
|
129
|
+
* @param options.getNetworkClientRegistry - Gets the network client registry.
|
|
130
|
+
* @param options.getNetworkState - Gets the state of the network controller.
|
|
131
|
+
* @param options.getPermittedAccounts - Get accounts that a given origin has permissions for.
|
|
132
|
+
* @param options.getSavedGasFees - Gets the saved gas fee config.
|
|
133
|
+
* @param options.getSelectedAddress - Gets the address of the currently selected account.
|
|
134
|
+
* @param options.incomingTransactions - Configuration options for incoming transaction support.
|
|
135
|
+
* @param options.isMultichainEnabled - Enable multichain support.
|
|
136
|
+
* @param options.messenger - The controller messenger.
|
|
137
|
+
* @param options.onNetworkStateChange - Allows subscribing to network controller state changes.
|
|
138
|
+
* @param options.pendingTransactions - Configuration options for pending transaction support.
|
|
139
|
+
* @param options.provider - The provider used to create the underlying EthQuery instance.
|
|
140
|
+
* @param options.securityProviderRequest - A function for verifying a transaction, whether it is malicious or not.
|
|
141
|
+
* @param options.sign - Function used to sign transactions.
|
|
142
|
+
* @param options.state - Initial state to set on this controller.
|
|
143
|
+
* @param options.transactionHistoryLimit - Transaction history limit.
|
|
144
|
+
* @param options.hooks - The controller hooks.
|
|
145
|
+
*/
|
|
146
|
+
constructor({ blockTracker, disableHistory, disableSendFlowHistory, disableSwaps, getCurrentAccountEIP1559Compatibility, getCurrentNetworkEIP1559Compatibility, getExternalPendingTransactions, getGasFeeEstimates, getNetworkClientRegistry, getNetworkState, getPermittedAccounts, getSavedGasFees, getSelectedAddress, incomingTransactions = {}, isMultichainEnabled = false, messenger, onNetworkStateChange, pendingTransactions = {}, provider, securityProviderRequest, sign, state, transactionHistoryLimit = 40, hooks, }) {
|
|
79
147
|
var _a, _b, _c, _d, _e, _f;
|
|
80
|
-
super(
|
|
148
|
+
super({
|
|
149
|
+
name: controllerName,
|
|
150
|
+
metadata,
|
|
151
|
+
messenger,
|
|
152
|
+
state: Object.assign(Object.assign({}, getDefaultTransactionControllerState()), state),
|
|
153
|
+
});
|
|
81
154
|
_TransactionController_instances.add(this);
|
|
155
|
+
_TransactionController_internalEvents.set(this, new events_1.EventEmitter());
|
|
82
156
|
this.inProcessOfSigning = new Set();
|
|
83
157
|
this.mutex = new async_mutex_1.Mutex();
|
|
84
158
|
_TransactionController_incomingTransactionOptions.set(this, void 0);
|
|
85
159
|
_TransactionController_pendingTransactionOptions.set(this, void 0);
|
|
86
160
|
this.signAbortCallbacks = new Map();
|
|
161
|
+
_TransactionController_transactionHistoryLimit.set(this, void 0);
|
|
87
162
|
_TransactionController_multichainTrackingHelper.set(this, void 0);
|
|
88
|
-
/**
|
|
89
|
-
* EventEmitter instance used to listen to specific transactional events
|
|
90
|
-
*/
|
|
91
|
-
this.hub = new events_1.EventEmitter();
|
|
92
|
-
/**
|
|
93
|
-
* Name of this controller used during composition
|
|
94
|
-
*/
|
|
95
|
-
this.name = 'TransactionController';
|
|
96
163
|
_TransactionController_checkForPendingTransactionAndStartPolling.set(this, () => {
|
|
97
164
|
// PendingTransactionTracker reads state through its getTransactions hook
|
|
98
165
|
this.pendingTransactionTracker.startIfPendingTransactions();
|
|
99
166
|
__classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").checkForPendingTransactionAndStartPolling();
|
|
100
167
|
});
|
|
101
|
-
this.defaultConfig = {
|
|
102
|
-
txHistoryLimit: 40,
|
|
103
|
-
};
|
|
104
|
-
this.defaultState = {
|
|
105
|
-
methodData: {},
|
|
106
|
-
transactions: [],
|
|
107
|
-
lastFetchedBlockNumbers: {},
|
|
108
|
-
};
|
|
109
|
-
this.initialize();
|
|
110
168
|
this.messagingSystem = messenger;
|
|
111
169
|
this.getNetworkState = getNetworkState;
|
|
112
170
|
this.isSendFlowHistoryDisabled = disableSendFlowHistory !== null && disableSendFlowHistory !== void 0 ? disableSendFlowHistory : false;
|
|
@@ -128,6 +186,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
128
186
|
this.securityProviderRequest = securityProviderRequest;
|
|
129
187
|
__classPrivateFieldSet(this, _TransactionController_incomingTransactionOptions, incomingTransactions, "f");
|
|
130
188
|
__classPrivateFieldSet(this, _TransactionController_pendingTransactionOptions, pendingTransactions, "f");
|
|
189
|
+
__classPrivateFieldSet(this, _TransactionController_transactionHistoryLimit, transactionHistoryLimit, "f");
|
|
190
|
+
this.sign = sign;
|
|
131
191
|
this.afterSign = (_a = hooks === null || hooks === void 0 ? void 0 : hooks.afterSign) !== null && _a !== void 0 ? _a : (() => true);
|
|
132
192
|
this.beforeApproveOnInit = (_b = hooks === null || hooks === void 0 ? void 0 : hooks.beforeApproveOnInit) !== null && _b !== void 0 ? _b : (() => true);
|
|
133
193
|
this.beforeCheckPendingTransaction =
|
|
@@ -187,13 +247,13 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
187
247
|
getGasFeeControllerEstimates: this.getGasFeeEstimates,
|
|
188
248
|
getTransactions: () => this.state.transactions,
|
|
189
249
|
onStateChange: (listener) => {
|
|
190
|
-
this.subscribe(listener);
|
|
250
|
+
this.messagingSystem.subscribe('TransactionController:stateChange', listener);
|
|
191
251
|
},
|
|
192
252
|
});
|
|
193
253
|
gasFeePoller.hub.on('transaction-updated', (transactionMeta) => __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateTransactionInternal).call(this, transactionMeta, { skipHistory: true }));
|
|
194
254
|
// when transactionsController state changes
|
|
195
255
|
// check for pending transactions and start polling if there are any
|
|
196
|
-
this.subscribe(__classPrivateFieldGet(this, _TransactionController_checkForPendingTransactionAndStartPolling, "f"));
|
|
256
|
+
this.messagingSystem.subscribe('TransactionController:stateChange', __classPrivateFieldGet(this, _TransactionController_checkForPendingTransactionAndStartPolling, "f"));
|
|
197
257
|
// TODO once v2 is merged make sure this only runs when
|
|
198
258
|
// selectedNetworkClientId changes
|
|
199
259
|
onNetworkStateChange(() => {
|
|
@@ -205,18 +265,25 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
205
265
|
}
|
|
206
266
|
failTransaction(transactionMeta, error, actionId) {
|
|
207
267
|
const newTransactionMeta = Object.assign(Object.assign({}, transactionMeta), { error: (0, utils_2.normalizeTxError)(error), status: types_1.TransactionStatus.failed });
|
|
208
|
-
this.
|
|
268
|
+
this.messagingSystem.publish(`${controllerName}:transactionFailed`, {
|
|
209
269
|
actionId,
|
|
210
270
|
error: error.message,
|
|
211
271
|
transactionMeta: newTransactionMeta,
|
|
212
272
|
});
|
|
213
273
|
this.updateTransaction(newTransactionMeta, 'TransactionController#failTransaction - Add error message and set status to failed');
|
|
214
274
|
this.onTransactionStatusChange(newTransactionMeta);
|
|
215
|
-
this.
|
|
275
|
+
this.messagingSystem.publish(`${controllerName}:transactionFinished`, newTransactionMeta);
|
|
276
|
+
__classPrivateFieldGet(this, _TransactionController_internalEvents, "f").emit(`${transactionMeta.id}:finished`, newTransactionMeta);
|
|
216
277
|
}
|
|
217
278
|
registryLookup(fourBytePrefix) {
|
|
218
279
|
return __awaiter(this, void 0, void 0, function* () {
|
|
219
280
|
const registryMethod = yield this.registry.lookup(fourBytePrefix);
|
|
281
|
+
if (!registryMethod) {
|
|
282
|
+
return {
|
|
283
|
+
registryMethod: '',
|
|
284
|
+
parsedRegistryMethod: { name: undefined, args: undefined },
|
|
285
|
+
};
|
|
286
|
+
}
|
|
220
287
|
const parsedRegistryMethod = this.registry.parse(registryMethod);
|
|
221
288
|
return { registryMethod, parsedRegistryMethod };
|
|
222
289
|
});
|
|
@@ -243,8 +310,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
243
310
|
return methodData[fourBytePrefix];
|
|
244
311
|
}
|
|
245
312
|
const registry = yield this.registryLookup(fourBytePrefix);
|
|
246
|
-
this.update({
|
|
247
|
-
|
|
313
|
+
this.update((state) => {
|
|
314
|
+
state.methodData[fourBytePrefix] = registry;
|
|
248
315
|
});
|
|
249
316
|
return registry;
|
|
250
317
|
}
|
|
@@ -277,7 +344,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
277
344
|
addTransaction(txParams, { actionId, deviceConfirmedOn, method, origin, requireApproval, securityAlertResponse, sendFlowHistory, swaps = {}, type, networkClientId, } = {}) {
|
|
278
345
|
return __awaiter(this, void 0, void 0, function* () {
|
|
279
346
|
(0, logger_1.projectLogger)('Adding transaction', txParams);
|
|
280
|
-
txParams = (0, utils_2.
|
|
347
|
+
txParams = (0, utils_2.normalizeTransactionParams)(txParams);
|
|
281
348
|
if (networkClientId &&
|
|
282
349
|
!__classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").has(networkClientId)) {
|
|
283
350
|
throw new Error('The networkClientId for this transaction could not be found');
|
|
@@ -296,7 +363,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
296
363
|
const transactionType = type !== null && type !== void 0 ? type : (yield (0, transaction_type_1.determineTransactionType)(txParams, ethQuery)).type;
|
|
297
364
|
const existingTransactionMeta = this.getTransactionWithActionId(actionId);
|
|
298
365
|
// If a request to add a transaction with the same actionId is submitted again, a new transaction will not be created for it.
|
|
299
|
-
|
|
366
|
+
let addedTransactionMeta = existingTransactionMeta
|
|
367
|
+
? Object.assign({}, existingTransactionMeta) : {
|
|
300
368
|
// Add actionId to txMeta to check if same actionId is seen again
|
|
301
369
|
actionId,
|
|
302
370
|
chainId,
|
|
@@ -313,38 +381,37 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
313
381
|
type: transactionType,
|
|
314
382
|
networkClientId,
|
|
315
383
|
};
|
|
316
|
-
yield this.updateGasProperties(
|
|
384
|
+
yield this.updateGasProperties(addedTransactionMeta);
|
|
317
385
|
// Checks if a transaction already exists with a given actionId
|
|
318
386
|
if (!existingTransactionMeta) {
|
|
319
387
|
// Set security provider response
|
|
320
388
|
if (method && this.securityProviderRequest) {
|
|
321
|
-
const securityProviderResponse = yield this.securityProviderRequest(
|
|
322
|
-
|
|
389
|
+
const securityProviderResponse = yield this.securityProviderRequest(addedTransactionMeta, method);
|
|
390
|
+
addedTransactionMeta.securityProviderResponse =
|
|
391
|
+
securityProviderResponse;
|
|
323
392
|
}
|
|
324
393
|
if (!this.isSendFlowHistoryDisabled) {
|
|
325
|
-
|
|
394
|
+
addedTransactionMeta.sendFlowHistory = sendFlowHistory !== null && sendFlowHistory !== void 0 ? sendFlowHistory : [];
|
|
326
395
|
}
|
|
327
396
|
// Initial history push
|
|
328
397
|
if (!this.isHistoryDisabled) {
|
|
329
|
-
(0, history_1.addInitialHistorySnapshot)(
|
|
398
|
+
addedTransactionMeta = (0, history_1.addInitialHistorySnapshot)(addedTransactionMeta);
|
|
330
399
|
}
|
|
331
|
-
|
|
400
|
+
addedTransactionMeta = (0, swaps_1.updateSwapsTransaction)(addedTransactionMeta, transactionType, swaps, {
|
|
332
401
|
isSwapsDisabled: this.isSwapsDisabled,
|
|
333
402
|
cancelTransaction: this.cancelTransaction.bind(this),
|
|
334
|
-
|
|
335
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
336
|
-
controllerHubEmitter: this.hub.emit.bind(this.hub),
|
|
403
|
+
messenger: this.messagingSystem,
|
|
337
404
|
});
|
|
338
|
-
this.addMetadata(
|
|
339
|
-
this.
|
|
405
|
+
this.addMetadata(addedTransactionMeta);
|
|
406
|
+
this.messagingSystem.publish(`${controllerName}:unapprovedTransactionAdded`, addedTransactionMeta);
|
|
340
407
|
}
|
|
341
408
|
return {
|
|
342
|
-
result: this.processApproval(
|
|
409
|
+
result: this.processApproval(addedTransactionMeta, {
|
|
343
410
|
isExisting: Boolean(existingTransactionMeta),
|
|
344
411
|
requireApproval,
|
|
345
412
|
actionId,
|
|
346
413
|
}),
|
|
347
|
-
transactionMeta,
|
|
414
|
+
transactionMeta: addedTransactionMeta,
|
|
348
415
|
};
|
|
349
416
|
});
|
|
350
417
|
}
|
|
@@ -476,15 +543,16 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
476
543
|
};
|
|
477
544
|
this.addMetadata(cancelTransactionMeta);
|
|
478
545
|
// stopTransaction has no approval request, so we assume the user has already approved the transaction
|
|
479
|
-
this.
|
|
546
|
+
this.messagingSystem.publish(`${controllerName}:transactionApproved`, {
|
|
480
547
|
transactionMeta: cancelTransactionMeta,
|
|
481
548
|
actionId,
|
|
482
549
|
});
|
|
483
|
-
this.
|
|
550
|
+
this.messagingSystem.publish(`${controllerName}:transactionSubmitted`, {
|
|
484
551
|
transactionMeta: cancelTransactionMeta,
|
|
485
552
|
actionId,
|
|
486
553
|
});
|
|
487
|
-
this.
|
|
554
|
+
this.messagingSystem.publish(`${controllerName}:transactionFinished`, cancelTransactionMeta);
|
|
555
|
+
__classPrivateFieldGet(this, _TransactionController_internalEvents, "f").emit(`${transactionMeta.id}:finished`, cancelTransactionMeta);
|
|
488
556
|
});
|
|
489
557
|
}
|
|
490
558
|
/**
|
|
@@ -542,33 +610,33 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
542
610
|
? Object.assign(Object.assign({}, transactionMeta.txParams), { gasLimit: transactionMeta.txParams.gas, maxFeePerGas: newMaxFeePerGas, maxPriorityFeePerGas: newMaxPriorityFeePerGas, type: types_1.TransactionEnvelopeType.feeMarket }) : Object.assign(Object.assign({}, transactionMeta.txParams), { gasLimit: transactionMeta.txParams.gas, gasPrice: newGasPrice });
|
|
543
611
|
const unsignedEthTx = this.prepareUnsignedEthTx(transactionMeta.chainId, txParams);
|
|
544
612
|
const signedTx = yield this.sign(unsignedEthTx, transactionMeta.txParams.from);
|
|
545
|
-
yield this.updateTransactionMetaRSV(transactionMeta, signedTx);
|
|
613
|
+
const transactionMetaWithRsv = yield this.updateTransactionMetaRSV(transactionMeta, signedTx);
|
|
546
614
|
const rawTx = (0, util_1.bufferToHex)(signedTx.serialize());
|
|
547
615
|
const newFee = (_c = txParams.maxFeePerGas) !== null && _c !== void 0 ? _c : txParams.gasPrice;
|
|
548
616
|
const oldFee = txParams.maxFeePerGas
|
|
549
|
-
?
|
|
550
|
-
:
|
|
617
|
+
? transactionMetaWithRsv.txParams.maxFeePerGas
|
|
618
|
+
: transactionMetaWithRsv.txParams.gasPrice;
|
|
551
619
|
(0, logger_1.projectLogger)('Submitting speed up transaction', { oldFee, newFee, txParams });
|
|
552
620
|
const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
553
621
|
networkClientId: transactionMeta.networkClientId,
|
|
554
622
|
chainId: transactionMeta.chainId,
|
|
555
623
|
});
|
|
556
624
|
const hash = yield this.publishTransactionForRetry(ethQuery, rawTx, transactionMeta);
|
|
557
|
-
const baseTransactionMeta = Object.assign(Object.assign({},
|
|
625
|
+
const baseTransactionMeta = Object.assign(Object.assign({}, transactionMetaWithRsv), { estimatedBaseFee, id: (0, uuid_1.v1)(), time: Date.now(), hash,
|
|
558
626
|
actionId, originalGasEstimate: transactionMeta.txParams.gas, type: types_1.TransactionType.retry, originalType: transactionMeta.type });
|
|
559
627
|
const newTransactionMeta = newMaxFeePerGas && newMaxPriorityFeePerGas
|
|
560
628
|
? Object.assign(Object.assign({}, baseTransactionMeta), { txParams: Object.assign(Object.assign({}, transactionMeta.txParams), { maxFeePerGas: newMaxFeePerGas, maxPriorityFeePerGas: newMaxPriorityFeePerGas }) }) : Object.assign(Object.assign({}, baseTransactionMeta), { txParams: Object.assign(Object.assign({}, transactionMeta.txParams), { gasPrice: newGasPrice }) });
|
|
561
629
|
this.addMetadata(newTransactionMeta);
|
|
562
630
|
// speedUpTransaction has no approval request, so we assume the user has already approved the transaction
|
|
563
|
-
this.
|
|
631
|
+
this.messagingSystem.publish(`${controllerName}:transactionApproved`, {
|
|
564
632
|
transactionMeta: newTransactionMeta,
|
|
565
633
|
actionId,
|
|
566
634
|
});
|
|
567
|
-
this.
|
|
635
|
+
this.messagingSystem.publish(`${controllerName}:transactionSubmitted`, {
|
|
568
636
|
transactionMeta: newTransactionMeta,
|
|
569
637
|
actionId,
|
|
570
638
|
});
|
|
571
|
-
this.
|
|
639
|
+
this.messagingSystem.publish(`${controllerName}:speedupTransactionAdded`, newTransactionMeta);
|
|
572
640
|
});
|
|
573
641
|
}
|
|
574
642
|
/**
|
|
@@ -633,8 +701,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
633
701
|
if (!transactionMeta) {
|
|
634
702
|
throw new Error(`Cannot update security alert response as no transaction metadata found`);
|
|
635
703
|
}
|
|
636
|
-
const
|
|
637
|
-
this.updateTransaction(
|
|
704
|
+
const updatedTransactionMeta = Object.assign(Object.assign({}, transactionMeta), { securityAlertResponse });
|
|
705
|
+
this.updateTransaction(updatedTransactionMeta, `${controllerName}:updatesecurityAlertResponse - securityAlertResponse updated`);
|
|
638
706
|
}
|
|
639
707
|
/**
|
|
640
708
|
* Removes all transactions from state, optionally based on the current network.
|
|
@@ -647,7 +715,9 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
647
715
|
wipeTransactions(ignoreNetwork, address) {
|
|
648
716
|
/* istanbul ignore next */
|
|
649
717
|
if (ignoreNetwork && !address) {
|
|
650
|
-
this.update(
|
|
718
|
+
this.update((state) => {
|
|
719
|
+
state.transactions = [];
|
|
720
|
+
});
|
|
651
721
|
return;
|
|
652
722
|
}
|
|
653
723
|
const currentChainId = this.getChainId();
|
|
@@ -660,8 +730,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
660
730
|
const isMatchingAddress = !address || ((_a = txParams.from) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === address.toLowerCase();
|
|
661
731
|
return !isMatchingAddress;
|
|
662
732
|
});
|
|
663
|
-
this.update({
|
|
664
|
-
transactions
|
|
733
|
+
this.update((state) => {
|
|
734
|
+
state.transactions = this.trimTransactionsForState(newTransactions);
|
|
665
735
|
});
|
|
666
736
|
}
|
|
667
737
|
/**
|
|
@@ -674,26 +744,23 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
674
744
|
confirmExternalTransaction(transactionMeta, transactionReceipt, baseFeePerGas) {
|
|
675
745
|
return __awaiter(this, void 0, void 0, function* () {
|
|
676
746
|
// Run validation and add external transaction to state.
|
|
677
|
-
this.addExternalTransaction(transactionMeta);
|
|
747
|
+
const newTransactionMeta = this.addExternalTransaction(transactionMeta);
|
|
678
748
|
try {
|
|
679
|
-
const transactionId =
|
|
749
|
+
const transactionId = newTransactionMeta.id;
|
|
680
750
|
// Make sure status is confirmed and define gasUsed as in receipt.
|
|
681
|
-
|
|
682
|
-
transactionMeta.txReceipt = transactionReceipt;
|
|
751
|
+
const updatedTransactionMeta = Object.assign(Object.assign({}, newTransactionMeta), { status: types_1.TransactionStatus.confirmed, txReceipt: transactionReceipt });
|
|
683
752
|
if (baseFeePerGas) {
|
|
684
|
-
|
|
753
|
+
updatedTransactionMeta.baseFeePerGas = baseFeePerGas;
|
|
685
754
|
}
|
|
686
755
|
// Update same nonce local transactions as dropped and define replacedBy properties.
|
|
687
756
|
this.markNonceDuplicatesDropped(transactionId);
|
|
688
757
|
// Update external provided transaction with updated gas values and confirmed status.
|
|
689
|
-
this.updateTransaction(
|
|
690
|
-
this.onTransactionStatusChange(
|
|
758
|
+
this.updateTransaction(updatedTransactionMeta, `${controllerName}:confirmExternalTransaction - Add external transaction`);
|
|
759
|
+
this.onTransactionStatusChange(updatedTransactionMeta);
|
|
691
760
|
// Intentional given potential duration of process.
|
|
692
761
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
693
|
-
this.updatePostBalance(
|
|
694
|
-
this.
|
|
695
|
-
transactionMeta,
|
|
696
|
-
});
|
|
762
|
+
this.updatePostBalance(updatedTransactionMeta);
|
|
763
|
+
this.messagingSystem.publish(`${controllerName}:transactionConfirmed`, updatedTransactionMeta);
|
|
697
764
|
}
|
|
698
765
|
catch (error) {
|
|
699
766
|
console.error('Failed to confirm external transaction', error);
|
|
@@ -709,7 +776,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
709
776
|
* @returns The updated transactionMeta.
|
|
710
777
|
*/
|
|
711
778
|
updateTransactionSendFlowHistory(transactionID, currentSendFlowHistoryLength, sendFlowHistoryToAdd) {
|
|
712
|
-
var _a
|
|
779
|
+
var _a;
|
|
713
780
|
if (this.isSendFlowHistoryDisabled) {
|
|
714
781
|
throw new Error('Send flow history is disabled for the current transaction controller');
|
|
715
782
|
}
|
|
@@ -718,13 +785,10 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
718
785
|
throw new Error(`Cannot update send flow history as no transaction metadata found`);
|
|
719
786
|
}
|
|
720
787
|
(0, utils_2.validateIfTransactionUnapproved)(transactionMeta, 'updateTransactionSendFlowHistory');
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
transactionMeta
|
|
724
|
-
|
|
725
|
-
...sendFlowHistoryToAdd,
|
|
726
|
-
];
|
|
727
|
-
this.updateTransaction(transactionMeta, 'TransactionController:updateTransactionSendFlowHistory - sendFlowHistory updated');
|
|
788
|
+
const sendFlowHistory = (_a = transactionMeta.sendFlowHistory) !== null && _a !== void 0 ? _a : [];
|
|
789
|
+
if (currentSendFlowHistoryLength === sendFlowHistory.length) {
|
|
790
|
+
const updatedTransactionMeta = Object.assign(Object.assign({}, transactionMeta), { sendFlowHistory: [...sendFlowHistory, ...sendFlowHistoryToAdd] });
|
|
791
|
+
this.updateTransaction(updatedTransactionMeta, `${controllerName}:updateTransactionSendFlowHistory - sendFlowHistory updated`);
|
|
728
792
|
}
|
|
729
793
|
return this.getTransaction(transactionID);
|
|
730
794
|
}
|
|
@@ -774,7 +838,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
774
838
|
transactionGasFees = (0, lodash_1.pickBy)(transactionGasFees);
|
|
775
839
|
// merge updated gas values with existing transaction meta
|
|
776
840
|
const updatedMeta = (0, lodash_1.merge)(transactionMeta, transactionGasFees);
|
|
777
|
-
this.updateTransaction(updatedMeta,
|
|
841
|
+
this.updateTransaction(updatedMeta, `${controllerName}:updateTransactionGasFees - gas values updated`);
|
|
778
842
|
return this.getTransaction(transactionId);
|
|
779
843
|
}
|
|
780
844
|
/**
|
|
@@ -806,7 +870,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
806
870
|
transactionPreviousGas.previousGas = (0, lodash_1.pickBy)(transactionPreviousGas.previousGas);
|
|
807
871
|
// merge updated previous gas values with existing transaction meta
|
|
808
872
|
const updatedMeta = (0, lodash_1.merge)(transactionMeta, transactionPreviousGas);
|
|
809
|
-
this.updateTransaction(updatedMeta,
|
|
873
|
+
this.updateTransaction(updatedMeta, `${controllerName}:updatePreviousGasParams - Previous gas values updated`);
|
|
810
874
|
return this.getTransaction(transactionId);
|
|
811
875
|
}
|
|
812
876
|
getNonceLock(address, networkClientId) {
|
|
@@ -950,16 +1014,16 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
950
1014
|
].includes(status)) {
|
|
951
1015
|
throw new Error(`Cannot update custodial transaction with status: ${status}`);
|
|
952
1016
|
}
|
|
953
|
-
const updatedTransactionMeta = (0, lodash_1.merge)(transactionMeta, (0, lodash_1.pickBy)({ hash, status }));
|
|
1017
|
+
const updatedTransactionMeta = (0, lodash_1.merge)({}, transactionMeta, (0, lodash_1.pickBy)({ hash, status }));
|
|
954
1018
|
if (status === types_1.TransactionStatus.submitted) {
|
|
955
1019
|
updatedTransactionMeta.submittedTime = new Date().getTime();
|
|
956
1020
|
}
|
|
957
1021
|
if (status === types_1.TransactionStatus.failed) {
|
|
958
1022
|
updatedTransactionMeta.error = (0, utils_2.normalizeTxError)(new Error(errorMessage));
|
|
959
1023
|
}
|
|
960
|
-
this.updateTransaction(updatedTransactionMeta,
|
|
1024
|
+
this.updateTransaction(updatedTransactionMeta, `${controllerName}:updateCustodialTransaction - Custodial transaction updated`);
|
|
961
1025
|
if ([types_1.TransactionStatus.submitted, types_1.TransactionStatus.failed].includes(status)) {
|
|
962
|
-
this.
|
|
1026
|
+
this.messagingSystem.publish(`${controllerName}:transactionFinished`, updatedTransactionMeta);
|
|
963
1027
|
}
|
|
964
1028
|
}
|
|
965
1029
|
/**
|
|
@@ -1072,7 +1136,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1072
1136
|
if (!this.sign) {
|
|
1073
1137
|
throw new Error('No sign method defined.');
|
|
1074
1138
|
}
|
|
1075
|
-
const normalizedTransactionParams = (0, utils_2.
|
|
1139
|
+
const normalizedTransactionParams = (0, utils_2.normalizeTransactionParams)(transactionParams);
|
|
1076
1140
|
const type = (0, utils_2.isEIP1559Transaction)(normalizedTransactionParams)
|
|
1077
1141
|
? types_1.TransactionEnvelopeType.feeMarket
|
|
1078
1142
|
: types_1.TransactionEnvelopeType.legacy;
|
|
@@ -1090,7 +1154,9 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1090
1154
|
*/
|
|
1091
1155
|
clearUnapprovedTransactions() {
|
|
1092
1156
|
const transactions = this.state.transactions.filter(({ status }) => status !== types_1.TransactionStatus.unapproved);
|
|
1093
|
-
this.update(
|
|
1157
|
+
this.update((state) => {
|
|
1158
|
+
state.transactions = this.trimTransactionsForState(transactions);
|
|
1159
|
+
});
|
|
1094
1160
|
}
|
|
1095
1161
|
/**
|
|
1096
1162
|
* Stop the signing process for a specific transaction.
|
|
@@ -1110,9 +1176,12 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1110
1176
|
this.signAbortCallbacks.delete(transactionId);
|
|
1111
1177
|
}
|
|
1112
1178
|
addMetadata(transactionMeta) {
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1179
|
+
this.update((state) => {
|
|
1180
|
+
state.transactions = this.trimTransactionsForState([
|
|
1181
|
+
...state.transactions,
|
|
1182
|
+
transactionMeta,
|
|
1183
|
+
]);
|
|
1184
|
+
});
|
|
1116
1185
|
}
|
|
1117
1186
|
updateGasProperties(transactionMeta) {
|
|
1118
1187
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1176,13 +1245,6 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1176
1245
|
shouldShowRequest,
|
|
1177
1246
|
});
|
|
1178
1247
|
resultCallbacks = acceptResult.resultCallbacks;
|
|
1179
|
-
if (resultCallbacks) {
|
|
1180
|
-
this.hub.once(`${transactionId}:publish-skip`, () => {
|
|
1181
|
-
resultCallbacks === null || resultCallbacks === void 0 ? void 0 : resultCallbacks.success();
|
|
1182
|
-
// Remove the reference to prevent additional reports once submitted.
|
|
1183
|
-
resultCallbacks = undefined;
|
|
1184
|
-
});
|
|
1185
|
-
}
|
|
1186
1248
|
const approvalValue = acceptResult.value;
|
|
1187
1249
|
const updatedTransaction = approvalValue === null || approvalValue === void 0 ? void 0 : approvalValue.txMeta;
|
|
1188
1250
|
if (updatedTransaction) {
|
|
@@ -1195,9 +1257,13 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1195
1257
|
}
|
|
1196
1258
|
const { isCompleted: isTxCompleted } = this.isTransactionCompleted(transactionId);
|
|
1197
1259
|
if (!isTxCompleted) {
|
|
1198
|
-
yield this.approveTransaction(transactionId);
|
|
1260
|
+
const approvalResult = yield this.approveTransaction(transactionId);
|
|
1261
|
+
if (approvalResult === ApprovalState.SkippedViaBeforePublishHook &&
|
|
1262
|
+
resultCallbacks) {
|
|
1263
|
+
resultCallbacks.success();
|
|
1264
|
+
}
|
|
1199
1265
|
const updatedTransactionMeta = this.getTransaction(transactionId);
|
|
1200
|
-
this.
|
|
1266
|
+
this.messagingSystem.publish(`${controllerName}:transactionApproved`, {
|
|
1201
1267
|
transactionMeta: updatedTransactionMeta,
|
|
1202
1268
|
actionId,
|
|
1203
1269
|
});
|
|
@@ -1247,42 +1313,42 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1247
1313
|
const releaseLock = yield this.mutex.acquire();
|
|
1248
1314
|
const index = transactions.findIndex(({ id }) => transactionId === id);
|
|
1249
1315
|
const transactionMeta = transactions[index];
|
|
1316
|
+
const updatedTransactionMeta = Object.assign({}, transactionMeta);
|
|
1250
1317
|
const { txParams: { from }, networkClientId, } = transactionMeta;
|
|
1251
1318
|
let releaseNonceLock;
|
|
1252
1319
|
try {
|
|
1253
1320
|
if (!this.sign) {
|
|
1254
1321
|
releaseLock();
|
|
1255
1322
|
this.failTransaction(transactionMeta, new Error('No sign method defined.'));
|
|
1256
|
-
return;
|
|
1323
|
+
return ApprovalState.NotApproved;
|
|
1257
1324
|
}
|
|
1258
1325
|
else if (!transactionMeta.chainId) {
|
|
1259
1326
|
releaseLock();
|
|
1260
1327
|
this.failTransaction(transactionMeta, new Error('No chainId defined.'));
|
|
1261
|
-
return;
|
|
1328
|
+
return ApprovalState.NotApproved;
|
|
1262
1329
|
}
|
|
1263
1330
|
if (this.inProcessOfSigning.has(transactionId)) {
|
|
1264
1331
|
(0, logger_1.projectLogger)('Skipping approval as signing in progress', transactionId);
|
|
1265
|
-
return;
|
|
1332
|
+
return ApprovalState.NotApproved;
|
|
1266
1333
|
}
|
|
1267
1334
|
const [nonce, releaseNonce] = yield (0, nonce_1.getNextNonce)(transactionMeta, (address) => __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getNonceLock(address, networkClientId));
|
|
1268
1335
|
releaseNonceLock = releaseNonce;
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
this.
|
|
1274
|
-
|
|
1275
|
-
const isEIP1559 = (0, utils_2.isEIP1559Transaction)(transactionMeta.txParams);
|
|
1336
|
+
updatedTransactionMeta.status = types_1.TransactionStatus.approved;
|
|
1337
|
+
updatedTransactionMeta.txParams = Object.assign(Object.assign({}, updatedTransactionMeta.txParams), { nonce, chainId: transactionMeta.chainId });
|
|
1338
|
+
const baseTxParams = Object.assign(Object.assign({}, updatedTransactionMeta.txParams), { gasLimit: updatedTransactionMeta.txParams.gas });
|
|
1339
|
+
this.updateTransaction(updatedTransactionMeta, 'TransactionController#approveTransaction - Transaction approved');
|
|
1340
|
+
this.onTransactionStatusChange(updatedTransactionMeta);
|
|
1341
|
+
const isEIP1559 = (0, utils_2.isEIP1559Transaction)(updatedTransactionMeta.txParams);
|
|
1276
1342
|
const txParams = isEIP1559
|
|
1277
|
-
? Object.assign(Object.assign({}, baseTxParams), { estimatedBaseFee:
|
|
1278
|
-
const rawTx = yield this.signTransaction(
|
|
1279
|
-
if (!this.beforePublish(
|
|
1343
|
+
? Object.assign(Object.assign({}, baseTxParams), { estimatedBaseFee: updatedTransactionMeta.txParams.estimatedBaseFee, type: types_1.TransactionEnvelopeType.feeMarket }) : baseTxParams;
|
|
1344
|
+
const rawTx = yield this.signTransaction(updatedTransactionMeta, txParams);
|
|
1345
|
+
if (!this.beforePublish(updatedTransactionMeta)) {
|
|
1280
1346
|
(0, logger_1.projectLogger)('Skipping publishing transaction based on hook');
|
|
1281
|
-
this.
|
|
1282
|
-
return;
|
|
1347
|
+
this.messagingSystem.publish(`${controllerName}:transactionPublishingSkipped`, updatedTransactionMeta);
|
|
1348
|
+
return ApprovalState.SkippedViaBeforePublishHook;
|
|
1283
1349
|
}
|
|
1284
1350
|
if (!rawTx) {
|
|
1285
|
-
return;
|
|
1351
|
+
return ApprovalState.NotApproved;
|
|
1286
1352
|
}
|
|
1287
1353
|
const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
1288
1354
|
networkClientId: transactionMeta.networkClientId,
|
|
@@ -1291,8 +1357,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1291
1357
|
if (transactionMeta.type === types_1.TransactionType.swap) {
|
|
1292
1358
|
(0, logger_1.projectLogger)('Determining pre-transaction balance');
|
|
1293
1359
|
const preTxBalance = yield (0, controller_utils_1.query)(ethQuery, 'getBalance', [from]);
|
|
1294
|
-
|
|
1295
|
-
(0, logger_1.projectLogger)('Updated pre-transaction balance',
|
|
1360
|
+
updatedTransactionMeta.preTxBalance = preTxBalance;
|
|
1361
|
+
(0, logger_1.projectLogger)('Updated pre-transaction balance', updatedTransactionMeta.preTxBalance);
|
|
1296
1362
|
}
|
|
1297
1363
|
(0, logger_1.projectLogger)('Publishing transaction', txParams);
|
|
1298
1364
|
let { transactionHash: hash } = yield this.publish(transactionMeta, rawTx);
|
|
@@ -1300,20 +1366,23 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1300
1366
|
hash = yield this.publishTransaction(ethQuery, rawTx);
|
|
1301
1367
|
}
|
|
1302
1368
|
(0, logger_1.projectLogger)('Publish successful', hash);
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
this.updateTransaction(
|
|
1307
|
-
this.
|
|
1308
|
-
transactionMeta,
|
|
1369
|
+
updatedTransactionMeta.hash = hash;
|
|
1370
|
+
updatedTransactionMeta.status = types_1.TransactionStatus.submitted;
|
|
1371
|
+
updatedTransactionMeta.submittedTime = new Date().getTime();
|
|
1372
|
+
this.updateTransaction(updatedTransactionMeta, 'TransactionController#approveTransaction - Transaction submitted');
|
|
1373
|
+
this.messagingSystem.publish(`${controllerName}:transactionSubmitted`, {
|
|
1374
|
+
transactionMeta: updatedTransactionMeta,
|
|
1309
1375
|
});
|
|
1310
|
-
this.
|
|
1311
|
-
this.
|
|
1376
|
+
this.messagingSystem.publish(`${controllerName}:transactionFinished`, updatedTransactionMeta);
|
|
1377
|
+
__classPrivateFieldGet(this, _TransactionController_internalEvents, "f").emit(`${updatedTransactionMeta.id}:finished`, updatedTransactionMeta);
|
|
1378
|
+
this.onTransactionStatusChange(updatedTransactionMeta);
|
|
1379
|
+
return ApprovalState.Approved;
|
|
1312
1380
|
// TODO: Replace `any` with type
|
|
1313
1381
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1314
1382
|
}
|
|
1315
1383
|
catch (error) {
|
|
1316
1384
|
this.failTransaction(transactionMeta, error);
|
|
1385
|
+
return ApprovalState.NotApproved;
|
|
1317
1386
|
}
|
|
1318
1387
|
finally {
|
|
1319
1388
|
this.inProcessOfSigning.delete(transactionId);
|
|
@@ -1340,15 +1409,18 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1340
1409
|
if (!transactionMeta) {
|
|
1341
1410
|
return;
|
|
1342
1411
|
}
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1412
|
+
this.update((state) => {
|
|
1413
|
+
const transactions = state.transactions.filter(({ id }) => id !== transactionId);
|
|
1414
|
+
state.transactions = this.trimTransactionsForState(transactions);
|
|
1415
|
+
});
|
|
1416
|
+
const updatedTransactionMeta = Object.assign(Object.assign({}, transactionMeta), { status: types_1.TransactionStatus.rejected });
|
|
1417
|
+
this.messagingSystem.publish(`${controllerName}:transactionFinished`, updatedTransactionMeta);
|
|
1418
|
+
__classPrivateFieldGet(this, _TransactionController_internalEvents, "f").emit(`${transactionMeta.id}:finished`, updatedTransactionMeta);
|
|
1419
|
+
this.messagingSystem.publish(`${controllerName}:transactionRejected`, {
|
|
1420
|
+
transactionMeta: updatedTransactionMeta,
|
|
1349
1421
|
actionId,
|
|
1350
1422
|
});
|
|
1351
|
-
this.onTransactionStatusChange(
|
|
1423
|
+
this.onTransactionStatusChange(updatedTransactionMeta);
|
|
1352
1424
|
}
|
|
1353
1425
|
/**
|
|
1354
1426
|
* Trim the amount of transactions that are set on the state. Checks
|
|
@@ -1357,25 +1429,25 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1357
1429
|
* Pending or unapproved transactions will not be removed by this
|
|
1358
1430
|
* operation. For safety of presenting a fully functional transaction UI
|
|
1359
1431
|
* representation, this function will not break apart transactions with the
|
|
1360
|
-
* same nonce, created on the same day, per network. Not accounting for
|
|
1361
|
-
* nonce, same day and network combo can result in
|
|
1362
|
-
*
|
|
1432
|
+
* same nonce, created on the same day, per network. Not accounting for
|
|
1433
|
+
* transactions of the same nonce, same day and network combo can result in
|
|
1434
|
+
* confusing or broken experiences in the UI.
|
|
1363
1435
|
*
|
|
1364
1436
|
* @param transactions - The transactions to be applied to the state.
|
|
1365
1437
|
* @returns The trimmed list of transactions.
|
|
1366
1438
|
*/
|
|
1367
1439
|
trimTransactionsForState(transactions) {
|
|
1368
1440
|
const nonceNetworkSet = new Set();
|
|
1369
|
-
const txsToKeep = transactions
|
|
1441
|
+
const txsToKeep = [...transactions]
|
|
1370
1442
|
.sort((a, b) => (a.time > b.time ? -1 : 1)) // Descending time order
|
|
1371
1443
|
.filter((tx) => {
|
|
1372
1444
|
const { chainId, status, txParams, time } = tx;
|
|
1373
1445
|
if (txParams) {
|
|
1374
|
-
const key = `${txParams.nonce}-${(0, controller_utils_1.convertHexToDecimal)(chainId)}-${new Date(time).toDateString()}`;
|
|
1446
|
+
const key = `${String(txParams.nonce)}-${(0, controller_utils_1.convertHexToDecimal)(chainId)}-${new Date(time).toDateString()}`;
|
|
1375
1447
|
if (nonceNetworkSet.has(key)) {
|
|
1376
1448
|
return true;
|
|
1377
1449
|
}
|
|
1378
|
-
else if (nonceNetworkSet.size < this
|
|
1450
|
+
else if (nonceNetworkSet.size < __classPrivateFieldGet(this, _TransactionController_transactionHistoryLimit, "f") ||
|
|
1379
1451
|
!this.isFinalState(status)) {
|
|
1380
1452
|
nonceNetworkSet.add(key);
|
|
1381
1453
|
return true;
|
|
@@ -1472,21 +1544,23 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1472
1544
|
return common_1.Common.custom(customChainParams);
|
|
1473
1545
|
}
|
|
1474
1546
|
onIncomingTransactions({ added, updated, }) {
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
transactions
|
|
1547
|
+
this.update((state) => {
|
|
1548
|
+
const { transactions: currentTransactions } = state;
|
|
1549
|
+
const updatedTransactions = [
|
|
1550
|
+
...added,
|
|
1551
|
+
...currentTransactions.map((originalTransaction) => {
|
|
1552
|
+
const updatedTransaction = updated.find(({ hash }) => hash === originalTransaction.hash);
|
|
1553
|
+
return updatedTransaction !== null && updatedTransaction !== void 0 ? updatedTransaction : originalTransaction;
|
|
1554
|
+
}),
|
|
1555
|
+
];
|
|
1556
|
+
state.transactions = this.trimTransactionsForState(updatedTransactions);
|
|
1485
1557
|
});
|
|
1486
1558
|
}
|
|
1487
1559
|
onUpdatedLastFetchedBlockNumbers({ lastFetchedBlockNumbers, blockNumber, }) {
|
|
1488
|
-
this.update(
|
|
1489
|
-
|
|
1560
|
+
this.update((state) => {
|
|
1561
|
+
state.lastFetchedBlockNumbers = lastFetchedBlockNumbers;
|
|
1562
|
+
});
|
|
1563
|
+
this.messagingSystem.publish(`${controllerName}:incomingTransactionBlockReceived`, blockNumber);
|
|
1490
1564
|
}
|
|
1491
1565
|
generateDappSuggestedGasFees(txParams, origin) {
|
|
1492
1566
|
if (!origin || origin === controller_utils_1.ORIGIN_METAMASK) {
|
|
@@ -1517,6 +1591,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1517
1591
|
* Validates and adds external provided transaction to state.
|
|
1518
1592
|
*
|
|
1519
1593
|
* @param transactionMeta - Nominated external transaction to be added to state.
|
|
1594
|
+
* @returns The new transaction.
|
|
1520
1595
|
*/
|
|
1521
1596
|
addExternalTransaction(transactionMeta) {
|
|
1522
1597
|
var _a, _b;
|
|
@@ -1529,15 +1604,16 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1529
1604
|
const pendingTxs = sameFromAndNetworkTransactions.filter((transaction) => transaction.status === types_1.TransactionStatus.submitted);
|
|
1530
1605
|
(0, external_transactions_1.validateConfirmedExternalTransaction)(transactionMeta, confirmedTxs, pendingTxs);
|
|
1531
1606
|
// Make sure provided external transaction has non empty history array
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1607
|
+
const newTransactionMeta = ((_b = transactionMeta.history) !== null && _b !== void 0 ? _b : []).length === 0 && !this.isHistoryDisabled
|
|
1608
|
+
? (0, history_1.addInitialHistorySnapshot)(transactionMeta)
|
|
1609
|
+
: transactionMeta;
|
|
1610
|
+
this.update((state) => {
|
|
1611
|
+
state.transactions = this.trimTransactionsForState([
|
|
1612
|
+
...state.transactions,
|
|
1613
|
+
newTransactionMeta,
|
|
1614
|
+
]);
|
|
1540
1615
|
});
|
|
1616
|
+
return newTransactionMeta;
|
|
1541
1617
|
}
|
|
1542
1618
|
/**
|
|
1543
1619
|
* Sets other txMeta statuses to dropped if the txMeta that has been confirmed has other transactions
|
|
@@ -1554,20 +1630,26 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1554
1630
|
const nonce = (_a = transactionMeta.txParams) === null || _a === void 0 ? void 0 : _a.nonce;
|
|
1555
1631
|
const from = (_b = transactionMeta.txParams) === null || _b === void 0 ? void 0 : _b.from;
|
|
1556
1632
|
const { chainId } = transactionMeta;
|
|
1557
|
-
const
|
|
1633
|
+
const sameNonceTransactions = this.state.transactions.filter((transaction) => transaction.id !== transactionId &&
|
|
1558
1634
|
transaction.txParams.from === from &&
|
|
1559
1635
|
transaction.txParams.nonce === nonce &&
|
|
1560
1636
|
transaction.chainId === chainId &&
|
|
1561
1637
|
transaction.type !== types_1.TransactionType.incoming);
|
|
1562
|
-
|
|
1638
|
+
const sameNonceTransactionIds = sameNonceTransactions.map((transaction) => transaction.id);
|
|
1639
|
+
if (sameNonceTransactions.length === 0) {
|
|
1563
1640
|
return;
|
|
1564
1641
|
}
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1642
|
+
this.update((state) => {
|
|
1643
|
+
for (const transaction of state.transactions) {
|
|
1644
|
+
if (sameNonceTransactionIds.includes(transaction.id)) {
|
|
1645
|
+
transaction.replacedBy = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.hash;
|
|
1646
|
+
transaction.replacedById = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.id;
|
|
1647
|
+
}
|
|
1648
|
+
}
|
|
1649
|
+
});
|
|
1650
|
+
for (const transaction of this.state.transactions) {
|
|
1651
|
+
if (sameNonceTransactionIds.includes(transaction.id) &&
|
|
1652
|
+
transaction.status !== types_1.TransactionStatus.failed) {
|
|
1571
1653
|
this.setTransactionStatusDropped(transaction);
|
|
1572
1654
|
}
|
|
1573
1655
|
}
|
|
@@ -1578,12 +1660,12 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1578
1660
|
* @param transactionMeta - TransactionMeta of transaction to be marked as dropped.
|
|
1579
1661
|
*/
|
|
1580
1662
|
setTransactionStatusDropped(transactionMeta) {
|
|
1581
|
-
transactionMeta
|
|
1582
|
-
this.
|
|
1583
|
-
transactionMeta,
|
|
1663
|
+
const updatedTransactionMeta = Object.assign(Object.assign({}, transactionMeta), { status: types_1.TransactionStatus.dropped });
|
|
1664
|
+
this.messagingSystem.publish(`${controllerName}:transactionDropped`, {
|
|
1665
|
+
transactionMeta: updatedTransactionMeta,
|
|
1584
1666
|
});
|
|
1585
|
-
this.updateTransaction(
|
|
1586
|
-
this.onTransactionStatusChange(
|
|
1667
|
+
this.updateTransaction(updatedTransactionMeta, 'TransactionController#setTransactionStatusDropped - Transaction dropped');
|
|
1668
|
+
this.onTransactionStatusChange(updatedTransactionMeta);
|
|
1587
1669
|
}
|
|
1588
1670
|
/**
|
|
1589
1671
|
* Get transaction with provided actionId.
|
|
@@ -1597,7 +1679,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1597
1679
|
waitForTransactionFinished(transactionId) {
|
|
1598
1680
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1599
1681
|
return new Promise((resolve) => {
|
|
1600
|
-
this.
|
|
1682
|
+
__classPrivateFieldGet(this, _TransactionController_internalEvents, "f").once(`${transactionId}:finished`, (txMeta) => {
|
|
1601
1683
|
resolve(txMeta);
|
|
1602
1684
|
});
|
|
1603
1685
|
});
|
|
@@ -1612,13 +1694,15 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1612
1694
|
*/
|
|
1613
1695
|
updateTransactionMetaRSV(transactionMeta, signedTx) {
|
|
1614
1696
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1697
|
+
const transactionMetaWithRsv = Object.assign({}, transactionMeta);
|
|
1615
1698
|
for (const key of ['r', 's', 'v']) {
|
|
1616
1699
|
const value = signedTx[key];
|
|
1617
1700
|
if (value === undefined || value === null) {
|
|
1618
1701
|
continue;
|
|
1619
1702
|
}
|
|
1620
|
-
|
|
1703
|
+
transactionMetaWithRsv[key] = (0, utils_1.add0x)(value.toString(16));
|
|
1621
1704
|
}
|
|
1705
|
+
return transactionMetaWithRsv;
|
|
1622
1706
|
});
|
|
1623
1707
|
}
|
|
1624
1708
|
getEIP1559Compatibility(networkClientId) {
|
|
@@ -1648,18 +1732,19 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1648
1732
|
(0, logger_1.projectLogger)('Skipping signed status based on hook');
|
|
1649
1733
|
return undefined;
|
|
1650
1734
|
}
|
|
1651
|
-
yield this.updateTransactionMetaRSV(transactionMeta, signedTx);
|
|
1652
|
-
|
|
1653
|
-
this.
|
|
1654
|
-
this.onTransactionStatusChange(transactionMeta);
|
|
1735
|
+
const transactionMetaWithRsv = Object.assign(Object.assign({}, (yield this.updateTransactionMetaRSV(transactionMeta, signedTx))), { status: types_1.TransactionStatus.signed });
|
|
1736
|
+
this.updateTransaction(transactionMetaWithRsv, 'TransactionController#approveTransaction - Transaction signed');
|
|
1737
|
+
this.onTransactionStatusChange(transactionMetaWithRsv);
|
|
1655
1738
|
const rawTx = (0, util_1.bufferToHex)(signedTx.serialize());
|
|
1656
|
-
|
|
1657
|
-
this.updateTransaction(
|
|
1739
|
+
const transactionMetaWithRawTx = Object.assign(Object.assign({}, transactionMetaWithRsv), { rawTx });
|
|
1740
|
+
this.updateTransaction(transactionMetaWithRawTx, 'TransactionController#approveTransaction - RawTransaction added');
|
|
1658
1741
|
return rawTx;
|
|
1659
1742
|
});
|
|
1660
1743
|
}
|
|
1661
1744
|
onTransactionStatusChange(transactionMeta) {
|
|
1662
|
-
this.
|
|
1745
|
+
this.messagingSystem.publish(`${controllerName}:transactionStatusUpdated`, {
|
|
1746
|
+
transactionMeta,
|
|
1747
|
+
});
|
|
1663
1748
|
}
|
|
1664
1749
|
getNonceTrackerTransactions(status, address, chainId = this.getChainId()) {
|
|
1665
1750
|
return (0, nonce_1.getAndFormatTransactionsForNonceTracker)(chainId, address, status, this.state.transactions);
|
|
@@ -1667,8 +1752,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1667
1752
|
onConfirmedTransaction(transactionMeta) {
|
|
1668
1753
|
(0, logger_1.projectLogger)('Processing confirmed transaction', transactionMeta.id);
|
|
1669
1754
|
this.markNonceDuplicatesDropped(transactionMeta.id);
|
|
1670
|
-
this.
|
|
1671
|
-
this.hub.emit(`${transactionMeta.id}:confirmed`, transactionMeta);
|
|
1755
|
+
this.messagingSystem.publish(`${controllerName}:transactionConfirmed`, transactionMeta);
|
|
1672
1756
|
this.onTransactionStatusChange(transactionMeta);
|
|
1673
1757
|
// Intentional given potential duration of process.
|
|
1674
1758
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
@@ -1689,7 +1773,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1689
1773
|
getTransaction: this.getTransaction.bind(this),
|
|
1690
1774
|
updateTransaction: this.updateTransaction.bind(this),
|
|
1691
1775
|
});
|
|
1692
|
-
this.
|
|
1776
|
+
this.messagingSystem.publish(`${controllerName}:postTransactionBalanceUpdated`, {
|
|
1693
1777
|
transactionMeta: updatedTransactionMeta,
|
|
1694
1778
|
approvalTransactionMeta,
|
|
1695
1779
|
});
|
|
@@ -1731,7 +1815,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1731
1815
|
}
|
|
1732
1816
|
}
|
|
1733
1817
|
exports.TransactionController = TransactionController;
|
|
1734
|
-
_TransactionController_incomingTransactionOptions = new WeakMap(), _TransactionController_pendingTransactionOptions = new WeakMap(), _TransactionController_multichainTrackingHelper = new WeakMap(), _TransactionController_checkForPendingTransactionAndStartPolling = new WeakMap(), _TransactionController_instances = new WeakSet(), _TransactionController_createNonceTracker = function _TransactionController_createNonceTracker({ provider, blockTracker, chainId, }) {
|
|
1818
|
+
_TransactionController_internalEvents = new WeakMap(), _TransactionController_incomingTransactionOptions = new WeakMap(), _TransactionController_pendingTransactionOptions = new WeakMap(), _TransactionController_transactionHistoryLimit = new WeakMap(), _TransactionController_multichainTrackingHelper = new WeakMap(), _TransactionController_checkForPendingTransactionAndStartPolling = new WeakMap(), _TransactionController_instances = new WeakSet(), _TransactionController_createNonceTracker = function _TransactionController_createNonceTracker({ provider, blockTracker, chainId, }) {
|
|
1735
1819
|
return new nonce_tracker_1.NonceTracker({
|
|
1736
1820
|
// TODO: Replace `any` with type
|
|
1737
1821
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -1749,7 +1833,7 @@ _TransactionController_incomingTransactionOptions = new WeakMap(), _TransactionC
|
|
|
1749
1833
|
isEnabled: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").isEnabled,
|
|
1750
1834
|
queryEntireHistory: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").queryEntireHistory,
|
|
1751
1835
|
remoteTransactionSource: etherscanRemoteTransactionSource,
|
|
1752
|
-
transactionLimit: this
|
|
1836
|
+
transactionLimit: __classPrivateFieldGet(this, _TransactionController_transactionHistoryLimit, "f"),
|
|
1753
1837
|
updateTransactions: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").updateTransactions,
|
|
1754
1838
|
});
|
|
1755
1839
|
__classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_addIncomingTransactionHelperListeners).call(this, incomingTransactionHelper);
|
|
@@ -1758,7 +1842,9 @@ _TransactionController_incomingTransactionOptions = new WeakMap(), _TransactionC
|
|
|
1758
1842
|
const ethQuery = new eth_query_1.default(provider);
|
|
1759
1843
|
const getChainId = chainId ? () => chainId : this.getChainId.bind(this);
|
|
1760
1844
|
const pendingTransactionTracker = new PendingTransactionTracker_1.PendingTransactionTracker({
|
|
1761
|
-
approveTransaction: this
|
|
1845
|
+
approveTransaction: (transactionId) => __awaiter(this, void 0, void 0, function* () {
|
|
1846
|
+
yield this.approveTransaction(transactionId);
|
|
1847
|
+
}),
|
|
1762
1848
|
blockTracker,
|
|
1763
1849
|
getChainId,
|
|
1764
1850
|
getEthQuery: () => ethQuery,
|
|
@@ -1804,14 +1890,14 @@ _TransactionController_incomingTransactionOptions = new WeakMap(), _TransactionC
|
|
|
1804
1890
|
}, _TransactionController_getGasFeeFlows = function _TransactionController_getGasFeeFlows() {
|
|
1805
1891
|
return [new LineaGasFeeFlow_1.LineaGasFeeFlow(), new DefaultGasFeeFlow_1.DefaultGasFeeFlow()];
|
|
1806
1892
|
}, _TransactionController_updateTransactionInternal = function _TransactionController_updateTransactionInternal(transactionMeta, { note, skipHistory }) {
|
|
1807
|
-
const
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
(0, history_1.updateTransactionHistory)(
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1893
|
+
const normalizedTransaction = Object.assign(Object.assign({}, transactionMeta), { txParams: (0, utils_2.normalizeTransactionParams)(transactionMeta.txParams) });
|
|
1894
|
+
(0, validation_1.validateTxParams)(normalizedTransaction.txParams);
|
|
1895
|
+
const transactionWithUpdatedHistory = skipHistory === true
|
|
1896
|
+
? normalizedTransaction
|
|
1897
|
+
: (0, history_1.updateTransactionHistory)(normalizedTransaction, note !== null && note !== void 0 ? note : 'Transaction updated');
|
|
1898
|
+
this.update((state) => {
|
|
1899
|
+
const index = state.transactions.findIndex(({ id }) => transactionMeta.id === id);
|
|
1900
|
+
state.transactions[index] = transactionWithUpdatedHistory;
|
|
1901
|
+
});
|
|
1816
1902
|
};
|
|
1817
1903
|
//# sourceMappingURL=TransactionController.js.map
|