@metamask-previews/transaction-controller 24.0.0-preview.6dad403 → 24.0.0-preview.d78968a2
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/dist/TransactionController.d.ts +232 -46
- package/dist/TransactionController.d.ts.map +1 -1
- package/dist/TransactionController.js +302 -210
- package/dist/TransactionController.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 +19 -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 -20
- 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 +14 -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.map +1 -1
- package/dist/utils/utils.js +17 -2
- package/dist/utils/utils.js.map +1 -1
- package/package.json +2 -1
|
@@ -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(() => {
|
|
@@ -204,19 +264,29 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
204
264
|
this.onBootCleanup();
|
|
205
265
|
}
|
|
206
266
|
failTransaction(transactionMeta, error, actionId) {
|
|
207
|
-
const newTransactionMeta =
|
|
208
|
-
|
|
267
|
+
const newTransactionMeta = (0, lodash_1.merge)({}, transactionMeta, {
|
|
268
|
+
error: (0, utils_2.normalizeTxError)(error),
|
|
269
|
+
status: types_1.TransactionStatus.failed,
|
|
270
|
+
});
|
|
271
|
+
this.messagingSystem.publish(`${controllerName}:transactionFailed`, {
|
|
209
272
|
actionId,
|
|
210
273
|
error: error.message,
|
|
211
274
|
transactionMeta: newTransactionMeta,
|
|
212
275
|
});
|
|
213
276
|
this.updateTransaction(newTransactionMeta, 'TransactionController#failTransaction - Add error message and set status to failed');
|
|
214
277
|
this.onTransactionStatusChange(newTransactionMeta);
|
|
215
|
-
this.
|
|
278
|
+
this.messagingSystem.publish(`${controllerName}:transactionFinished`, newTransactionMeta);
|
|
279
|
+
__classPrivateFieldGet(this, _TransactionController_internalEvents, "f").emit(`${transactionMeta.id}:finished`, newTransactionMeta);
|
|
216
280
|
}
|
|
217
281
|
registryLookup(fourBytePrefix) {
|
|
218
282
|
return __awaiter(this, void 0, void 0, function* () {
|
|
219
283
|
const registryMethod = yield this.registry.lookup(fourBytePrefix);
|
|
284
|
+
if (!registryMethod) {
|
|
285
|
+
return {
|
|
286
|
+
registryMethod: '',
|
|
287
|
+
parsedRegistryMethod: { name: undefined, args: undefined },
|
|
288
|
+
};
|
|
289
|
+
}
|
|
220
290
|
const parsedRegistryMethod = this.registry.parse(registryMethod);
|
|
221
291
|
return { registryMethod, parsedRegistryMethod };
|
|
222
292
|
});
|
|
@@ -243,8 +313,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
243
313
|
return methodData[fourBytePrefix];
|
|
244
314
|
}
|
|
245
315
|
const registry = yield this.registryLookup(fourBytePrefix);
|
|
246
|
-
this.update({
|
|
247
|
-
|
|
316
|
+
this.update((state) => {
|
|
317
|
+
state.methodData[fourBytePrefix] = registry;
|
|
248
318
|
});
|
|
249
319
|
return registry;
|
|
250
320
|
}
|
|
@@ -296,55 +366,56 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
296
366
|
const transactionType = type !== null && type !== void 0 ? type : (yield (0, transaction_type_1.determineTransactionType)(txParams, ethQuery)).type;
|
|
297
367
|
const existingTransactionMeta = this.getTransactionWithActionId(actionId);
|
|
298
368
|
// If a request to add a transaction with the same actionId is submitted again, a new transaction will not be created for it.
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
369
|
+
let addedTransactionMeta = existingTransactionMeta
|
|
370
|
+
? (0, lodash_1.cloneDeep)(existingTransactionMeta)
|
|
371
|
+
: {
|
|
372
|
+
// Add actionId to txMeta to check if same actionId is seen again
|
|
373
|
+
actionId,
|
|
374
|
+
chainId,
|
|
375
|
+
dappSuggestedGasFees,
|
|
376
|
+
deviceConfirmedOn,
|
|
377
|
+
id: (0, uuid_1.v1)(),
|
|
378
|
+
origin,
|
|
379
|
+
securityAlertResponse,
|
|
380
|
+
status: types_1.TransactionStatus.unapproved,
|
|
381
|
+
time: Date.now(),
|
|
382
|
+
txParams,
|
|
383
|
+
userEditedGasLimit: false,
|
|
384
|
+
verifiedOnBlockchain: false,
|
|
385
|
+
type: transactionType,
|
|
386
|
+
networkClientId,
|
|
387
|
+
};
|
|
388
|
+
yield this.updateGasProperties(addedTransactionMeta);
|
|
317
389
|
// Checks if a transaction already exists with a given actionId
|
|
318
390
|
if (!existingTransactionMeta) {
|
|
319
391
|
// Set security provider response
|
|
320
392
|
if (method && this.securityProviderRequest) {
|
|
321
|
-
const securityProviderResponse = yield this.securityProviderRequest(
|
|
322
|
-
|
|
393
|
+
const securityProviderResponse = yield this.securityProviderRequest(addedTransactionMeta, method);
|
|
394
|
+
addedTransactionMeta.securityProviderResponse =
|
|
395
|
+
securityProviderResponse;
|
|
323
396
|
}
|
|
324
397
|
if (!this.isSendFlowHistoryDisabled) {
|
|
325
|
-
|
|
398
|
+
addedTransactionMeta.sendFlowHistory = sendFlowHistory !== null && sendFlowHistory !== void 0 ? sendFlowHistory : [];
|
|
326
399
|
}
|
|
327
400
|
// Initial history push
|
|
328
401
|
if (!this.isHistoryDisabled) {
|
|
329
|
-
(0, history_1.addInitialHistorySnapshot)(
|
|
402
|
+
addedTransactionMeta = (0, history_1.addInitialHistorySnapshot)(addedTransactionMeta);
|
|
330
403
|
}
|
|
331
|
-
|
|
404
|
+
addedTransactionMeta = (0, swaps_1.updateSwapsTransaction)(addedTransactionMeta, transactionType, swaps, {
|
|
332
405
|
isSwapsDisabled: this.isSwapsDisabled,
|
|
333
406
|
cancelTransaction: this.cancelTransaction.bind(this),
|
|
334
|
-
|
|
335
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
336
|
-
controllerHubEmitter: this.hub.emit.bind(this.hub),
|
|
407
|
+
messenger: this.messagingSystem,
|
|
337
408
|
});
|
|
338
|
-
this.addMetadata(
|
|
339
|
-
this.
|
|
409
|
+
this.addMetadata(addedTransactionMeta);
|
|
410
|
+
this.messagingSystem.publish(`${controllerName}:unapprovedTransactionAdded`, addedTransactionMeta);
|
|
340
411
|
}
|
|
341
412
|
return {
|
|
342
|
-
result: this.processApproval(
|
|
413
|
+
result: this.processApproval(addedTransactionMeta, {
|
|
343
414
|
isExisting: Boolean(existingTransactionMeta),
|
|
344
415
|
requireApproval,
|
|
345
416
|
actionId,
|
|
346
417
|
}),
|
|
347
|
-
transactionMeta,
|
|
418
|
+
transactionMeta: addedTransactionMeta,
|
|
348
419
|
};
|
|
349
420
|
});
|
|
350
421
|
}
|
|
@@ -476,15 +547,16 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
476
547
|
};
|
|
477
548
|
this.addMetadata(cancelTransactionMeta);
|
|
478
549
|
// stopTransaction has no approval request, so we assume the user has already approved the transaction
|
|
479
|
-
this.
|
|
550
|
+
this.messagingSystem.publish(`${controllerName}:transactionApproved`, {
|
|
480
551
|
transactionMeta: cancelTransactionMeta,
|
|
481
552
|
actionId,
|
|
482
553
|
});
|
|
483
|
-
this.
|
|
554
|
+
this.messagingSystem.publish(`${controllerName}:transactionSubmitted`, {
|
|
484
555
|
transactionMeta: cancelTransactionMeta,
|
|
485
556
|
actionId,
|
|
486
557
|
});
|
|
487
|
-
this.
|
|
558
|
+
this.messagingSystem.publish(`${controllerName}:transactionFinished`, cancelTransactionMeta);
|
|
559
|
+
__classPrivateFieldGet(this, _TransactionController_internalEvents, "f").emit(`${transactionMeta.id}:finished`, cancelTransactionMeta);
|
|
488
560
|
});
|
|
489
561
|
}
|
|
490
562
|
/**
|
|
@@ -542,33 +614,33 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
542
614
|
? 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
615
|
const unsignedEthTx = this.prepareUnsignedEthTx(transactionMeta.chainId, txParams);
|
|
544
616
|
const signedTx = yield this.sign(unsignedEthTx, transactionMeta.txParams.from);
|
|
545
|
-
yield this.updateTransactionMetaRSV(transactionMeta, signedTx);
|
|
617
|
+
const transactionMetaWithRsv = yield this.updateTransactionMetaRSV(transactionMeta, signedTx);
|
|
546
618
|
const rawTx = (0, util_1.bufferToHex)(signedTx.serialize());
|
|
547
619
|
const newFee = (_c = txParams.maxFeePerGas) !== null && _c !== void 0 ? _c : txParams.gasPrice;
|
|
548
620
|
const oldFee = txParams.maxFeePerGas
|
|
549
|
-
?
|
|
550
|
-
:
|
|
621
|
+
? transactionMetaWithRsv.txParams.maxFeePerGas
|
|
622
|
+
: transactionMetaWithRsv.txParams.gasPrice;
|
|
551
623
|
(0, logger_1.projectLogger)('Submitting speed up transaction', { oldFee, newFee, txParams });
|
|
552
624
|
const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
553
625
|
networkClientId: transactionMeta.networkClientId,
|
|
554
626
|
chainId: transactionMeta.chainId,
|
|
555
627
|
});
|
|
556
628
|
const hash = yield this.publishTransactionForRetry(ethQuery, rawTx, transactionMeta);
|
|
557
|
-
const baseTransactionMeta = Object.assign(Object.assign({},
|
|
629
|
+
const baseTransactionMeta = Object.assign(Object.assign({}, transactionMetaWithRsv), { estimatedBaseFee, id: (0, uuid_1.v1)(), time: Date.now(), hash,
|
|
558
630
|
actionId, originalGasEstimate: transactionMeta.txParams.gas, type: types_1.TransactionType.retry, originalType: transactionMeta.type });
|
|
559
631
|
const newTransactionMeta = newMaxFeePerGas && newMaxPriorityFeePerGas
|
|
560
632
|
? 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
633
|
this.addMetadata(newTransactionMeta);
|
|
562
634
|
// speedUpTransaction has no approval request, so we assume the user has already approved the transaction
|
|
563
|
-
this.
|
|
635
|
+
this.messagingSystem.publish(`${controllerName}:transactionApproved`, {
|
|
564
636
|
transactionMeta: newTransactionMeta,
|
|
565
637
|
actionId,
|
|
566
638
|
});
|
|
567
|
-
this.
|
|
639
|
+
this.messagingSystem.publish(`${controllerName}:transactionSubmitted`, {
|
|
568
640
|
transactionMeta: newTransactionMeta,
|
|
569
641
|
actionId,
|
|
570
642
|
});
|
|
571
|
-
this.
|
|
643
|
+
this.messagingSystem.publish(`${controllerName}:speedupTransactionAdded`, newTransactionMeta);
|
|
572
644
|
});
|
|
573
645
|
}
|
|
574
646
|
/**
|
|
@@ -633,8 +705,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
633
705
|
if (!transactionMeta) {
|
|
634
706
|
throw new Error(`Cannot update security alert response as no transaction metadata found`);
|
|
635
707
|
}
|
|
636
|
-
const
|
|
637
|
-
this.updateTransaction(
|
|
708
|
+
const updatedTransactionMeta = Object.assign(Object.assign({}, transactionMeta), { securityAlertResponse });
|
|
709
|
+
this.updateTransaction(updatedTransactionMeta, `${controllerName}:updatesecurityAlertResponse - securityAlertResponse updated`);
|
|
638
710
|
}
|
|
639
711
|
/**
|
|
640
712
|
* Removes all transactions from state, optionally based on the current network.
|
|
@@ -647,7 +719,9 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
647
719
|
wipeTransactions(ignoreNetwork, address) {
|
|
648
720
|
/* istanbul ignore next */
|
|
649
721
|
if (ignoreNetwork && !address) {
|
|
650
|
-
this.update(
|
|
722
|
+
this.update((state) => {
|
|
723
|
+
state.transactions = [];
|
|
724
|
+
});
|
|
651
725
|
return;
|
|
652
726
|
}
|
|
653
727
|
const currentChainId = this.getChainId();
|
|
@@ -660,8 +734,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
660
734
|
const isMatchingAddress = !address || ((_a = txParams.from) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === address.toLowerCase();
|
|
661
735
|
return !isMatchingAddress;
|
|
662
736
|
});
|
|
663
|
-
this.update({
|
|
664
|
-
transactions
|
|
737
|
+
this.update((state) => {
|
|
738
|
+
state.transactions = this.trimTransactionsForState(newTransactions);
|
|
665
739
|
});
|
|
666
740
|
}
|
|
667
741
|
/**
|
|
@@ -674,26 +748,23 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
674
748
|
confirmExternalTransaction(transactionMeta, transactionReceipt, baseFeePerGas) {
|
|
675
749
|
return __awaiter(this, void 0, void 0, function* () {
|
|
676
750
|
// Run validation and add external transaction to state.
|
|
677
|
-
this.addExternalTransaction(transactionMeta);
|
|
751
|
+
const newTransactionMeta = this.addExternalTransaction(transactionMeta);
|
|
678
752
|
try {
|
|
679
|
-
const transactionId =
|
|
753
|
+
const transactionId = newTransactionMeta.id;
|
|
680
754
|
// Make sure status is confirmed and define gasUsed as in receipt.
|
|
681
|
-
|
|
682
|
-
transactionMeta.txReceipt = transactionReceipt;
|
|
755
|
+
const updatedTransactionMeta = Object.assign(Object.assign({}, newTransactionMeta), { status: types_1.TransactionStatus.confirmed, txReceipt: transactionReceipt });
|
|
683
756
|
if (baseFeePerGas) {
|
|
684
|
-
|
|
757
|
+
updatedTransactionMeta.baseFeePerGas = baseFeePerGas;
|
|
685
758
|
}
|
|
686
759
|
// Update same nonce local transactions as dropped and define replacedBy properties.
|
|
687
760
|
this.markNonceDuplicatesDropped(transactionId);
|
|
688
761
|
// Update external provided transaction with updated gas values and confirmed status.
|
|
689
|
-
this.updateTransaction(
|
|
690
|
-
this.onTransactionStatusChange(
|
|
762
|
+
this.updateTransaction(updatedTransactionMeta, `${controllerName}:confirmExternalTransaction - Add external transaction`);
|
|
763
|
+
this.onTransactionStatusChange(updatedTransactionMeta);
|
|
691
764
|
// Intentional given potential duration of process.
|
|
692
765
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
693
|
-
this.updatePostBalance(
|
|
694
|
-
this.
|
|
695
|
-
transactionMeta,
|
|
696
|
-
});
|
|
766
|
+
this.updatePostBalance(updatedTransactionMeta);
|
|
767
|
+
this.messagingSystem.publish(`${controllerName}:transactionConfirmed`, updatedTransactionMeta);
|
|
697
768
|
}
|
|
698
769
|
catch (error) {
|
|
699
770
|
console.error('Failed to confirm external transaction', error);
|
|
@@ -709,7 +780,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
709
780
|
* @returns The updated transactionMeta.
|
|
710
781
|
*/
|
|
711
782
|
updateTransactionSendFlowHistory(transactionID, currentSendFlowHistoryLength, sendFlowHistoryToAdd) {
|
|
712
|
-
var _a
|
|
783
|
+
var _a;
|
|
713
784
|
if (this.isSendFlowHistoryDisabled) {
|
|
714
785
|
throw new Error('Send flow history is disabled for the current transaction controller');
|
|
715
786
|
}
|
|
@@ -718,13 +789,10 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
718
789
|
throw new Error(`Cannot update send flow history as no transaction metadata found`);
|
|
719
790
|
}
|
|
720
791
|
(0, utils_2.validateIfTransactionUnapproved)(transactionMeta, 'updateTransactionSendFlowHistory');
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
transactionMeta
|
|
724
|
-
|
|
725
|
-
...sendFlowHistoryToAdd,
|
|
726
|
-
];
|
|
727
|
-
this.updateTransaction(transactionMeta, 'TransactionController:updateTransactionSendFlowHistory - sendFlowHistory updated');
|
|
792
|
+
const sendFlowHistory = (_a = transactionMeta.sendFlowHistory) !== null && _a !== void 0 ? _a : [];
|
|
793
|
+
if (currentSendFlowHistoryLength === sendFlowHistory.length) {
|
|
794
|
+
const updatedTransactionMeta = Object.assign(Object.assign({}, transactionMeta), { sendFlowHistory: [...sendFlowHistory, ...sendFlowHistoryToAdd] });
|
|
795
|
+
this.updateTransaction(updatedTransactionMeta, `${controllerName}:updateTransactionSendFlowHistory - sendFlowHistory updated`);
|
|
728
796
|
}
|
|
729
797
|
return this.getTransaction(transactionID);
|
|
730
798
|
}
|
|
@@ -773,8 +841,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
773
841
|
transactionGasFees.txParams = (0, lodash_1.pickBy)(transactionGasFees.txParams);
|
|
774
842
|
transactionGasFees = (0, lodash_1.pickBy)(transactionGasFees);
|
|
775
843
|
// merge updated gas values with existing transaction meta
|
|
776
|
-
const updatedMeta = (0, lodash_1.merge)(transactionMeta, transactionGasFees);
|
|
777
|
-
this.updateTransaction(updatedMeta,
|
|
844
|
+
const updatedMeta = (0, lodash_1.merge)({}, transactionMeta, transactionGasFees);
|
|
845
|
+
this.updateTransaction(updatedMeta, `${controllerName}:updateTransactionGasFees - gas values updated`);
|
|
778
846
|
return this.getTransaction(transactionId);
|
|
779
847
|
}
|
|
780
848
|
/**
|
|
@@ -805,8 +873,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
805
873
|
// only update what is defined
|
|
806
874
|
transactionPreviousGas.previousGas = (0, lodash_1.pickBy)(transactionPreviousGas.previousGas);
|
|
807
875
|
// merge updated previous gas values with existing transaction meta
|
|
808
|
-
const updatedMeta = (0, lodash_1.merge)(transactionMeta, transactionPreviousGas);
|
|
809
|
-
this.updateTransaction(updatedMeta,
|
|
876
|
+
const updatedMeta = (0, lodash_1.merge)({}, transactionMeta, transactionPreviousGas);
|
|
877
|
+
this.updateTransaction(updatedMeta, `${controllerName}:updatePreviousGasParams - Previous gas values updated`);
|
|
810
878
|
return this.getTransaction(transactionId);
|
|
811
879
|
}
|
|
812
880
|
getNonceLock(address, networkClientId) {
|
|
@@ -845,7 +913,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
845
913
|
},
|
|
846
914
|
};
|
|
847
915
|
editableParams.txParams = (0, lodash_1.pickBy)(editableParams.txParams);
|
|
848
|
-
const updatedTransaction = (0, lodash_1.merge)(transactionMeta, editableParams);
|
|
916
|
+
const updatedTransaction = (0, lodash_1.merge)({}, transactionMeta, editableParams);
|
|
849
917
|
const { type } = yield (0, transaction_type_1.determineTransactionType)(updatedTransaction.txParams, __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
850
918
|
networkClientId: transactionMeta.networkClientId,
|
|
851
919
|
chainId: transactionMeta.chainId,
|
|
@@ -950,16 +1018,16 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
950
1018
|
].includes(status)) {
|
|
951
1019
|
throw new Error(`Cannot update custodial transaction with status: ${status}`);
|
|
952
1020
|
}
|
|
953
|
-
const updatedTransactionMeta = (0, lodash_1.merge)(transactionMeta, (0, lodash_1.pickBy)({ hash, status }));
|
|
1021
|
+
const updatedTransactionMeta = (0, lodash_1.merge)({}, transactionMeta, (0, lodash_1.pickBy)({ hash, status }));
|
|
954
1022
|
if (status === types_1.TransactionStatus.submitted) {
|
|
955
1023
|
updatedTransactionMeta.submittedTime = new Date().getTime();
|
|
956
1024
|
}
|
|
957
1025
|
if (status === types_1.TransactionStatus.failed) {
|
|
958
1026
|
updatedTransactionMeta.error = (0, utils_2.normalizeTxError)(new Error(errorMessage));
|
|
959
1027
|
}
|
|
960
|
-
this.updateTransaction(updatedTransactionMeta,
|
|
1028
|
+
this.updateTransaction(updatedTransactionMeta, `${controllerName}:updateCustodialTransaction - Custodial transaction updated`);
|
|
961
1029
|
if ([types_1.TransactionStatus.submitted, types_1.TransactionStatus.failed].includes(status)) {
|
|
962
|
-
this.
|
|
1030
|
+
this.messagingSystem.publish(`${controllerName}:transactionFinished`, updatedTransactionMeta);
|
|
963
1031
|
}
|
|
964
1032
|
}
|
|
965
1033
|
/**
|
|
@@ -1090,7 +1158,9 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1090
1158
|
*/
|
|
1091
1159
|
clearUnapprovedTransactions() {
|
|
1092
1160
|
const transactions = this.state.transactions.filter(({ status }) => status !== types_1.TransactionStatus.unapproved);
|
|
1093
|
-
this.update(
|
|
1161
|
+
this.update((state) => {
|
|
1162
|
+
state.transactions = this.trimTransactionsForState(transactions);
|
|
1163
|
+
});
|
|
1094
1164
|
}
|
|
1095
1165
|
/**
|
|
1096
1166
|
* Stop the signing process for a specific transaction.
|
|
@@ -1110,9 +1180,12 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1110
1180
|
this.signAbortCallbacks.delete(transactionId);
|
|
1111
1181
|
}
|
|
1112
1182
|
addMetadata(transactionMeta) {
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1183
|
+
this.update((state) => {
|
|
1184
|
+
state.transactions = this.trimTransactionsForState([
|
|
1185
|
+
...state.transactions,
|
|
1186
|
+
transactionMeta,
|
|
1187
|
+
]);
|
|
1188
|
+
});
|
|
1116
1189
|
}
|
|
1117
1190
|
updateGasProperties(transactionMeta) {
|
|
1118
1191
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1176,13 +1249,6 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1176
1249
|
shouldShowRequest,
|
|
1177
1250
|
});
|
|
1178
1251
|
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
1252
|
const approvalValue = acceptResult.value;
|
|
1187
1253
|
const updatedTransaction = approvalValue === null || approvalValue === void 0 ? void 0 : approvalValue.txMeta;
|
|
1188
1254
|
if (updatedTransaction) {
|
|
@@ -1195,9 +1261,13 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1195
1261
|
}
|
|
1196
1262
|
const { isCompleted: isTxCompleted } = this.isTransactionCompleted(transactionId);
|
|
1197
1263
|
if (!isTxCompleted) {
|
|
1198
|
-
yield this.approveTransaction(transactionId);
|
|
1264
|
+
const approvalResult = yield this.approveTransaction(transactionId);
|
|
1265
|
+
if (approvalResult === ApprovalState.SkippedViaBeforePublishHook &&
|
|
1266
|
+
resultCallbacks) {
|
|
1267
|
+
resultCallbacks.success();
|
|
1268
|
+
}
|
|
1199
1269
|
const updatedTransactionMeta = this.getTransaction(transactionId);
|
|
1200
|
-
this.
|
|
1270
|
+
this.messagingSystem.publish(`${controllerName}:transactionApproved`, {
|
|
1201
1271
|
transactionMeta: updatedTransactionMeta,
|
|
1202
1272
|
actionId,
|
|
1203
1273
|
});
|
|
@@ -1247,42 +1317,42 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1247
1317
|
const releaseLock = yield this.mutex.acquire();
|
|
1248
1318
|
const index = transactions.findIndex(({ id }) => transactionId === id);
|
|
1249
1319
|
const transactionMeta = transactions[index];
|
|
1320
|
+
const updatedTransactionMeta = (0, lodash_1.cloneDeep)(transactionMeta);
|
|
1250
1321
|
const { txParams: { from }, networkClientId, } = transactionMeta;
|
|
1251
1322
|
let releaseNonceLock;
|
|
1252
1323
|
try {
|
|
1253
1324
|
if (!this.sign) {
|
|
1254
1325
|
releaseLock();
|
|
1255
1326
|
this.failTransaction(transactionMeta, new Error('No sign method defined.'));
|
|
1256
|
-
return;
|
|
1327
|
+
return ApprovalState.NotApproved;
|
|
1257
1328
|
}
|
|
1258
1329
|
else if (!transactionMeta.chainId) {
|
|
1259
1330
|
releaseLock();
|
|
1260
1331
|
this.failTransaction(transactionMeta, new Error('No chainId defined.'));
|
|
1261
|
-
return;
|
|
1332
|
+
return ApprovalState.NotApproved;
|
|
1262
1333
|
}
|
|
1263
1334
|
if (this.inProcessOfSigning.has(transactionId)) {
|
|
1264
1335
|
(0, logger_1.projectLogger)('Skipping approval as signing in progress', transactionId);
|
|
1265
|
-
return;
|
|
1336
|
+
return ApprovalState.NotApproved;
|
|
1266
1337
|
}
|
|
1267
1338
|
const [nonce, releaseNonce] = yield (0, nonce_1.getNextNonce)(transactionMeta, (address) => __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getNonceLock(address, networkClientId));
|
|
1268
1339
|
releaseNonceLock = releaseNonce;
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
this.
|
|
1274
|
-
|
|
1275
|
-
const isEIP1559 = (0, utils_2.isEIP1559Transaction)(transactionMeta.txParams);
|
|
1340
|
+
updatedTransactionMeta.status = types_1.TransactionStatus.approved;
|
|
1341
|
+
updatedTransactionMeta.txParams = Object.assign(Object.assign({}, updatedTransactionMeta.txParams), { nonce, chainId: transactionMeta.chainId });
|
|
1342
|
+
const baseTxParams = Object.assign(Object.assign({}, updatedTransactionMeta.txParams), { gasLimit: updatedTransactionMeta.txParams.gas });
|
|
1343
|
+
this.updateTransaction(updatedTransactionMeta, 'TransactionController#approveTransaction - Transaction approved');
|
|
1344
|
+
this.onTransactionStatusChange(updatedTransactionMeta);
|
|
1345
|
+
const isEIP1559 = (0, utils_2.isEIP1559Transaction)(updatedTransactionMeta.txParams);
|
|
1276
1346
|
const txParams = isEIP1559
|
|
1277
|
-
? Object.assign(Object.assign({}, baseTxParams), { estimatedBaseFee:
|
|
1278
|
-
const rawTx = yield this.signTransaction(
|
|
1279
|
-
if (!this.beforePublish(
|
|
1347
|
+
? Object.assign(Object.assign({}, baseTxParams), { estimatedBaseFee: updatedTransactionMeta.txParams.estimatedBaseFee, type: types_1.TransactionEnvelopeType.feeMarket }) : baseTxParams;
|
|
1348
|
+
const rawTx = yield this.signTransaction(updatedTransactionMeta, txParams);
|
|
1349
|
+
if (!this.beforePublish(updatedTransactionMeta)) {
|
|
1280
1350
|
(0, logger_1.projectLogger)('Skipping publishing transaction based on hook');
|
|
1281
|
-
this.
|
|
1282
|
-
return;
|
|
1351
|
+
this.messagingSystem.publish(`${controllerName}:transactionPublishingSkipped`, updatedTransactionMeta);
|
|
1352
|
+
return ApprovalState.SkippedViaBeforePublishHook;
|
|
1283
1353
|
}
|
|
1284
1354
|
if (!rawTx) {
|
|
1285
|
-
return;
|
|
1355
|
+
return ApprovalState.NotApproved;
|
|
1286
1356
|
}
|
|
1287
1357
|
const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
1288
1358
|
networkClientId: transactionMeta.networkClientId,
|
|
@@ -1291,8 +1361,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1291
1361
|
if (transactionMeta.type === types_1.TransactionType.swap) {
|
|
1292
1362
|
(0, logger_1.projectLogger)('Determining pre-transaction balance');
|
|
1293
1363
|
const preTxBalance = yield (0, controller_utils_1.query)(ethQuery, 'getBalance', [from]);
|
|
1294
|
-
|
|
1295
|
-
(0, logger_1.projectLogger)('Updated pre-transaction balance',
|
|
1364
|
+
updatedTransactionMeta.preTxBalance = preTxBalance;
|
|
1365
|
+
(0, logger_1.projectLogger)('Updated pre-transaction balance', updatedTransactionMeta.preTxBalance);
|
|
1296
1366
|
}
|
|
1297
1367
|
(0, logger_1.projectLogger)('Publishing transaction', txParams);
|
|
1298
1368
|
let { transactionHash: hash } = yield this.publish(transactionMeta, rawTx);
|
|
@@ -1300,20 +1370,23 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1300
1370
|
hash = yield this.publishTransaction(ethQuery, rawTx);
|
|
1301
1371
|
}
|
|
1302
1372
|
(0, logger_1.projectLogger)('Publish successful', hash);
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
this.updateTransaction(
|
|
1307
|
-
this.
|
|
1308
|
-
transactionMeta,
|
|
1373
|
+
updatedTransactionMeta.hash = hash;
|
|
1374
|
+
updatedTransactionMeta.status = types_1.TransactionStatus.submitted;
|
|
1375
|
+
updatedTransactionMeta.submittedTime = new Date().getTime();
|
|
1376
|
+
this.updateTransaction(updatedTransactionMeta, 'TransactionController#approveTransaction - Transaction submitted');
|
|
1377
|
+
this.messagingSystem.publish(`${controllerName}:transactionSubmitted`, {
|
|
1378
|
+
transactionMeta: updatedTransactionMeta,
|
|
1309
1379
|
});
|
|
1310
|
-
this.
|
|
1311
|
-
this.
|
|
1380
|
+
this.messagingSystem.publish(`${controllerName}:transactionFinished`, updatedTransactionMeta);
|
|
1381
|
+
__classPrivateFieldGet(this, _TransactionController_internalEvents, "f").emit(`${updatedTransactionMeta.id}:finished`, updatedTransactionMeta);
|
|
1382
|
+
this.onTransactionStatusChange(updatedTransactionMeta);
|
|
1383
|
+
return ApprovalState.Approved;
|
|
1312
1384
|
// TODO: Replace `any` with type
|
|
1313
1385
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1314
1386
|
}
|
|
1315
1387
|
catch (error) {
|
|
1316
1388
|
this.failTransaction(transactionMeta, error);
|
|
1389
|
+
return ApprovalState.NotApproved;
|
|
1317
1390
|
}
|
|
1318
1391
|
finally {
|
|
1319
1392
|
this.inProcessOfSigning.delete(transactionId);
|
|
@@ -1340,15 +1413,18 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1340
1413
|
if (!transactionMeta) {
|
|
1341
1414
|
return;
|
|
1342
1415
|
}
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1416
|
+
this.update((state) => {
|
|
1417
|
+
const transactions = state.transactions.filter(({ id }) => id !== transactionId);
|
|
1418
|
+
state.transactions = this.trimTransactionsForState(transactions);
|
|
1419
|
+
});
|
|
1420
|
+
const updatedTransactionMeta = Object.assign(Object.assign({}, transactionMeta), { status: types_1.TransactionStatus.rejected });
|
|
1421
|
+
this.messagingSystem.publish(`${controllerName}:transactionFinished`, updatedTransactionMeta);
|
|
1422
|
+
__classPrivateFieldGet(this, _TransactionController_internalEvents, "f").emit(`${transactionMeta.id}:finished`, updatedTransactionMeta);
|
|
1423
|
+
this.messagingSystem.publish(`${controllerName}:transactionRejected`, {
|
|
1424
|
+
transactionMeta: updatedTransactionMeta,
|
|
1349
1425
|
actionId,
|
|
1350
1426
|
});
|
|
1351
|
-
this.onTransactionStatusChange(
|
|
1427
|
+
this.onTransactionStatusChange(updatedTransactionMeta);
|
|
1352
1428
|
}
|
|
1353
1429
|
/**
|
|
1354
1430
|
* Trim the amount of transactions that are set on the state. Checks
|
|
@@ -1357,25 +1433,25 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1357
1433
|
* Pending or unapproved transactions will not be removed by this
|
|
1358
1434
|
* operation. For safety of presenting a fully functional transaction UI
|
|
1359
1435
|
* 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
|
-
*
|
|
1436
|
+
* same nonce, created on the same day, per network. Not accounting for
|
|
1437
|
+
* transactions of the same nonce, same day and network combo can result in
|
|
1438
|
+
* confusing or broken experiences in the UI.
|
|
1363
1439
|
*
|
|
1364
1440
|
* @param transactions - The transactions to be applied to the state.
|
|
1365
1441
|
* @returns The trimmed list of transactions.
|
|
1366
1442
|
*/
|
|
1367
1443
|
trimTransactionsForState(transactions) {
|
|
1368
1444
|
const nonceNetworkSet = new Set();
|
|
1369
|
-
const txsToKeep = transactions
|
|
1445
|
+
const txsToKeep = [...transactions]
|
|
1370
1446
|
.sort((a, b) => (a.time > b.time ? -1 : 1)) // Descending time order
|
|
1371
1447
|
.filter((tx) => {
|
|
1372
1448
|
const { chainId, status, txParams, time } = tx;
|
|
1373
1449
|
if (txParams) {
|
|
1374
|
-
const key = `${txParams.nonce}-${(0, controller_utils_1.convertHexToDecimal)(chainId)}-${new Date(time).toDateString()}`;
|
|
1450
|
+
const key = `${String(txParams.nonce)}-${(0, controller_utils_1.convertHexToDecimal)(chainId)}-${new Date(time).toDateString()}`;
|
|
1375
1451
|
if (nonceNetworkSet.has(key)) {
|
|
1376
1452
|
return true;
|
|
1377
1453
|
}
|
|
1378
|
-
else if (nonceNetworkSet.size < this
|
|
1454
|
+
else if (nonceNetworkSet.size < __classPrivateFieldGet(this, _TransactionController_transactionHistoryLimit, "f") ||
|
|
1379
1455
|
!this.isFinalState(status)) {
|
|
1380
1456
|
nonceNetworkSet.add(key);
|
|
1381
1457
|
return true;
|
|
@@ -1472,21 +1548,23 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1472
1548
|
return common_1.Common.custom(customChainParams);
|
|
1473
1549
|
}
|
|
1474
1550
|
onIncomingTransactions({ added, updated, }) {
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
transactions
|
|
1551
|
+
this.update((state) => {
|
|
1552
|
+
const { transactions: currentTransactions } = state;
|
|
1553
|
+
const updatedTransactions = [
|
|
1554
|
+
...added,
|
|
1555
|
+
...currentTransactions.map((originalTransaction) => {
|
|
1556
|
+
const updatedTransaction = updated.find(({ hash }) => hash === originalTransaction.hash);
|
|
1557
|
+
return updatedTransaction !== null && updatedTransaction !== void 0 ? updatedTransaction : originalTransaction;
|
|
1558
|
+
}),
|
|
1559
|
+
];
|
|
1560
|
+
state.transactions = this.trimTransactionsForState(updatedTransactions);
|
|
1485
1561
|
});
|
|
1486
1562
|
}
|
|
1487
1563
|
onUpdatedLastFetchedBlockNumbers({ lastFetchedBlockNumbers, blockNumber, }) {
|
|
1488
|
-
this.update(
|
|
1489
|
-
|
|
1564
|
+
this.update((state) => {
|
|
1565
|
+
state.lastFetchedBlockNumbers = lastFetchedBlockNumbers;
|
|
1566
|
+
});
|
|
1567
|
+
this.messagingSystem.publish(`${controllerName}:incomingTransactionBlockReceived`, blockNumber);
|
|
1490
1568
|
}
|
|
1491
1569
|
generateDappSuggestedGasFees(txParams, origin) {
|
|
1492
1570
|
if (!origin || origin === controller_utils_1.ORIGIN_METAMASK) {
|
|
@@ -1517,6 +1595,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1517
1595
|
* Validates and adds external provided transaction to state.
|
|
1518
1596
|
*
|
|
1519
1597
|
* @param transactionMeta - Nominated external transaction to be added to state.
|
|
1598
|
+
* @returns The new transaction.
|
|
1520
1599
|
*/
|
|
1521
1600
|
addExternalTransaction(transactionMeta) {
|
|
1522
1601
|
var _a, _b;
|
|
@@ -1529,15 +1608,16 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1529
1608
|
const pendingTxs = sameFromAndNetworkTransactions.filter((transaction) => transaction.status === types_1.TransactionStatus.submitted);
|
|
1530
1609
|
(0, external_transactions_1.validateConfirmedExternalTransaction)(transactionMeta, confirmedTxs, pendingTxs);
|
|
1531
1610
|
// Make sure provided external transaction has non empty history array
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1611
|
+
const newTransactionMeta = ((_b = transactionMeta.history) !== null && _b !== void 0 ? _b : []).length === 0 && !this.isHistoryDisabled
|
|
1612
|
+
? (0, history_1.addInitialHistorySnapshot)(transactionMeta)
|
|
1613
|
+
: transactionMeta;
|
|
1614
|
+
this.update((state) => {
|
|
1615
|
+
state.transactions = this.trimTransactionsForState([
|
|
1616
|
+
...state.transactions,
|
|
1617
|
+
newTransactionMeta,
|
|
1618
|
+
]);
|
|
1540
1619
|
});
|
|
1620
|
+
return newTransactionMeta;
|
|
1541
1621
|
}
|
|
1542
1622
|
/**
|
|
1543
1623
|
* Sets other txMeta statuses to dropped if the txMeta that has been confirmed has other transactions
|
|
@@ -1554,20 +1634,26 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1554
1634
|
const nonce = (_a = transactionMeta.txParams) === null || _a === void 0 ? void 0 : _a.nonce;
|
|
1555
1635
|
const from = (_b = transactionMeta.txParams) === null || _b === void 0 ? void 0 : _b.from;
|
|
1556
1636
|
const { chainId } = transactionMeta;
|
|
1557
|
-
const
|
|
1637
|
+
const sameNonceTransactions = this.state.transactions.filter((transaction) => transaction.id !== transactionId &&
|
|
1558
1638
|
transaction.txParams.from === from &&
|
|
1559
1639
|
transaction.txParams.nonce === nonce &&
|
|
1560
1640
|
transaction.chainId === chainId &&
|
|
1561
1641
|
transaction.type !== types_1.TransactionType.incoming);
|
|
1562
|
-
|
|
1642
|
+
const sameNonceTransactionIds = sameNonceTransactions.map((transaction) => transaction.id);
|
|
1643
|
+
if (sameNonceTransactions.length === 0) {
|
|
1563
1644
|
return;
|
|
1564
1645
|
}
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1646
|
+
this.update((state) => {
|
|
1647
|
+
for (const transaction of state.transactions) {
|
|
1648
|
+
if (sameNonceTransactionIds.includes(transaction.id)) {
|
|
1649
|
+
transaction.replacedBy = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.hash;
|
|
1650
|
+
transaction.replacedById = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.id;
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
});
|
|
1654
|
+
for (const transaction of this.state.transactions) {
|
|
1655
|
+
if (sameNonceTransactionIds.includes(transaction.id) &&
|
|
1656
|
+
transaction.status !== types_1.TransactionStatus.failed) {
|
|
1571
1657
|
this.setTransactionStatusDropped(transaction);
|
|
1572
1658
|
}
|
|
1573
1659
|
}
|
|
@@ -1578,12 +1664,12 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1578
1664
|
* @param transactionMeta - TransactionMeta of transaction to be marked as dropped.
|
|
1579
1665
|
*/
|
|
1580
1666
|
setTransactionStatusDropped(transactionMeta) {
|
|
1581
|
-
transactionMeta
|
|
1582
|
-
this.
|
|
1583
|
-
transactionMeta,
|
|
1667
|
+
const updatedTransactionMeta = Object.assign(Object.assign({}, transactionMeta), { status: types_1.TransactionStatus.dropped });
|
|
1668
|
+
this.messagingSystem.publish(`${controllerName}:transactionDropped`, {
|
|
1669
|
+
transactionMeta: updatedTransactionMeta,
|
|
1584
1670
|
});
|
|
1585
|
-
this.updateTransaction(
|
|
1586
|
-
this.onTransactionStatusChange(
|
|
1671
|
+
this.updateTransaction(updatedTransactionMeta, 'TransactionController#setTransactionStatusDropped - Transaction dropped');
|
|
1672
|
+
this.onTransactionStatusChange(updatedTransactionMeta);
|
|
1587
1673
|
}
|
|
1588
1674
|
/**
|
|
1589
1675
|
* Get transaction with provided actionId.
|
|
@@ -1597,7 +1683,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1597
1683
|
waitForTransactionFinished(transactionId) {
|
|
1598
1684
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1599
1685
|
return new Promise((resolve) => {
|
|
1600
|
-
this.
|
|
1686
|
+
__classPrivateFieldGet(this, _TransactionController_internalEvents, "f").once(`${transactionId}:finished`, (txMeta) => {
|
|
1601
1687
|
resolve(txMeta);
|
|
1602
1688
|
});
|
|
1603
1689
|
});
|
|
@@ -1612,13 +1698,15 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1612
1698
|
*/
|
|
1613
1699
|
updateTransactionMetaRSV(transactionMeta, signedTx) {
|
|
1614
1700
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1701
|
+
const transactionMetaWithRsv = (0, lodash_1.cloneDeep)(transactionMeta);
|
|
1615
1702
|
for (const key of ['r', 's', 'v']) {
|
|
1616
1703
|
const value = signedTx[key];
|
|
1617
1704
|
if (value === undefined || value === null) {
|
|
1618
1705
|
continue;
|
|
1619
1706
|
}
|
|
1620
|
-
|
|
1707
|
+
transactionMetaWithRsv[key] = (0, utils_1.add0x)(value.toString(16));
|
|
1621
1708
|
}
|
|
1709
|
+
return transactionMetaWithRsv;
|
|
1622
1710
|
});
|
|
1623
1711
|
}
|
|
1624
1712
|
getEIP1559Compatibility(networkClientId) {
|
|
@@ -1648,18 +1736,21 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1648
1736
|
(0, logger_1.projectLogger)('Skipping signed status based on hook');
|
|
1649
1737
|
return undefined;
|
|
1650
1738
|
}
|
|
1651
|
-
yield this.updateTransactionMetaRSV(transactionMeta, signedTx);
|
|
1652
|
-
|
|
1653
|
-
this.
|
|
1654
|
-
this.onTransactionStatusChange(transactionMeta);
|
|
1739
|
+
const transactionMetaWithRsv = Object.assign(Object.assign({}, (yield this.updateTransactionMetaRSV(transactionMeta, signedTx))), { status: types_1.TransactionStatus.signed });
|
|
1740
|
+
this.updateTransaction(transactionMetaWithRsv, 'TransactionController#approveTransaction - Transaction signed');
|
|
1741
|
+
this.onTransactionStatusChange(transactionMetaWithRsv);
|
|
1655
1742
|
const rawTx = (0, util_1.bufferToHex)(signedTx.serialize());
|
|
1656
|
-
|
|
1657
|
-
|
|
1743
|
+
const transactionMetaWithRawTx = (0, lodash_1.merge)({}, transactionMetaWithRsv, {
|
|
1744
|
+
rawTx,
|
|
1745
|
+
});
|
|
1746
|
+
this.updateTransaction(transactionMetaWithRawTx, 'TransactionController#approveTransaction - RawTransaction added');
|
|
1658
1747
|
return rawTx;
|
|
1659
1748
|
});
|
|
1660
1749
|
}
|
|
1661
1750
|
onTransactionStatusChange(transactionMeta) {
|
|
1662
|
-
this.
|
|
1751
|
+
this.messagingSystem.publish(`${controllerName}:transactionStatusUpdated`, {
|
|
1752
|
+
transactionMeta,
|
|
1753
|
+
});
|
|
1663
1754
|
}
|
|
1664
1755
|
getNonceTrackerTransactions(status, address, chainId = this.getChainId()) {
|
|
1665
1756
|
return (0, nonce_1.getAndFormatTransactionsForNonceTracker)(chainId, address, status, this.state.transactions);
|
|
@@ -1667,8 +1758,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1667
1758
|
onConfirmedTransaction(transactionMeta) {
|
|
1668
1759
|
(0, logger_1.projectLogger)('Processing confirmed transaction', transactionMeta.id);
|
|
1669
1760
|
this.markNonceDuplicatesDropped(transactionMeta.id);
|
|
1670
|
-
this.
|
|
1671
|
-
this.hub.emit(`${transactionMeta.id}:confirmed`, transactionMeta);
|
|
1761
|
+
this.messagingSystem.publish(`${controllerName}:transactionConfirmed`, transactionMeta);
|
|
1672
1762
|
this.onTransactionStatusChange(transactionMeta);
|
|
1673
1763
|
// Intentional given potential duration of process.
|
|
1674
1764
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
@@ -1689,7 +1779,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1689
1779
|
getTransaction: this.getTransaction.bind(this),
|
|
1690
1780
|
updateTransaction: this.updateTransaction.bind(this),
|
|
1691
1781
|
});
|
|
1692
|
-
this.
|
|
1782
|
+
this.messagingSystem.publish(`${controllerName}:postTransactionBalanceUpdated`, {
|
|
1693
1783
|
transactionMeta: updatedTransactionMeta,
|
|
1694
1784
|
approvalTransactionMeta,
|
|
1695
1785
|
});
|
|
@@ -1731,7 +1821,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1731
1821
|
}
|
|
1732
1822
|
}
|
|
1733
1823
|
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, }) {
|
|
1824
|
+
_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
1825
|
return new nonce_tracker_1.NonceTracker({
|
|
1736
1826
|
// TODO: Replace `any` with type
|
|
1737
1827
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -1749,7 +1839,7 @@ _TransactionController_incomingTransactionOptions = new WeakMap(), _TransactionC
|
|
|
1749
1839
|
isEnabled: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").isEnabled,
|
|
1750
1840
|
queryEntireHistory: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").queryEntireHistory,
|
|
1751
1841
|
remoteTransactionSource: etherscanRemoteTransactionSource,
|
|
1752
|
-
transactionLimit: this
|
|
1842
|
+
transactionLimit: __classPrivateFieldGet(this, _TransactionController_transactionHistoryLimit, "f"),
|
|
1753
1843
|
updateTransactions: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").updateTransactions,
|
|
1754
1844
|
});
|
|
1755
1845
|
__classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_addIncomingTransactionHelperListeners).call(this, incomingTransactionHelper);
|
|
@@ -1758,7 +1848,9 @@ _TransactionController_incomingTransactionOptions = new WeakMap(), _TransactionC
|
|
|
1758
1848
|
const ethQuery = new eth_query_1.default(provider);
|
|
1759
1849
|
const getChainId = chainId ? () => chainId : this.getChainId.bind(this);
|
|
1760
1850
|
const pendingTransactionTracker = new PendingTransactionTracker_1.PendingTransactionTracker({
|
|
1761
|
-
approveTransaction: this
|
|
1851
|
+
approveTransaction: (transactionId) => __awaiter(this, void 0, void 0, function* () {
|
|
1852
|
+
yield this.approveTransaction(transactionId);
|
|
1853
|
+
}),
|
|
1762
1854
|
blockTracker,
|
|
1763
1855
|
getChainId,
|
|
1764
1856
|
getEthQuery: () => ethQuery,
|
|
@@ -1804,14 +1896,14 @@ _TransactionController_incomingTransactionOptions = new WeakMap(), _TransactionC
|
|
|
1804
1896
|
}, _TransactionController_getGasFeeFlows = function _TransactionController_getGasFeeFlows() {
|
|
1805
1897
|
return [new LineaGasFeeFlow_1.LineaGasFeeFlow(), new DefaultGasFeeFlow_1.DefaultGasFeeFlow()];
|
|
1806
1898
|
}, _TransactionController_updateTransactionInternal = function _TransactionController_updateTransactionInternal(transactionMeta, { note, skipHistory }) {
|
|
1807
|
-
const
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
(0, history_1.updateTransactionHistory)(
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1899
|
+
const normalizedTransaction = Object.assign(Object.assign({}, transactionMeta), { txParams: (0, utils_2.normalizeTransactionParams)(transactionMeta.txParams) });
|
|
1900
|
+
(0, validation_1.validateTxParams)(normalizedTransaction.txParams);
|
|
1901
|
+
const transactionWithUpdatedHistory = skipHistory === true
|
|
1902
|
+
? normalizedTransaction
|
|
1903
|
+
: (0, history_1.updateTransactionHistory)(normalizedTransaction, note !== null && note !== void 0 ? note : 'Transaction updated');
|
|
1904
|
+
this.update((state) => {
|
|
1905
|
+
const index = state.transactions.findIndex(({ id }) => transactionMeta.id === id);
|
|
1906
|
+
state.transactions[index] = transactionWithUpdatedHistory;
|
|
1907
|
+
});
|
|
1816
1908
|
};
|
|
1817
1909
|
//# sourceMappingURL=TransactionController.js.map
|