@metamask/transaction-controller 22.0.0 → 23.0.0
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 +39 -1
- package/dist/TransactionController.d.ts +104 -106
- package/dist/TransactionController.d.ts.map +1 -1
- package/dist/TransactionController.js +281 -172
- package/dist/TransactionController.js.map +1 -1
- package/dist/helpers/EtherscanRemoteTransactionSource.d.ts.map +1 -1
- package/dist/helpers/EtherscanRemoteTransactionSource.js +28 -8
- package/dist/helpers/EtherscanRemoteTransactionSource.js.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.d.ts +17 -3
- package/dist/helpers/IncomingTransactionHelper.d.ts.map +1 -1
- package/dist/helpers/IncomingTransactionHelper.js +17 -14
- package/dist/helpers/IncomingTransactionHelper.js.map +1 -1
- package/dist/helpers/MultichainTrackingHelper.d.ts +72 -0
- package/dist/helpers/MultichainTrackingHelper.d.ts.map +1 -0
- package/dist/helpers/MultichainTrackingHelper.js +292 -0
- package/dist/helpers/MultichainTrackingHelper.js.map +1 -0
- package/dist/helpers/PendingTransactionTracker.d.ts +7 -7
- package/dist/helpers/PendingTransactionTracker.d.ts.map +1 -1
- package/dist/helpers/PendingTransactionTracker.js +28 -28
- package/dist/helpers/PendingTransactionTracker.js.map +1 -1
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/etherscan.d.ts +7 -0
- package/dist/utils/etherscan.d.ts.map +1 -1
- package/dist/utils/etherscan.js +17 -6
- package/dist/utils/etherscan.js.map +1 -1
- package/dist/utils/gas-fees.d.ts +4 -3
- package/dist/utils/gas-fees.d.ts.map +1 -1
- package/dist/utils/gas-fees.js +6 -2
- package/dist/utils/gas-fees.js.map +1 -1
- package/dist/utils/gas.d.ts +3 -2
- package/dist/utils/gas.d.ts.map +1 -1
- package/dist/utils/gas.js +4 -5
- package/dist/utils/gas.js.map +1 -1
- package/dist/utils/nonce.d.ts +3 -3
- package/dist/utils/nonce.d.ts.map +1 -1
- package/dist/utils/nonce.js +3 -3
- package/dist/utils/nonce.js.map +1 -1
- package/package.json +2 -1
|
@@ -8,9 +8,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
12
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
13
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
14
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
15
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
16
|
+
};
|
|
17
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
18
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
19
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
20
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
21
|
+
};
|
|
11
22
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
23
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
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;
|
|
14
26
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
27
|
exports.TransactionController = exports.SPEED_UP_RATE = exports.CANCEL_RATE = exports.HARDFORK = void 0;
|
|
16
28
|
const common_1 = require("@ethereumjs/common");
|
|
@@ -18,6 +30,7 @@ const tx_1 = require("@ethereumjs/tx");
|
|
|
18
30
|
const base_controller_1 = require("@metamask/base-controller");
|
|
19
31
|
const controller_utils_1 = require("@metamask/controller-utils");
|
|
20
32
|
const eth_query_1 = __importDefault(require("@metamask/eth-query"));
|
|
33
|
+
const network_controller_1 = require("@metamask/network-controller");
|
|
21
34
|
const rpc_errors_1 = require("@metamask/rpc-errors");
|
|
22
35
|
const async_mutex_1 = require("async-mutex");
|
|
23
36
|
const eth_method_registry_1 = require("eth-method-registry");
|
|
@@ -28,6 +41,7 @@ const nonce_tracker_1 = require("nonce-tracker");
|
|
|
28
41
|
const uuid_1 = require("uuid");
|
|
29
42
|
const EtherscanRemoteTransactionSource_1 = require("./helpers/EtherscanRemoteTransactionSource");
|
|
30
43
|
const IncomingTransactionHelper_1 = require("./helpers/IncomingTransactionHelper");
|
|
44
|
+
const MultichainTrackingHelper_1 = require("./helpers/MultichainTrackingHelper");
|
|
31
45
|
const PendingTransactionTracker_1 = require("./helpers/PendingTransactionTracker");
|
|
32
46
|
const logger_1 = require("./logger");
|
|
33
47
|
const types_1 = require("./types");
|
|
@@ -57,49 +71,16 @@ const controllerName = 'TransactionController';
|
|
|
57
71
|
* Controller responsible for submitting and managing transactions.
|
|
58
72
|
*/
|
|
59
73
|
class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
60
|
-
|
|
61
|
-
* Creates a TransactionController instance.
|
|
62
|
-
*
|
|
63
|
-
* @param options - The controller options.
|
|
64
|
-
* @param options.blockTracker - The block tracker used to poll for new blocks data.
|
|
65
|
-
* @param options.disableHistory - Whether to disable storing history in transaction metadata.
|
|
66
|
-
* @param options.disableSendFlowHistory - Explicitly disable transaction metadata history.
|
|
67
|
-
* @param options.disableSwaps - Whether to disable additional processing on swaps transactions.
|
|
68
|
-
* @param options.getCurrentAccountEIP1559Compatibility - Whether or not the account supports EIP-1559.
|
|
69
|
-
* @param options.getCurrentNetworkEIP1559Compatibility - Whether or not the network supports EIP-1559.
|
|
70
|
-
* @param options.getExternalPendingTransactions - Callback to retrieve pending transactions from external sources.
|
|
71
|
-
* @param options.getGasFeeEstimates - Callback to retrieve gas fee estimates.
|
|
72
|
-
* @param options.getNetworkState - Gets the state of the network controller.
|
|
73
|
-
* @param options.getPermittedAccounts - Get accounts that a given origin has permissions for.
|
|
74
|
-
* @param options.getSavedGasFees - Gets the saved gas fee config.
|
|
75
|
-
* @param options.getSelectedAddress - Gets the address of the currently selected account.
|
|
76
|
-
* @param options.incomingTransactions - Configuration options for incoming transaction support.
|
|
77
|
-
* @param options.incomingTransactions.includeTokenTransfers - Whether or not to include ERC20 token transfers.
|
|
78
|
-
* @param options.incomingTransactions.isEnabled - Whether or not incoming transaction retrieval is enabled.
|
|
79
|
-
* @param options.incomingTransactions.queryEntireHistory - Whether to initially query the entire transaction history or only recent blocks.
|
|
80
|
-
* @param options.incomingTransactions.updateTransactions - Whether to update local transactions using remote transaction data.
|
|
81
|
-
* @param options.messenger - The controller messenger.
|
|
82
|
-
* @param options.onNetworkStateChange - Allows subscribing to network controller state changes.
|
|
83
|
-
* @param options.pendingTransactions - Configuration options for pending transaction support.
|
|
84
|
-
* @param options.pendingTransactions.isResubmitEnabled - Whether transaction publishing is automatically retried.
|
|
85
|
-
* @param options.provider - The provider used to create the underlying EthQuery instance.
|
|
86
|
-
* @param options.securityProviderRequest - A function for verifying a transaction, whether it is malicious or not.
|
|
87
|
-
* @param options.hooks - The controller hooks.
|
|
88
|
-
* @param options.hooks.afterSign - Additional logic to execute after signing a transaction. Return false to not change the status to signed.
|
|
89
|
-
* @param options.hooks.beforeApproveOnInit - Additional logic to execute before starting an approval flow for a transaction during initialization. Return false to skip the transaction.
|
|
90
|
-
* @param options.hooks.beforeCheckPendingTransaction - Additional logic to execute before checking pending transactions. Return false to prevent the broadcast of the transaction.
|
|
91
|
-
* @param options.hooks.beforePublish - Additional logic to execute before publishing a transaction. Return false to prevent the broadcast of the transaction.
|
|
92
|
-
* @param options.hooks.getAdditionalSignArguments - Returns additional arguments required to sign a transaction.
|
|
93
|
-
* @param options.hooks.publish - Alternate logic to publish a transaction.
|
|
94
|
-
* @param config - Initial options used to configure this controller.
|
|
95
|
-
* @param state - Initial state to set on this controller.
|
|
96
|
-
*/
|
|
97
|
-
constructor({ blockTracker, disableHistory, disableSendFlowHistory, disableSwaps, getCurrentAccountEIP1559Compatibility, getCurrentNetworkEIP1559Compatibility, getExternalPendingTransactions, getGasFeeEstimates, getNetworkState, getPermittedAccounts, getSavedGasFees, getSelectedAddress, incomingTransactions = {}, messenger, onNetworkStateChange, pendingTransactions = {}, provider, securityProviderRequest, hooks = {}, }, config, state) {
|
|
74
|
+
constructor({ blockTracker, disableHistory, disableSendFlowHistory, disableSwaps, getCurrentAccountEIP1559Compatibility, getCurrentNetworkEIP1559Compatibility, getExternalPendingTransactions, getGasFeeEstimates, getNetworkState, getPermittedAccounts, getSavedGasFees, getSelectedAddress, incomingTransactions = {}, messenger, onNetworkStateChange, pendingTransactions = {}, provider, securityProviderRequest, getNetworkClientRegistry, isMultichainEnabled = false, hooks, }, config, state) {
|
|
98
75
|
var _a, _b, _c, _d, _e, _f;
|
|
99
76
|
super(config, state);
|
|
77
|
+
_TransactionController_instances.add(this);
|
|
100
78
|
this.inProcessOfSigning = new Set();
|
|
101
79
|
this.mutex = new async_mutex_1.Mutex();
|
|
80
|
+
_TransactionController_incomingTransactionOptions.set(this, void 0);
|
|
81
|
+
_TransactionController_pendingTransactionOptions.set(this, void 0);
|
|
102
82
|
this.signAbortCallbacks = new Map();
|
|
83
|
+
_TransactionController_multichainTrackingHelper.set(this, void 0);
|
|
103
84
|
/**
|
|
104
85
|
* EventEmitter instance used to listen to specific transactional events
|
|
105
86
|
*/
|
|
@@ -108,6 +89,11 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
108
89
|
* Name of this controller used during composition
|
|
109
90
|
*/
|
|
110
91
|
this.name = 'TransactionController';
|
|
92
|
+
_TransactionController_checkForPendingTransactionAndStartPolling.set(this, () => {
|
|
93
|
+
// PendingTransactionTracker reads state through its getTransactions hook
|
|
94
|
+
this.pendingTransactionTracker.startIfPendingTransactions();
|
|
95
|
+
__classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").checkForPendingTransactionAndStartPolling();
|
|
96
|
+
});
|
|
111
97
|
this.defaultConfig = {
|
|
112
98
|
txHistoryLimit: 40,
|
|
113
99
|
};
|
|
@@ -117,10 +103,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
117
103
|
lastFetchedBlockNumbers: {},
|
|
118
104
|
};
|
|
119
105
|
this.initialize();
|
|
120
|
-
this.provider = provider;
|
|
121
106
|
this.messagingSystem = messenger;
|
|
122
107
|
this.getNetworkState = getNetworkState;
|
|
123
|
-
this.ethQuery = new eth_query_1.default(provider);
|
|
124
108
|
this.isSendFlowHistoryDisabled = disableSendFlowHistory !== null && disableSendFlowHistory !== void 0 ? disableSendFlowHistory : false;
|
|
125
109
|
this.isHistoryDisabled = disableHistory !== null && disableHistory !== void 0 ? disableHistory : false;
|
|
126
110
|
this.isSwapsDisabled = disableSwaps !== null && disableSwaps !== void 0 ? disableSwaps : false;
|
|
@@ -138,6 +122,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
138
122
|
this.getExternalPendingTransactions =
|
|
139
123
|
getExternalPendingTransactions !== null && getExternalPendingTransactions !== void 0 ? getExternalPendingTransactions : (() => []);
|
|
140
124
|
this.securityProviderRequest = securityProviderRequest;
|
|
125
|
+
__classPrivateFieldSet(this, _TransactionController_incomingTransactionOptions, incomingTransactions, "f");
|
|
126
|
+
__classPrivateFieldSet(this, _TransactionController_pendingTransactionOptions, pendingTransactions, "f");
|
|
141
127
|
this.afterSign = (_a = hooks === null || hooks === void 0 ? void 0 : hooks.afterSign) !== null && _a !== void 0 ? _a : (() => true);
|
|
142
128
|
this.beforeApproveOnInit = (_b = hooks === null || hooks === void 0 ? void 0 : hooks.beforeApproveOnInit) !== null && _b !== void 0 ? _b : (() => true);
|
|
143
129
|
this.beforeCheckPendingTransaction =
|
|
@@ -149,50 +135,51 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
149
135
|
(_e = hooks === null || hooks === void 0 ? void 0 : hooks.getAdditionalSignArguments) !== null && _e !== void 0 ? _e : (() => []);
|
|
150
136
|
this.publish =
|
|
151
137
|
(_f = hooks === null || hooks === void 0 ? void 0 : hooks.publish) !== null && _f !== void 0 ? _f : (() => Promise.resolve({ transactionHash: undefined }));
|
|
152
|
-
this.nonceTracker =
|
|
153
|
-
// @ts-expect-error provider types misaligned: SafeEventEmitterProvider vs Record<string,string>
|
|
138
|
+
this.nonceTracker = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createNonceTracker).call(this, {
|
|
154
139
|
provider,
|
|
155
140
|
blockTracker,
|
|
156
|
-
getPendingTransactions: this.getNonceTrackerPendingTransactions.bind(this),
|
|
157
|
-
getConfirmedTransactions: this.getNonceTrackerTransactions.bind(this, types_1.TransactionStatus.confirmed),
|
|
158
|
-
});
|
|
159
|
-
this.incomingTransactionHelper = new IncomingTransactionHelper_1.IncomingTransactionHelper({
|
|
160
|
-
blockTracker,
|
|
161
|
-
getCurrentAccount: getSelectedAddress,
|
|
162
|
-
getLastFetchedBlockNumbers: () => this.state.lastFetchedBlockNumbers,
|
|
163
|
-
getNetworkState,
|
|
164
|
-
isEnabled: incomingTransactions.isEnabled,
|
|
165
|
-
queryEntireHistory: incomingTransactions.queryEntireHistory,
|
|
166
|
-
remoteTransactionSource: new EtherscanRemoteTransactionSource_1.EtherscanRemoteTransactionSource({
|
|
167
|
-
includeTokenTransfers: incomingTransactions.includeTokenTransfers,
|
|
168
|
-
}),
|
|
169
|
-
transactionLimit: this.config.txHistoryLimit,
|
|
170
|
-
updateTransactions: incomingTransactions.updateTransactions,
|
|
171
141
|
});
|
|
172
|
-
this
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
approveTransaction: this.approveTransaction.bind(this),
|
|
176
|
-
blockTracker,
|
|
177
|
-
getChainId: this.getChainId.bind(this),
|
|
178
|
-
getEthQuery: () => this.ethQuery,
|
|
179
|
-
getTransactions: () => this.state.transactions,
|
|
180
|
-
isResubmitEnabled: pendingTransactions.isResubmitEnabled,
|
|
142
|
+
__classPrivateFieldSet(this, _TransactionController_multichainTrackingHelper, new MultichainTrackingHelper_1.MultichainTrackingHelper({
|
|
143
|
+
isMultichainEnabled,
|
|
144
|
+
provider,
|
|
181
145
|
nonceTracker: this.nonceTracker,
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
listener();
|
|
146
|
+
incomingTransactionOptions: incomingTransactions,
|
|
147
|
+
findNetworkClientIdByChainId: (chainId) => {
|
|
148
|
+
return this.messagingSystem.call(`NetworkController:findNetworkClientIdByChainId`, chainId);
|
|
186
149
|
},
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
150
|
+
getNetworkClientById: ((networkClientId) => {
|
|
151
|
+
return this.messagingSystem.call(`NetworkController:getNetworkClientById`, networkClientId);
|
|
152
|
+
}),
|
|
153
|
+
getNetworkClientRegistry,
|
|
154
|
+
removeIncomingTransactionHelperListeners: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removeIncomingTransactionHelperListeners).bind(this),
|
|
155
|
+
removePendingTransactionTrackerListeners: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removePendingTransactionTrackerListeners).bind(this),
|
|
156
|
+
createNonceTracker: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createNonceTracker).bind(this),
|
|
157
|
+
createIncomingTransactionHelper: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createIncomingTransactionHelper).bind(this),
|
|
158
|
+
createPendingTransactionTracker: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createPendingTransactionTracker).bind(this),
|
|
159
|
+
onNetworkStateChange: (listener) => {
|
|
160
|
+
this.messagingSystem.subscribe('NetworkController:stateChange', listener);
|
|
191
161
|
},
|
|
162
|
+
}), "f");
|
|
163
|
+
__classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").initialize();
|
|
164
|
+
const etherscanRemoteTransactionSource = new EtherscanRemoteTransactionSource_1.EtherscanRemoteTransactionSource({
|
|
165
|
+
includeTokenTransfers: incomingTransactions.includeTokenTransfers,
|
|
166
|
+
});
|
|
167
|
+
this.incomingTransactionHelper = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createIncomingTransactionHelper).call(this, {
|
|
168
|
+
blockTracker,
|
|
169
|
+
etherscanRemoteTransactionSource,
|
|
170
|
+
});
|
|
171
|
+
this.pendingTransactionTracker = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createPendingTransactionTracker).call(this, {
|
|
172
|
+
provider,
|
|
173
|
+
blockTracker,
|
|
192
174
|
});
|
|
193
|
-
|
|
175
|
+
// when transactionsController state changes
|
|
176
|
+
// check for pending transactions and start polling if there are any
|
|
177
|
+
this.subscribe(__classPrivateFieldGet(this, _TransactionController_checkForPendingTransactionAndStartPolling, "f"));
|
|
178
|
+
// TODO once v2 is merged make sure this only runs when
|
|
179
|
+
// selectedNetworkClientId changes
|
|
194
180
|
onNetworkStateChange(() => {
|
|
195
181
|
(0, logger_1.projectLogger)('Detected network change', this.getChainId());
|
|
182
|
+
this.pendingTransactionTracker.startIfPendingTransactions();
|
|
196
183
|
this.onBootCleanup();
|
|
197
184
|
});
|
|
198
185
|
this.onBootCleanup();
|
|
@@ -215,6 +202,12 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
215
202
|
return { registryMethod, parsedRegistryMethod };
|
|
216
203
|
});
|
|
217
204
|
}
|
|
205
|
+
/**
|
|
206
|
+
* Stops polling and removes listeners to prepare the controller for garbage collection.
|
|
207
|
+
*/
|
|
208
|
+
destroy() {
|
|
209
|
+
__classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_stopAllTracking).call(this);
|
|
210
|
+
}
|
|
218
211
|
/**
|
|
219
212
|
* Handle new method data request.
|
|
220
213
|
*
|
|
@@ -259,21 +252,30 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
259
252
|
* @param opts.swaps - Options for swaps transactions.
|
|
260
253
|
* @param opts.swaps.hasApproveTx - Whether the transaction has an approval transaction.
|
|
261
254
|
* @param opts.swaps.meta - Metadata for swap transaction.
|
|
255
|
+
* @param opts.networkClientId - The id of the network client for this transaction.
|
|
262
256
|
* @returns Object containing a promise resolving to the transaction hash if approved.
|
|
263
257
|
*/
|
|
264
|
-
addTransaction(txParams, { actionId, deviceConfirmedOn, method, origin, requireApproval, securityAlertResponse, sendFlowHistory, swaps = {}, type, } = {}) {
|
|
258
|
+
addTransaction(txParams, { actionId, deviceConfirmedOn, method, origin, requireApproval, securityAlertResponse, sendFlowHistory, swaps = {}, type, networkClientId, } = {}) {
|
|
265
259
|
return __awaiter(this, void 0, void 0, function* () {
|
|
266
260
|
(0, logger_1.projectLogger)('Adding transaction', txParams);
|
|
267
261
|
txParams = (0, utils_1.normalizeTxParams)(txParams);
|
|
268
|
-
|
|
262
|
+
if (networkClientId &&
|
|
263
|
+
!__classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").has(networkClientId)) {
|
|
264
|
+
throw new Error('The networkClientId for this transaction could not be found');
|
|
265
|
+
}
|
|
266
|
+
const isEIP1559Compatible = yield this.getEIP1559Compatibility(networkClientId);
|
|
269
267
|
(0, validation_1.validateTxParams)(txParams, isEIP1559Compatible);
|
|
270
268
|
if (origin) {
|
|
271
269
|
yield (0, validation_1.validateTransactionOrigin)(yield this.getPermittedAccounts(origin), this.getSelectedAddress(), txParams.from, origin);
|
|
272
270
|
}
|
|
273
271
|
const dappSuggestedGasFees = this.generateDappSuggestedGasFees(txParams, origin);
|
|
274
|
-
const
|
|
272
|
+
const chainId = this.getChainId(networkClientId);
|
|
273
|
+
const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
274
|
+
networkClientId,
|
|
275
|
+
chainId,
|
|
276
|
+
});
|
|
277
|
+
const transactionType = type !== null && type !== void 0 ? type : (yield (0, transaction_type_1.determineTransactionType)(txParams, ethQuery)).type;
|
|
275
278
|
const existingTransactionMeta = this.getTransactionWithActionId(actionId);
|
|
276
|
-
const chainId = this.getChainId();
|
|
277
279
|
// If a request to add a transaction with the same actionId is submitted again, a new transaction will not be created for it.
|
|
278
280
|
const transactionMeta = existingTransactionMeta || {
|
|
279
281
|
// Add actionId to txMeta to check if same actionId is seen again
|
|
@@ -290,6 +292,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
290
292
|
userEditedGasLimit: false,
|
|
291
293
|
verifiedOnBlockchain: false,
|
|
292
294
|
type: transactionType,
|
|
295
|
+
networkClientId,
|
|
293
296
|
};
|
|
294
297
|
yield this.updateGasProperties(transactionMeta);
|
|
295
298
|
// Checks if a transaction already exists with a given actionId
|
|
@@ -326,15 +329,31 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
326
329
|
};
|
|
327
330
|
});
|
|
328
331
|
}
|
|
329
|
-
startIncomingTransactionPolling() {
|
|
330
|
-
|
|
332
|
+
startIncomingTransactionPolling(networkClientIds = []) {
|
|
333
|
+
if (networkClientIds.length === 0) {
|
|
334
|
+
this.incomingTransactionHelper.start();
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
__classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").startIncomingTransactionPolling(networkClientIds);
|
|
331
338
|
}
|
|
332
|
-
stopIncomingTransactionPolling() {
|
|
339
|
+
stopIncomingTransactionPolling(networkClientIds = []) {
|
|
340
|
+
if (networkClientIds.length === 0) {
|
|
341
|
+
this.incomingTransactionHelper.stop();
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
__classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopIncomingTransactionPolling(networkClientIds);
|
|
345
|
+
}
|
|
346
|
+
stopAllIncomingTransactionPolling() {
|
|
333
347
|
this.incomingTransactionHelper.stop();
|
|
348
|
+
__classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopAllIncomingTransactionPolling();
|
|
334
349
|
}
|
|
335
|
-
updateIncomingTransactions() {
|
|
350
|
+
updateIncomingTransactions(networkClientIds = []) {
|
|
336
351
|
return __awaiter(this, void 0, void 0, function* () {
|
|
337
|
-
|
|
352
|
+
if (networkClientIds.length === 0) {
|
|
353
|
+
yield this.incomingTransactionHelper.update();
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
yield __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").updateIncomingTransactions(networkClientIds);
|
|
338
357
|
});
|
|
339
358
|
}
|
|
340
359
|
/**
|
|
@@ -406,7 +425,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
406
425
|
to: transactionMeta.txParams.from,
|
|
407
426
|
value: '0x0',
|
|
408
427
|
};
|
|
409
|
-
const unsignedEthTx = this.prepareUnsignedEthTx(newTxParams);
|
|
428
|
+
const unsignedEthTx = this.prepareUnsignedEthTx(transactionMeta.chainId, newTxParams);
|
|
410
429
|
const signedTx = yield this.sign(unsignedEthTx, transactionMeta.txParams.from);
|
|
411
430
|
const rawTx = (0, ethereumjs_util_1.bufferToHex)(signedTx.serialize());
|
|
412
431
|
const newFee = (_c = newTxParams.maxFeePerGas) !== null && _c !== void 0 ? _c : newTxParams.gasPrice;
|
|
@@ -418,10 +437,15 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
418
437
|
newFee,
|
|
419
438
|
txParams: newTxParams,
|
|
420
439
|
});
|
|
421
|
-
const
|
|
440
|
+
const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
441
|
+
networkClientId: transactionMeta.networkClientId,
|
|
442
|
+
chainId: transactionMeta.chainId,
|
|
443
|
+
});
|
|
444
|
+
const hash = yield this.publishTransactionForRetry(ethQuery, rawTx, transactionMeta);
|
|
422
445
|
const cancelTransactionMeta = {
|
|
423
446
|
actionId,
|
|
424
447
|
chainId: transactionMeta.chainId,
|
|
448
|
+
networkClientId: transactionMeta.networkClientId,
|
|
425
449
|
estimatedBaseFee,
|
|
426
450
|
hash,
|
|
427
451
|
id: (0, uuid_1.v1)(),
|
|
@@ -497,7 +521,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
497
521
|
(existingMaxPriorityFeePerGas && minMaxPriorityFeePerGas);
|
|
498
522
|
const txParams = newMaxFeePerGas && newMaxPriorityFeePerGas
|
|
499
523
|
? 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 });
|
|
500
|
-
const unsignedEthTx = this.prepareUnsignedEthTx(txParams);
|
|
524
|
+
const unsignedEthTx = this.prepareUnsignedEthTx(transactionMeta.chainId, txParams);
|
|
501
525
|
const signedTx = yield this.sign(unsignedEthTx, transactionMeta.txParams.from);
|
|
502
526
|
yield this.updateTransactionMetaRSV(transactionMeta, signedTx);
|
|
503
527
|
const rawTx = (0, ethereumjs_util_1.bufferToHex)(signedTx.serialize());
|
|
@@ -506,7 +530,11 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
506
530
|
? transactionMeta.txParams.maxFeePerGas
|
|
507
531
|
: transactionMeta.txParams.gasPrice;
|
|
508
532
|
(0, logger_1.projectLogger)('Submitting speed up transaction', { oldFee, newFee, txParams });
|
|
509
|
-
const
|
|
533
|
+
const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
534
|
+
networkClientId: transactionMeta.networkClientId,
|
|
535
|
+
chainId: transactionMeta.chainId,
|
|
536
|
+
});
|
|
537
|
+
const hash = yield this.publishTransactionForRetry(ethQuery, rawTx, transactionMeta);
|
|
510
538
|
const baseTransactionMeta = Object.assign(Object.assign({}, transactionMeta), { estimatedBaseFee, id: (0, uuid_1.v1)(), time: Date.now(), hash,
|
|
511
539
|
actionId, originalGasEstimate: transactionMeta.txParams.gas, type: types_1.TransactionType.retry, originalType: transactionMeta.type });
|
|
512
540
|
const newTransactionMeta = newMaxFeePerGas && newMaxPriorityFeePerGas
|
|
@@ -528,11 +556,15 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
528
556
|
* Estimates required gas for a given transaction.
|
|
529
557
|
*
|
|
530
558
|
* @param transaction - The transaction to estimate gas for.
|
|
559
|
+
* @param networkClientId - The network client id to use for the estimate.
|
|
531
560
|
* @returns The gas and gas price.
|
|
532
561
|
*/
|
|
533
|
-
estimateGas(transaction) {
|
|
562
|
+
estimateGas(transaction, networkClientId) {
|
|
534
563
|
return __awaiter(this, void 0, void 0, function* () {
|
|
535
|
-
const
|
|
564
|
+
const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
565
|
+
networkClientId,
|
|
566
|
+
});
|
|
567
|
+
const { estimatedGas, simulationFails } = yield (0, gas_1.estimateGas)(transaction, ethQuery);
|
|
536
568
|
return { gas: estimatedGas, simulationFails };
|
|
537
569
|
});
|
|
538
570
|
}
|
|
@@ -541,10 +573,14 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
541
573
|
*
|
|
542
574
|
* @param transaction - The transaction params to estimate gas for.
|
|
543
575
|
* @param multiplier - The multiplier to use for the gas buffer.
|
|
576
|
+
* @param networkClientId - The network client id to use for the estimate.
|
|
544
577
|
*/
|
|
545
|
-
estimateGasBuffered(transaction, multiplier) {
|
|
578
|
+
estimateGasBuffered(transaction, multiplier, networkClientId) {
|
|
546
579
|
return __awaiter(this, void 0, void 0, function* () {
|
|
547
|
-
const
|
|
580
|
+
const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
581
|
+
networkClientId,
|
|
582
|
+
});
|
|
583
|
+
const { blockGasLimit, estimatedGas, simulationFails } = yield (0, gas_1.estimateGas)(transaction, ethQuery);
|
|
548
584
|
const gas = (0, gas_1.addGasBuffer)(estimatedGas, blockGasLimit, multiplier);
|
|
549
585
|
return {
|
|
550
586
|
gas,
|
|
@@ -614,12 +650,6 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
614
650
|
transactions: this.trimTransactionsForState(newTransactions),
|
|
615
651
|
});
|
|
616
652
|
}
|
|
617
|
-
startIncomingTransactionProcessing() {
|
|
618
|
-
this.incomingTransactionHelper.start();
|
|
619
|
-
}
|
|
620
|
-
stopIncomingTransactionProcessing() {
|
|
621
|
-
this.incomingTransactionHelper.stop();
|
|
622
|
-
}
|
|
623
653
|
/**
|
|
624
654
|
* Adds external provided transaction to state as confirmed transaction.
|
|
625
655
|
*
|
|
@@ -765,16 +795,9 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
765
795
|
this.updateTransaction(updatedMeta, 'TransactionController:updatePreviousGasParams - Previous gas values updated');
|
|
766
796
|
return this.getTransaction(transactionId);
|
|
767
797
|
}
|
|
768
|
-
|
|
769
|
-
* Gets the next nonce according to the nonce-tracker.
|
|
770
|
-
* Ensure `releaseLock` is called once processing of the `nonce` value is complete.
|
|
771
|
-
*
|
|
772
|
-
* @param address - The hex string address for the transaction.
|
|
773
|
-
* @returns object with the `nextNonce` `nonceDetails`, and the releaseLock.
|
|
774
|
-
*/
|
|
775
|
-
getNonceLock(address) {
|
|
798
|
+
getNonceLock(address, networkClientId) {
|
|
776
799
|
return __awaiter(this, void 0, void 0, function* () {
|
|
777
|
-
return this.
|
|
800
|
+
return __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getNonceLock(address, networkClientId);
|
|
778
801
|
});
|
|
779
802
|
}
|
|
780
803
|
/**
|
|
@@ -809,7 +832,10 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
809
832
|
};
|
|
810
833
|
editableParams.txParams = (0, lodash_1.pickBy)(editableParams.txParams);
|
|
811
834
|
const updatedTransaction = (0, lodash_1.merge)(transactionMeta, editableParams);
|
|
812
|
-
const { type } = yield (0, transaction_type_1.determineTransactionType)(updatedTransaction.txParams, this.
|
|
835
|
+
const { type } = yield (0, transaction_type_1.determineTransactionType)(updatedTransaction.txParams, __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
836
|
+
networkClientId: transactionMeta.networkClientId,
|
|
837
|
+
chainId: transactionMeta.chainId,
|
|
838
|
+
}));
|
|
813
839
|
updatedTransaction.type = type;
|
|
814
840
|
this.updateTransaction(updatedTransaction, `Update Editable Params for ${txId}`);
|
|
815
841
|
return this.getTransaction(txId);
|
|
@@ -832,7 +858,19 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
832
858
|
return '';
|
|
833
859
|
}
|
|
834
860
|
const initialTx = listOfTxParams[0];
|
|
835
|
-
const common = this.getCommonConfiguration();
|
|
861
|
+
const common = this.getCommonConfiguration(initialTx.chainId);
|
|
862
|
+
// We need to ensure we get the nonce using the the NonceTracker on the chain matching
|
|
863
|
+
// the txParams. In this context we only have chainId available to us, but the
|
|
864
|
+
// NonceTrackers are keyed by networkClientId. To workaround this, we attempt to find
|
|
865
|
+
// a networkClientId that matches the chainId. As a fallback, the globally selected
|
|
866
|
+
// network's NonceTracker will be used instead.
|
|
867
|
+
let networkClientId;
|
|
868
|
+
try {
|
|
869
|
+
networkClientId = this.messagingSystem.call(`NetworkController:findNetworkClientIdByChainId`, initialTx.chainId);
|
|
870
|
+
}
|
|
871
|
+
catch (err) {
|
|
872
|
+
(0, logger_1.projectLogger)('failed to find networkClientId from chainId', err);
|
|
873
|
+
}
|
|
836
874
|
const initialTxAsEthTx = tx_1.TransactionFactory.fromTxData(initialTx, {
|
|
837
875
|
common,
|
|
838
876
|
});
|
|
@@ -847,7 +885,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
847
885
|
const fromAddress = initialTx.from;
|
|
848
886
|
const requiresNonce = hasNonce !== true;
|
|
849
887
|
nonceLock = requiresNonce
|
|
850
|
-
? yield this.
|
|
888
|
+
? yield this.getNonceLock(fromAddress, networkClientId)
|
|
851
889
|
: undefined;
|
|
852
890
|
const nonce = nonceLock
|
|
853
891
|
? (0, ethereumjs_util_1.addHexPrefix)(nonceLock.nextNonce.toString(16))
|
|
@@ -857,7 +895,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
857
895
|
}
|
|
858
896
|
rawTransactions = yield Promise.all(listOfTxParams.map((txParams) => {
|
|
859
897
|
txParams.nonce = nonce;
|
|
860
|
-
return this.signExternalTransaction(txParams);
|
|
898
|
+
return this.signExternalTransaction(txParams.chainId, txParams);
|
|
861
899
|
}));
|
|
862
900
|
}
|
|
863
901
|
catch (err) {
|
|
@@ -1015,19 +1053,18 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1015
1053
|
}
|
|
1016
1054
|
return filteredTransactions;
|
|
1017
1055
|
}
|
|
1018
|
-
signExternalTransaction(transactionParams) {
|
|
1056
|
+
signExternalTransaction(chainId, transactionParams) {
|
|
1019
1057
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1020
1058
|
if (!this.sign) {
|
|
1021
1059
|
throw new Error('No sign method defined.');
|
|
1022
1060
|
}
|
|
1023
1061
|
const normalizedTransactionParams = (0, utils_1.normalizeTxParams)(transactionParams);
|
|
1024
|
-
const chainId = this.getChainId();
|
|
1025
1062
|
const type = (0, utils_1.isEIP1559Transaction)(normalizedTransactionParams)
|
|
1026
1063
|
? types_1.TransactionEnvelopeType.feeMarket
|
|
1027
1064
|
: types_1.TransactionEnvelopeType.legacy;
|
|
1028
1065
|
const updatedTransactionParams = Object.assign(Object.assign({}, normalizedTransactionParams), { type, gasLimit: normalizedTransactionParams.gas, chainId });
|
|
1029
1066
|
const { from } = updatedTransactionParams;
|
|
1030
|
-
const common = this.getCommonConfiguration();
|
|
1067
|
+
const common = this.getCommonConfiguration(chainId);
|
|
1031
1068
|
const unsignedTransaction = tx_1.TransactionFactory.fromTxData(updatedTransactionParams, { common });
|
|
1032
1069
|
const signedTransaction = yield this.sign(unsignedTransaction, from);
|
|
1033
1070
|
const rawTransaction = (0, ethereumjs_util_1.bufferToHex)(signedTransaction.serialize());
|
|
@@ -1065,35 +1102,41 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1065
1102
|
}
|
|
1066
1103
|
updateGasProperties(transactionMeta) {
|
|
1067
1104
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1068
|
-
const isEIP1559Compatible = (yield this.getEIP1559Compatibility()) &&
|
|
1105
|
+
const isEIP1559Compatible = (yield this.getEIP1559Compatibility(transactionMeta.networkClientId)) &&
|
|
1069
1106
|
transactionMeta.txParams.type !== types_1.TransactionEnvelopeType.legacy;
|
|
1070
|
-
const chainId =
|
|
1107
|
+
const { networkClientId, chainId } = transactionMeta;
|
|
1108
|
+
const isCustomNetwork = networkClientId
|
|
1109
|
+
? this.messagingSystem.call(`NetworkController:getNetworkClientById`, networkClientId).configuration.type === network_controller_1.NetworkClientType.Custom
|
|
1110
|
+
: this.getNetworkState().providerConfig.type === controller_utils_1.NetworkType.rpc;
|
|
1071
1111
|
yield (0, gas_1.updateGas)({
|
|
1072
|
-
ethQuery: this.
|
|
1073
|
-
|
|
1112
|
+
ethQuery: __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
1113
|
+
networkClientId,
|
|
1114
|
+
chainId,
|
|
1115
|
+
}),
|
|
1116
|
+
chainId,
|
|
1117
|
+
isCustomNetwork,
|
|
1074
1118
|
txMeta: transactionMeta,
|
|
1075
1119
|
});
|
|
1076
1120
|
yield (0, gas_fees_1.updateGasFees)({
|
|
1077
1121
|
eip1559: isEIP1559Compatible,
|
|
1078
|
-
ethQuery: this.
|
|
1079
|
-
|
|
1122
|
+
ethQuery: __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
1123
|
+
networkClientId,
|
|
1124
|
+
chainId,
|
|
1125
|
+
}),
|
|
1126
|
+
getSavedGasFees: this.getSavedGasFees.bind(this),
|
|
1080
1127
|
getGasFeeEstimates: this.getGasFeeEstimates.bind(this),
|
|
1081
1128
|
txMeta: transactionMeta,
|
|
1082
1129
|
});
|
|
1083
1130
|
});
|
|
1084
1131
|
}
|
|
1085
|
-
getCurrentChainTransactionsByStatus(status) {
|
|
1086
|
-
const chainId = this.getChainId();
|
|
1087
|
-
return this.state.transactions.filter((transaction) => transaction.status === status && transaction.chainId === chainId);
|
|
1088
|
-
}
|
|
1089
1132
|
onBootCleanup() {
|
|
1090
1133
|
this.submitApprovedTransactions();
|
|
1091
1134
|
}
|
|
1092
1135
|
/**
|
|
1093
|
-
* Force
|
|
1136
|
+
* Force submit approved transactions for all chains.
|
|
1094
1137
|
*/
|
|
1095
1138
|
submitApprovedTransactions() {
|
|
1096
|
-
const approvedTransactions = this.
|
|
1139
|
+
const approvedTransactions = this.state.transactions.filter((transaction) => transaction.status === types_1.TransactionStatus.approved);
|
|
1097
1140
|
for (const transactionMeta of approvedTransactions) {
|
|
1098
1141
|
if (this.beforeApproveOnInit(transactionMeta)) {
|
|
1099
1142
|
this.approveTransaction(transactionMeta.id).catch((error) => {
|
|
@@ -1187,10 +1230,9 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1187
1230
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1188
1231
|
const { transactions } = this.state;
|
|
1189
1232
|
const releaseLock = yield this.mutex.acquire();
|
|
1190
|
-
const chainId = this.getChainId();
|
|
1191
1233
|
const index = transactions.findIndex(({ id }) => transactionId === id);
|
|
1192
1234
|
const transactionMeta = transactions[index];
|
|
1193
|
-
const { txParams: { from }, } = transactionMeta;
|
|
1235
|
+
const { txParams: { from }, networkClientId, } = transactionMeta;
|
|
1194
1236
|
let releaseNonceLock;
|
|
1195
1237
|
try {
|
|
1196
1238
|
if (!this.sign) {
|
|
@@ -1198,7 +1240,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1198
1240
|
this.failTransaction(transactionMeta, new Error('No sign method defined.'));
|
|
1199
1241
|
return;
|
|
1200
1242
|
}
|
|
1201
|
-
else if (!chainId) {
|
|
1243
|
+
else if (!transactionMeta.chainId) {
|
|
1202
1244
|
releaseLock();
|
|
1203
1245
|
this.failTransaction(transactionMeta, new Error('No chainId defined.'));
|
|
1204
1246
|
return;
|
|
@@ -1207,11 +1249,11 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1207
1249
|
(0, logger_1.projectLogger)('Skipping approval as signing in progress', transactionId);
|
|
1208
1250
|
return;
|
|
1209
1251
|
}
|
|
1210
|
-
const [nonce, releaseNonce] = yield (0, nonce_1.getNextNonce)(transactionMeta, this.
|
|
1252
|
+
const [nonce, releaseNonce] = yield (0, nonce_1.getNextNonce)(transactionMeta, (address) => __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getNonceLock(address, networkClientId));
|
|
1211
1253
|
releaseNonceLock = releaseNonce;
|
|
1212
1254
|
transactionMeta.status = types_1.TransactionStatus.approved;
|
|
1213
1255
|
transactionMeta.txParams.nonce = nonce;
|
|
1214
|
-
transactionMeta.txParams.chainId = chainId;
|
|
1256
|
+
transactionMeta.txParams.chainId = transactionMeta.chainId;
|
|
1215
1257
|
const baseTxParams = Object.assign(Object.assign({}, transactionMeta.txParams), { gasLimit: transactionMeta.txParams.gas });
|
|
1216
1258
|
this.updateTransaction(transactionMeta, 'TransactionController#approveTransaction - Transaction approved');
|
|
1217
1259
|
this.onTransactionStatusChange(transactionMeta);
|
|
@@ -1227,16 +1269,20 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1227
1269
|
if (!rawTx) {
|
|
1228
1270
|
return;
|
|
1229
1271
|
}
|
|
1272
|
+
const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
1273
|
+
networkClientId: transactionMeta.networkClientId,
|
|
1274
|
+
chainId: transactionMeta.chainId,
|
|
1275
|
+
});
|
|
1230
1276
|
if (transactionMeta.type === types_1.TransactionType.swap) {
|
|
1231
1277
|
(0, logger_1.projectLogger)('Determining pre-transaction balance');
|
|
1232
|
-
const preTxBalance = yield (0, controller_utils_1.query)(
|
|
1278
|
+
const preTxBalance = yield (0, controller_utils_1.query)(ethQuery, 'getBalance', [from]);
|
|
1233
1279
|
transactionMeta.preTxBalance = preTxBalance;
|
|
1234
1280
|
(0, logger_1.projectLogger)('Updated pre-transaction balance', transactionMeta.preTxBalance);
|
|
1235
1281
|
}
|
|
1236
1282
|
(0, logger_1.projectLogger)('Publishing transaction', txParams);
|
|
1237
1283
|
let { transactionHash: hash } = yield this.publish(transactionMeta, rawTx);
|
|
1238
1284
|
if (hash === undefined) {
|
|
1239
|
-
hash = yield this.publishTransaction(rawTx);
|
|
1285
|
+
hash = yield this.publishTransaction(ethQuery, rawTx);
|
|
1240
1286
|
}
|
|
1241
1287
|
(0, logger_1.projectLogger)('Publish successful', hash);
|
|
1242
1288
|
transactionMeta.hash = hash;
|
|
@@ -1262,9 +1308,9 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1262
1308
|
}
|
|
1263
1309
|
});
|
|
1264
1310
|
}
|
|
1265
|
-
publishTransaction(rawTransaction) {
|
|
1311
|
+
publishTransaction(ethQuery, rawTransaction) {
|
|
1266
1312
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1267
|
-
return yield (0, controller_utils_1.query)(
|
|
1313
|
+
return yield (0, controller_utils_1.query)(ethQuery, 'sendRawTransaction', [rawTransaction]);
|
|
1268
1314
|
});
|
|
1269
1315
|
}
|
|
1270
1316
|
/**
|
|
@@ -1380,14 +1426,17 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1380
1426
|
const isCompleted = this.isLocalFinalState(transaction.status);
|
|
1381
1427
|
return { meta: transaction, isCompleted };
|
|
1382
1428
|
}
|
|
1383
|
-
getChainId() {
|
|
1429
|
+
getChainId(networkClientId) {
|
|
1430
|
+
if (networkClientId) {
|
|
1431
|
+
return this.messagingSystem.call(`NetworkController:getNetworkClientById`, networkClientId).configuration.chainId;
|
|
1432
|
+
}
|
|
1384
1433
|
const { providerConfig } = this.getNetworkState();
|
|
1385
1434
|
return providerConfig.chainId;
|
|
1386
1435
|
}
|
|
1387
|
-
prepareUnsignedEthTx(txParams) {
|
|
1436
|
+
prepareUnsignedEthTx(chainId, txParams) {
|
|
1388
1437
|
return tx_1.TransactionFactory.fromTxData(txParams, {
|
|
1389
|
-
common: this.getCommonConfiguration(),
|
|
1390
1438
|
freeze: false,
|
|
1439
|
+
common: this.getCommonConfiguration(chainId),
|
|
1391
1440
|
});
|
|
1392
1441
|
}
|
|
1393
1442
|
/**
|
|
@@ -1397,17 +1446,11 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1397
1446
|
* specified in txParams, @ethereumjs/tx is able to determine which EIP-2718
|
|
1398
1447
|
* transaction type to use.
|
|
1399
1448
|
*
|
|
1449
|
+
* @param chainId - The chainId to use for the configuration.
|
|
1400
1450
|
* @returns common configuration object
|
|
1401
1451
|
*/
|
|
1402
|
-
getCommonConfiguration() {
|
|
1403
|
-
const { providerConfig: { type: chain, chainId, nickname: name }, } = this.getNetworkState();
|
|
1404
|
-
if (chain !== controller_utils_1.RPC &&
|
|
1405
|
-
chain !== controller_utils_1.NetworkType['linea-goerli'] &&
|
|
1406
|
-
chain !== controller_utils_1.NetworkType['linea-mainnet']) {
|
|
1407
|
-
return new common_1.Common({ chain, hardfork: exports.HARDFORK });
|
|
1408
|
-
}
|
|
1452
|
+
getCommonConfiguration(chainId) {
|
|
1409
1453
|
const customChainParams = {
|
|
1410
|
-
name,
|
|
1411
1454
|
chainId: parseInt(chainId, 16),
|
|
1412
1455
|
defaultHardfork: exports.HARDFORK,
|
|
1413
1456
|
};
|
|
@@ -1462,7 +1505,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1462
1505
|
*/
|
|
1463
1506
|
addExternalTransaction(transactionMeta) {
|
|
1464
1507
|
var _a, _b;
|
|
1465
|
-
const chainId =
|
|
1508
|
+
const { chainId } = transactionMeta;
|
|
1466
1509
|
const { transactions } = this.state;
|
|
1467
1510
|
const fromAddress = (_a = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.txParams) === null || _a === void 0 ? void 0 : _a.from;
|
|
1468
1511
|
const sameFromAndNetworkTransactions = transactions.filter((transaction) => transaction.txParams.from === fromAddress &&
|
|
@@ -1489,10 +1532,13 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1489
1532
|
*/
|
|
1490
1533
|
markNonceDuplicatesDropped(transactionId) {
|
|
1491
1534
|
var _a, _b;
|
|
1492
|
-
const chainId = this.getChainId();
|
|
1493
1535
|
const transactionMeta = this.getTransaction(transactionId);
|
|
1494
|
-
|
|
1495
|
-
|
|
1536
|
+
if (!transactionMeta) {
|
|
1537
|
+
return;
|
|
1538
|
+
}
|
|
1539
|
+
const nonce = (_a = transactionMeta.txParams) === null || _a === void 0 ? void 0 : _a.nonce;
|
|
1540
|
+
const from = (_b = transactionMeta.txParams) === null || _b === void 0 ? void 0 : _b.from;
|
|
1541
|
+
const { chainId } = transactionMeta;
|
|
1496
1542
|
const sameNonceTxs = this.state.transactions.filter((transaction) => transaction.id !== transactionId &&
|
|
1497
1543
|
transaction.txParams.from === from &&
|
|
1498
1544
|
transaction.txParams.nonce === nonce &&
|
|
@@ -1503,8 +1549,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1503
1549
|
}
|
|
1504
1550
|
// Mark all same nonce transactions as dropped and give it a replacedBy hash
|
|
1505
1551
|
for (const transaction of sameNonceTxs) {
|
|
1506
|
-
transaction.replacedBy = transactionMeta
|
|
1507
|
-
transaction.replacedById = transactionMeta
|
|
1552
|
+
transaction.replacedBy = transactionMeta.hash;
|
|
1553
|
+
transaction.replacedById = transactionMeta.id;
|
|
1508
1554
|
// Drop any transaction that wasn't previously failed (off chain failure)
|
|
1509
1555
|
if (transaction.status !== types_1.TransactionStatus.failed) {
|
|
1510
1556
|
this.setTransactionStatusDropped(transaction);
|
|
@@ -1560,23 +1606,17 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1560
1606
|
}
|
|
1561
1607
|
});
|
|
1562
1608
|
}
|
|
1563
|
-
getEIP1559Compatibility() {
|
|
1609
|
+
getEIP1559Compatibility(networkClientId) {
|
|
1564
1610
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1565
|
-
const currentNetworkIsEIP1559Compatible = yield this.getCurrentNetworkEIP1559Compatibility();
|
|
1611
|
+
const currentNetworkIsEIP1559Compatible = yield this.getCurrentNetworkEIP1559Compatibility(networkClientId);
|
|
1566
1612
|
const currentAccountIsEIP1559Compatible = yield this.getCurrentAccountEIP1559Compatibility();
|
|
1567
1613
|
return (currentNetworkIsEIP1559Compatible && currentAccountIsEIP1559Compatible);
|
|
1568
1614
|
});
|
|
1569
1615
|
}
|
|
1570
|
-
addPendingTransactionTrackerListeners() {
|
|
1571
|
-
this.pendingTransactionTracker.hub.on('transaction-confirmed', this.onConfirmedTransaction.bind(this));
|
|
1572
|
-
this.pendingTransactionTracker.hub.on('transaction-dropped', this.setTransactionStatusDropped.bind(this));
|
|
1573
|
-
this.pendingTransactionTracker.hub.on('transaction-failed', this.failTransaction.bind(this));
|
|
1574
|
-
this.pendingTransactionTracker.hub.on('transaction-updated', this.updateTransaction.bind(this));
|
|
1575
|
-
}
|
|
1576
1616
|
signTransaction(transactionMeta, txParams) {
|
|
1577
1617
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1578
1618
|
(0, logger_1.projectLogger)('Signing transaction', txParams);
|
|
1579
|
-
const unsignedEthTx = this.prepareUnsignedEthTx(txParams);
|
|
1619
|
+
const unsignedEthTx = this.prepareUnsignedEthTx(transactionMeta.chainId, txParams);
|
|
1580
1620
|
this.inProcessOfSigning.add(transactionMeta.id);
|
|
1581
1621
|
const signedTx = yield new Promise((resolve, reject) => {
|
|
1582
1622
|
var _a;
|
|
@@ -1606,14 +1646,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1606
1646
|
onTransactionStatusChange(transactionMeta) {
|
|
1607
1647
|
this.hub.emit('transaction-status-update', { transactionMeta });
|
|
1608
1648
|
}
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
const externalPendingTransactions = this.getExternalPendingTransactions(address);
|
|
1612
|
-
return [...standardPendingTransactions, ...externalPendingTransactions];
|
|
1613
|
-
}
|
|
1614
|
-
getNonceTrackerTransactions(status, address) {
|
|
1615
|
-
const currentChainId = this.getChainId();
|
|
1616
|
-
return (0, nonce_1.getAndFormatTransactionsForNonceTracker)(currentChainId, address, status, this.state.transactions);
|
|
1649
|
+
getNonceTrackerTransactions(status, address, chainId = this.getChainId()) {
|
|
1650
|
+
return (0, nonce_1.getAndFormatTransactionsForNonceTracker)(chainId, address, status, this.state.transactions);
|
|
1617
1651
|
}
|
|
1618
1652
|
onConfirmedTransaction(transactionMeta) {
|
|
1619
1653
|
(0, logger_1.projectLogger)('Processing confirmed transaction', transactionMeta.id);
|
|
@@ -1631,8 +1665,12 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1631
1665
|
if (transactionMeta.type !== types_1.TransactionType.swap) {
|
|
1632
1666
|
return;
|
|
1633
1667
|
}
|
|
1668
|
+
const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
1669
|
+
networkClientId: transactionMeta.networkClientId,
|
|
1670
|
+
chainId: transactionMeta.chainId,
|
|
1671
|
+
});
|
|
1634
1672
|
const { updatedTransactionMeta, approvalTransactionMeta } = yield (0, swaps_1.updatePostTransactionBalance)(transactionMeta, {
|
|
1635
|
-
ethQuery
|
|
1673
|
+
ethQuery,
|
|
1636
1674
|
getTransaction: this.getTransaction.bind(this),
|
|
1637
1675
|
updateTransaction: this.updateTransaction.bind(this),
|
|
1638
1676
|
});
|
|
@@ -1647,10 +1685,10 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1647
1685
|
}
|
|
1648
1686
|
});
|
|
1649
1687
|
}
|
|
1650
|
-
publishTransactionForRetry(rawTx, transactionMeta) {
|
|
1688
|
+
publishTransactionForRetry(ethQuery, rawTx, transactionMeta) {
|
|
1651
1689
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1652
1690
|
try {
|
|
1653
|
-
const hash = yield this.publishTransaction(rawTx);
|
|
1691
|
+
const hash = yield this.publishTransaction(ethQuery, rawTx);
|
|
1654
1692
|
return hash;
|
|
1655
1693
|
}
|
|
1656
1694
|
catch (error) {
|
|
@@ -1678,4 +1716,75 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1678
1716
|
}
|
|
1679
1717
|
}
|
|
1680
1718
|
exports.TransactionController = TransactionController;
|
|
1719
|
+
_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, }) {
|
|
1720
|
+
return new nonce_tracker_1.NonceTracker({
|
|
1721
|
+
// TODO: Replace `any` with type
|
|
1722
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1723
|
+
provider: provider,
|
|
1724
|
+
blockTracker,
|
|
1725
|
+
getPendingTransactions: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getNonceTrackerPendingTransactions).bind(this, chainId),
|
|
1726
|
+
getConfirmedTransactions: this.getNonceTrackerTransactions.bind(this, types_1.TransactionStatus.confirmed),
|
|
1727
|
+
});
|
|
1728
|
+
}, _TransactionController_createIncomingTransactionHelper = function _TransactionController_createIncomingTransactionHelper({ blockTracker, etherscanRemoteTransactionSource, chainId, }) {
|
|
1729
|
+
const incomingTransactionHelper = new IncomingTransactionHelper_1.IncomingTransactionHelper({
|
|
1730
|
+
blockTracker,
|
|
1731
|
+
getCurrentAccount: this.getSelectedAddress,
|
|
1732
|
+
getLastFetchedBlockNumbers: () => this.state.lastFetchedBlockNumbers,
|
|
1733
|
+
getChainId: chainId ? () => chainId : this.getChainId.bind(this),
|
|
1734
|
+
isEnabled: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").isEnabled,
|
|
1735
|
+
queryEntireHistory: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").queryEntireHistory,
|
|
1736
|
+
remoteTransactionSource: etherscanRemoteTransactionSource,
|
|
1737
|
+
transactionLimit: this.config.txHistoryLimit,
|
|
1738
|
+
updateTransactions: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").updateTransactions,
|
|
1739
|
+
});
|
|
1740
|
+
__classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_addIncomingTransactionHelperListeners).call(this, incomingTransactionHelper);
|
|
1741
|
+
return incomingTransactionHelper;
|
|
1742
|
+
}, _TransactionController_createPendingTransactionTracker = function _TransactionController_createPendingTransactionTracker({ provider, blockTracker, chainId, }) {
|
|
1743
|
+
const ethQuery = new eth_query_1.default(provider);
|
|
1744
|
+
const getChainId = chainId ? () => chainId : this.getChainId.bind(this);
|
|
1745
|
+
const pendingTransactionTracker = new PendingTransactionTracker_1.PendingTransactionTracker({
|
|
1746
|
+
approveTransaction: this.approveTransaction.bind(this),
|
|
1747
|
+
blockTracker,
|
|
1748
|
+
getChainId,
|
|
1749
|
+
getEthQuery: () => ethQuery,
|
|
1750
|
+
getTransactions: () => this.state.transactions,
|
|
1751
|
+
isResubmitEnabled: __classPrivateFieldGet(this, _TransactionController_pendingTransactionOptions, "f").isResubmitEnabled,
|
|
1752
|
+
getGlobalLock: () => __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").acquireNonceLockForChainIdKey({
|
|
1753
|
+
chainId: getChainId(),
|
|
1754
|
+
}),
|
|
1755
|
+
publishTransaction: this.publishTransaction.bind(this),
|
|
1756
|
+
hooks: {
|
|
1757
|
+
beforeCheckPendingTransaction: this.beforeCheckPendingTransaction.bind(this),
|
|
1758
|
+
beforePublish: this.beforePublish.bind(this),
|
|
1759
|
+
},
|
|
1760
|
+
});
|
|
1761
|
+
__classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_addPendingTransactionTrackerListeners).call(this, pendingTransactionTracker);
|
|
1762
|
+
return pendingTransactionTracker;
|
|
1763
|
+
}, _TransactionController_stopAllTracking = function _TransactionController_stopAllTracking() {
|
|
1764
|
+
this.pendingTransactionTracker.stop();
|
|
1765
|
+
__classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removePendingTransactionTrackerListeners).call(this, this.pendingTransactionTracker);
|
|
1766
|
+
this.incomingTransactionHelper.stop();
|
|
1767
|
+
__classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removeIncomingTransactionHelperListeners).call(this, this.incomingTransactionHelper);
|
|
1768
|
+
__classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopAllTracking();
|
|
1769
|
+
}, _TransactionController_removeIncomingTransactionHelperListeners = function _TransactionController_removeIncomingTransactionHelperListeners(incomingTransactionHelper) {
|
|
1770
|
+
incomingTransactionHelper.hub.removeAllListeners('transactions');
|
|
1771
|
+
incomingTransactionHelper.hub.removeAllListeners('updatedLastFetchedBlockNumbers');
|
|
1772
|
+
}, _TransactionController_addIncomingTransactionHelperListeners = function _TransactionController_addIncomingTransactionHelperListeners(incomingTransactionHelper) {
|
|
1773
|
+
incomingTransactionHelper.hub.on('transactions', this.onIncomingTransactions.bind(this));
|
|
1774
|
+
incomingTransactionHelper.hub.on('updatedLastFetchedBlockNumbers', this.onUpdatedLastFetchedBlockNumbers.bind(this));
|
|
1775
|
+
}, _TransactionController_removePendingTransactionTrackerListeners = function _TransactionController_removePendingTransactionTrackerListeners(pendingTransactionTracker) {
|
|
1776
|
+
pendingTransactionTracker.hub.removeAllListeners('transaction-confirmed');
|
|
1777
|
+
pendingTransactionTracker.hub.removeAllListeners('transaction-dropped');
|
|
1778
|
+
pendingTransactionTracker.hub.removeAllListeners('transaction-failed');
|
|
1779
|
+
pendingTransactionTracker.hub.removeAllListeners('transaction-updated');
|
|
1780
|
+
}, _TransactionController_addPendingTransactionTrackerListeners = function _TransactionController_addPendingTransactionTrackerListeners(pendingTransactionTracker) {
|
|
1781
|
+
pendingTransactionTracker.hub.on('transaction-confirmed', this.onConfirmedTransaction.bind(this));
|
|
1782
|
+
pendingTransactionTracker.hub.on('transaction-dropped', this.setTransactionStatusDropped.bind(this));
|
|
1783
|
+
pendingTransactionTracker.hub.on('transaction-failed', this.failTransaction.bind(this));
|
|
1784
|
+
pendingTransactionTracker.hub.on('transaction-updated', this.updateTransaction.bind(this));
|
|
1785
|
+
}, _TransactionController_getNonceTrackerPendingTransactions = function _TransactionController_getNonceTrackerPendingTransactions(chainId, address) {
|
|
1786
|
+
const standardPendingTransactions = this.getNonceTrackerTransactions(types_1.TransactionStatus.submitted, address, chainId);
|
|
1787
|
+
const externalPendingTransactions = this.getExternalPendingTransactions(address, chainId);
|
|
1788
|
+
return [...standardPendingTransactions, ...externalPendingTransactions];
|
|
1789
|
+
};
|
|
1681
1790
|
//# sourceMappingURL=TransactionController.js.map
|