@metamask/transaction-controller 22.0.0 → 23.1.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 +51 -1
- package/dist/TransactionController.d.ts +106 -107
- package/dist/TransactionController.d.ts.map +1 -1
- package/dist/TransactionController.js +355 -219
- package/dist/TransactionController.js.map +1 -1
- package/dist/gas-flows/DefaultGasFeeFlow.d.ts +10 -0
- package/dist/gas-flows/DefaultGasFeeFlow.d.ts.map +1 -0
- package/dist/gas-flows/DefaultGasFeeFlow.js +78 -0
- package/dist/gas-flows/DefaultGasFeeFlow.js.map +1 -0
- package/dist/gas-flows/LineaGasFeeFlow.d.ts +12 -0
- package/dist/gas-flows/LineaGasFeeFlow.d.ts.map +1 -0
- package/dist/gas-flows/LineaGasFeeFlow.js +111 -0
- package/dist/gas-flows/LineaGasFeeFlow.js.map +1 -0
- package/dist/helpers/EtherscanRemoteTransactionSource.d.ts.map +1 -1
- package/dist/helpers/EtherscanRemoteTransactionSource.js +37 -14
- package/dist/helpers/EtherscanRemoteTransactionSource.js.map +1 -1
- package/dist/helpers/GasFeePoller.d.ts +32 -0
- package/dist/helpers/GasFeePoller.d.ts.map +1 -0
- package/dist/helpers/GasFeePoller.js +144 -0
- package/dist/helpers/GasFeePoller.js.map +1 -0
- 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/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +62 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +8 -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 +14 -19
- package/dist/utils/gas-fees.d.ts.map +1 -1
- package/dist/utils/gas-fees.js +24 -35
- package/dist/utils/gas-fees.js.map +1 -1
- package/dist/utils/gas-flow.d.ts +32 -0
- package/dist/utils/gas-flow.d.ts.map +1 -0
- package/dist/utils/gas-flow.js +53 -0
- package/dist/utils/gas-flow.js.map +1 -0
- package/dist/utils/gas.d.ts +4 -3
- package/dist/utils/gas.d.ts.map +1 -1
- package/dist/utils/gas.js +8 -10
- 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/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +15 -16
- package/dist/utils/utils.js.map +1 -1
- package/package.json +6 -3
|
@@ -8,26 +8,44 @@ 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, _TransactionController_getGasFeeFlows, _TransactionController_updateTransactionInternal;
|
|
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");
|
|
17
29
|
const tx_1 = require("@ethereumjs/tx");
|
|
30
|
+
const util_1 = require("@ethereumjs/util");
|
|
18
31
|
const base_controller_1 = require("@metamask/base-controller");
|
|
19
32
|
const controller_utils_1 = require("@metamask/controller-utils");
|
|
20
33
|
const eth_query_1 = __importDefault(require("@metamask/eth-query"));
|
|
34
|
+
const network_controller_1 = require("@metamask/network-controller");
|
|
21
35
|
const rpc_errors_1 = require("@metamask/rpc-errors");
|
|
36
|
+
const utils_1 = require("@metamask/utils");
|
|
22
37
|
const async_mutex_1 = require("async-mutex");
|
|
23
38
|
const eth_method_registry_1 = require("eth-method-registry");
|
|
24
|
-
const ethereumjs_util_1 = require("ethereumjs-util");
|
|
25
39
|
const events_1 = require("events");
|
|
26
40
|
const lodash_1 = require("lodash");
|
|
27
41
|
const nonce_tracker_1 = require("nonce-tracker");
|
|
28
42
|
const uuid_1 = require("uuid");
|
|
43
|
+
const DefaultGasFeeFlow_1 = require("./gas-flows/DefaultGasFeeFlow");
|
|
44
|
+
const LineaGasFeeFlow_1 = require("./gas-flows/LineaGasFeeFlow");
|
|
29
45
|
const EtherscanRemoteTransactionSource_1 = require("./helpers/EtherscanRemoteTransactionSource");
|
|
46
|
+
const GasFeePoller_1 = require("./helpers/GasFeePoller");
|
|
30
47
|
const IncomingTransactionHelper_1 = require("./helpers/IncomingTransactionHelper");
|
|
48
|
+
const MultichainTrackingHelper_1 = require("./helpers/MultichainTrackingHelper");
|
|
31
49
|
const PendingTransactionTracker_1 = require("./helpers/PendingTransactionTracker");
|
|
32
50
|
const logger_1 = require("./logger");
|
|
33
51
|
const types_1 = require("./types");
|
|
@@ -38,7 +56,7 @@ const history_1 = require("./utils/history");
|
|
|
38
56
|
const nonce_1 = require("./utils/nonce");
|
|
39
57
|
const swaps_1 = require("./utils/swaps");
|
|
40
58
|
const transaction_type_1 = require("./utils/transaction-type");
|
|
41
|
-
const
|
|
59
|
+
const utils_2 = require("./utils/utils");
|
|
42
60
|
const validation_1 = require("./utils/validation");
|
|
43
61
|
exports.HARDFORK = common_1.Hardfork.London;
|
|
44
62
|
/**
|
|
@@ -57,49 +75,16 @@ const controllerName = 'TransactionController';
|
|
|
57
75
|
* Controller responsible for submitting and managing transactions.
|
|
58
76
|
*/
|
|
59
77
|
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) {
|
|
78
|
+
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
79
|
var _a, _b, _c, _d, _e, _f;
|
|
99
80
|
super(config, state);
|
|
81
|
+
_TransactionController_instances.add(this);
|
|
100
82
|
this.inProcessOfSigning = new Set();
|
|
101
83
|
this.mutex = new async_mutex_1.Mutex();
|
|
84
|
+
_TransactionController_incomingTransactionOptions.set(this, void 0);
|
|
85
|
+
_TransactionController_pendingTransactionOptions.set(this, void 0);
|
|
102
86
|
this.signAbortCallbacks = new Map();
|
|
87
|
+
_TransactionController_multichainTrackingHelper.set(this, void 0);
|
|
103
88
|
/**
|
|
104
89
|
* EventEmitter instance used to listen to specific transactional events
|
|
105
90
|
*/
|
|
@@ -108,6 +93,11 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
108
93
|
* Name of this controller used during composition
|
|
109
94
|
*/
|
|
110
95
|
this.name = 'TransactionController';
|
|
96
|
+
_TransactionController_checkForPendingTransactionAndStartPolling.set(this, () => {
|
|
97
|
+
// PendingTransactionTracker reads state through its getTransactions hook
|
|
98
|
+
this.pendingTransactionTracker.startIfPendingTransactions();
|
|
99
|
+
__classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").checkForPendingTransactionAndStartPolling();
|
|
100
|
+
});
|
|
111
101
|
this.defaultConfig = {
|
|
112
102
|
txHistoryLimit: 40,
|
|
113
103
|
};
|
|
@@ -117,10 +107,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
117
107
|
lastFetchedBlockNumbers: {},
|
|
118
108
|
};
|
|
119
109
|
this.initialize();
|
|
120
|
-
this.provider = provider;
|
|
121
110
|
this.messagingSystem = messenger;
|
|
122
111
|
this.getNetworkState = getNetworkState;
|
|
123
|
-
this.ethQuery = new eth_query_1.default(provider);
|
|
124
112
|
this.isSendFlowHistoryDisabled = disableSendFlowHistory !== null && disableSendFlowHistory !== void 0 ? disableSendFlowHistory : false;
|
|
125
113
|
this.isHistoryDisabled = disableHistory !== null && disableHistory !== void 0 ? disableHistory : false;
|
|
126
114
|
this.isSwapsDisabled = disableSwaps !== null && disableSwaps !== void 0 ? disableSwaps : false;
|
|
@@ -138,6 +126,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
138
126
|
this.getExternalPendingTransactions =
|
|
139
127
|
getExternalPendingTransactions !== null && getExternalPendingTransactions !== void 0 ? getExternalPendingTransactions : (() => []);
|
|
140
128
|
this.securityProviderRequest = securityProviderRequest;
|
|
129
|
+
__classPrivateFieldSet(this, _TransactionController_incomingTransactionOptions, incomingTransactions, "f");
|
|
130
|
+
__classPrivateFieldSet(this, _TransactionController_pendingTransactionOptions, pendingTransactions, "f");
|
|
141
131
|
this.afterSign = (_a = hooks === null || hooks === void 0 ? void 0 : hooks.afterSign) !== null && _a !== void 0 ? _a : (() => true);
|
|
142
132
|
this.beforeApproveOnInit = (_b = hooks === null || hooks === void 0 ? void 0 : hooks.beforeApproveOnInit) !== null && _b !== void 0 ? _b : (() => true);
|
|
143
133
|
this.beforeCheckPendingTransaction =
|
|
@@ -149,56 +139,72 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
149
139
|
(_e = hooks === null || hooks === void 0 ? void 0 : hooks.getAdditionalSignArguments) !== null && _e !== void 0 ? _e : (() => []);
|
|
150
140
|
this.publish =
|
|
151
141
|
(_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>
|
|
142
|
+
this.nonceTracker = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createNonceTracker).call(this, {
|
|
154
143
|
provider,
|
|
155
144
|
blockTracker,
|
|
156
|
-
getPendingTransactions: this.getNonceTrackerPendingTransactions.bind(this),
|
|
157
|
-
getConfirmedTransactions: this.getNonceTrackerTransactions.bind(this, types_1.TransactionStatus.confirmed),
|
|
158
145
|
});
|
|
159
|
-
this
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
146
|
+
__classPrivateFieldSet(this, _TransactionController_multichainTrackingHelper, new MultichainTrackingHelper_1.MultichainTrackingHelper({
|
|
147
|
+
isMultichainEnabled,
|
|
148
|
+
provider,
|
|
149
|
+
nonceTracker: this.nonceTracker,
|
|
150
|
+
incomingTransactionOptions: incomingTransactions,
|
|
151
|
+
findNetworkClientIdByChainId: (chainId) => {
|
|
152
|
+
return this.messagingSystem.call(`NetworkController:findNetworkClientIdByChainId`, chainId);
|
|
153
|
+
},
|
|
154
|
+
getNetworkClientById: ((networkClientId) => {
|
|
155
|
+
return this.messagingSystem.call(`NetworkController:getNetworkClientById`, networkClientId);
|
|
168
156
|
}),
|
|
169
|
-
|
|
170
|
-
|
|
157
|
+
getNetworkClientRegistry,
|
|
158
|
+
removeIncomingTransactionHelperListeners: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removeIncomingTransactionHelperListeners).bind(this),
|
|
159
|
+
removePendingTransactionTrackerListeners: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removePendingTransactionTrackerListeners).bind(this),
|
|
160
|
+
createNonceTracker: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createNonceTracker).bind(this),
|
|
161
|
+
createIncomingTransactionHelper: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createIncomingTransactionHelper).bind(this),
|
|
162
|
+
createPendingTransactionTracker: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createPendingTransactionTracker).bind(this),
|
|
163
|
+
onNetworkStateChange: (listener) => {
|
|
164
|
+
this.messagingSystem.subscribe('NetworkController:stateChange', listener);
|
|
165
|
+
},
|
|
166
|
+
}), "f");
|
|
167
|
+
__classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").initialize();
|
|
168
|
+
const etherscanRemoteTransactionSource = new EtherscanRemoteTransactionSource_1.EtherscanRemoteTransactionSource({
|
|
169
|
+
includeTokenTransfers: incomingTransactions.includeTokenTransfers,
|
|
171
170
|
});
|
|
172
|
-
this.incomingTransactionHelper
|
|
173
|
-
this.incomingTransactionHelper.hub.on('updatedLastFetchedBlockNumbers', this.onUpdatedLastFetchedBlockNumbers.bind(this));
|
|
174
|
-
this.pendingTransactionTracker = new PendingTransactionTracker_1.PendingTransactionTracker({
|
|
175
|
-
approveTransaction: this.approveTransaction.bind(this),
|
|
171
|
+
this.incomingTransactionHelper = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createIncomingTransactionHelper).call(this, {
|
|
176
172
|
blockTracker,
|
|
177
|
-
|
|
178
|
-
|
|
173
|
+
etherscanRemoteTransactionSource,
|
|
174
|
+
});
|
|
175
|
+
this.pendingTransactionTracker = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createPendingTransactionTracker).call(this, {
|
|
176
|
+
provider,
|
|
177
|
+
blockTracker,
|
|
178
|
+
});
|
|
179
|
+
this.gasFeeFlows = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getGasFeeFlows).call(this);
|
|
180
|
+
const gasFeePoller = new GasFeePoller_1.GasFeePoller({
|
|
181
|
+
// Default gas fee polling is not yet supported by the clients
|
|
182
|
+
gasFeeFlows: this.gasFeeFlows.slice(0, -1),
|
|
183
|
+
getEthQuery: (chainId, networkClientId) => __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
184
|
+
networkClientId,
|
|
185
|
+
chainId,
|
|
186
|
+
}),
|
|
187
|
+
getGasFeeControllerEstimates: this.getGasFeeEstimates,
|
|
179
188
|
getTransactions: () => this.state.transactions,
|
|
180
|
-
isResubmitEnabled: pendingTransactions.isResubmitEnabled,
|
|
181
|
-
nonceTracker: this.nonceTracker,
|
|
182
189
|
onStateChange: (listener) => {
|
|
183
190
|
this.subscribe(listener);
|
|
184
|
-
onNetworkStateChange(listener);
|
|
185
|
-
listener();
|
|
186
|
-
},
|
|
187
|
-
publishTransaction: this.publishTransaction.bind(this),
|
|
188
|
-
hooks: {
|
|
189
|
-
beforeCheckPendingTransaction: this.beforeCheckPendingTransaction.bind(this),
|
|
190
|
-
beforePublish: this.beforePublish.bind(this),
|
|
191
191
|
},
|
|
192
192
|
});
|
|
193
|
-
this.
|
|
193
|
+
gasFeePoller.hub.on('transaction-updated', (transactionMeta) => __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateTransactionInternal).call(this, transactionMeta, { skipHistory: true }));
|
|
194
|
+
// when transactionsController state changes
|
|
195
|
+
// check for pending transactions and start polling if there are any
|
|
196
|
+
this.subscribe(__classPrivateFieldGet(this, _TransactionController_checkForPendingTransactionAndStartPolling, "f"));
|
|
197
|
+
// TODO once v2 is merged make sure this only runs when
|
|
198
|
+
// selectedNetworkClientId changes
|
|
194
199
|
onNetworkStateChange(() => {
|
|
195
200
|
(0, logger_1.projectLogger)('Detected network change', this.getChainId());
|
|
201
|
+
this.pendingTransactionTracker.startIfPendingTransactions();
|
|
196
202
|
this.onBootCleanup();
|
|
197
203
|
});
|
|
198
204
|
this.onBootCleanup();
|
|
199
205
|
}
|
|
200
206
|
failTransaction(transactionMeta, error, actionId) {
|
|
201
|
-
const newTransactionMeta = Object.assign(Object.assign({}, transactionMeta), { error: (0,
|
|
207
|
+
const newTransactionMeta = Object.assign(Object.assign({}, transactionMeta), { error: (0, utils_2.normalizeTxError)(error), status: types_1.TransactionStatus.failed });
|
|
202
208
|
this.hub.emit('transaction-failed', {
|
|
203
209
|
actionId,
|
|
204
210
|
error: error.message,
|
|
@@ -215,6 +221,12 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
215
221
|
return { registryMethod, parsedRegistryMethod };
|
|
216
222
|
});
|
|
217
223
|
}
|
|
224
|
+
/**
|
|
225
|
+
* Stops polling and removes listeners to prepare the controller for garbage collection.
|
|
226
|
+
*/
|
|
227
|
+
destroy() {
|
|
228
|
+
__classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_stopAllTracking).call(this);
|
|
229
|
+
}
|
|
218
230
|
/**
|
|
219
231
|
* Handle new method data request.
|
|
220
232
|
*
|
|
@@ -259,21 +271,30 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
259
271
|
* @param opts.swaps - Options for swaps transactions.
|
|
260
272
|
* @param opts.swaps.hasApproveTx - Whether the transaction has an approval transaction.
|
|
261
273
|
* @param opts.swaps.meta - Metadata for swap transaction.
|
|
274
|
+
* @param opts.networkClientId - The id of the network client for this transaction.
|
|
262
275
|
* @returns Object containing a promise resolving to the transaction hash if approved.
|
|
263
276
|
*/
|
|
264
|
-
addTransaction(txParams, { actionId, deviceConfirmedOn, method, origin, requireApproval, securityAlertResponse, sendFlowHistory, swaps = {}, type, } = {}) {
|
|
277
|
+
addTransaction(txParams, { actionId, deviceConfirmedOn, method, origin, requireApproval, securityAlertResponse, sendFlowHistory, swaps = {}, type, networkClientId, } = {}) {
|
|
265
278
|
return __awaiter(this, void 0, void 0, function* () {
|
|
266
279
|
(0, logger_1.projectLogger)('Adding transaction', txParams);
|
|
267
|
-
txParams = (0,
|
|
268
|
-
|
|
280
|
+
txParams = (0, utils_2.normalizeTxParams)(txParams);
|
|
281
|
+
if (networkClientId &&
|
|
282
|
+
!__classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").has(networkClientId)) {
|
|
283
|
+
throw new Error('The networkClientId for this transaction could not be found');
|
|
284
|
+
}
|
|
285
|
+
const isEIP1559Compatible = yield this.getEIP1559Compatibility(networkClientId);
|
|
269
286
|
(0, validation_1.validateTxParams)(txParams, isEIP1559Compatible);
|
|
270
287
|
if (origin) {
|
|
271
288
|
yield (0, validation_1.validateTransactionOrigin)(yield this.getPermittedAccounts(origin), this.getSelectedAddress(), txParams.from, origin);
|
|
272
289
|
}
|
|
273
290
|
const dappSuggestedGasFees = this.generateDappSuggestedGasFees(txParams, origin);
|
|
274
|
-
const
|
|
291
|
+
const chainId = this.getChainId(networkClientId);
|
|
292
|
+
const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
293
|
+
networkClientId,
|
|
294
|
+
chainId,
|
|
295
|
+
});
|
|
296
|
+
const transactionType = type !== null && type !== void 0 ? type : (yield (0, transaction_type_1.determineTransactionType)(txParams, ethQuery)).type;
|
|
275
297
|
const existingTransactionMeta = this.getTransactionWithActionId(actionId);
|
|
276
|
-
const chainId = this.getChainId();
|
|
277
298
|
// If a request to add a transaction with the same actionId is submitted again, a new transaction will not be created for it.
|
|
278
299
|
const transactionMeta = existingTransactionMeta || {
|
|
279
300
|
// Add actionId to txMeta to check if same actionId is seen again
|
|
@@ -290,6 +311,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
290
311
|
userEditedGasLimit: false,
|
|
291
312
|
verifiedOnBlockchain: false,
|
|
292
313
|
type: transactionType,
|
|
314
|
+
networkClientId,
|
|
293
315
|
};
|
|
294
316
|
yield this.updateGasProperties(transactionMeta);
|
|
295
317
|
// Checks if a transaction already exists with a given actionId
|
|
@@ -326,15 +348,31 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
326
348
|
};
|
|
327
349
|
});
|
|
328
350
|
}
|
|
329
|
-
startIncomingTransactionPolling() {
|
|
330
|
-
|
|
351
|
+
startIncomingTransactionPolling(networkClientIds = []) {
|
|
352
|
+
if (networkClientIds.length === 0) {
|
|
353
|
+
this.incomingTransactionHelper.start();
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
__classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").startIncomingTransactionPolling(networkClientIds);
|
|
357
|
+
}
|
|
358
|
+
stopIncomingTransactionPolling(networkClientIds = []) {
|
|
359
|
+
if (networkClientIds.length === 0) {
|
|
360
|
+
this.incomingTransactionHelper.stop();
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
__classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopIncomingTransactionPolling(networkClientIds);
|
|
331
364
|
}
|
|
332
|
-
|
|
365
|
+
stopAllIncomingTransactionPolling() {
|
|
333
366
|
this.incomingTransactionHelper.stop();
|
|
367
|
+
__classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopAllIncomingTransactionPolling();
|
|
334
368
|
}
|
|
335
|
-
updateIncomingTransactions() {
|
|
369
|
+
updateIncomingTransactions(networkClientIds = []) {
|
|
336
370
|
return __awaiter(this, void 0, void 0, function* () {
|
|
337
|
-
|
|
371
|
+
if (networkClientIds.length === 0) {
|
|
372
|
+
yield this.incomingTransactionHelper.update();
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
yield __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").updateIncomingTransactions(networkClientIds);
|
|
338
376
|
});
|
|
339
377
|
}
|
|
340
378
|
/**
|
|
@@ -356,8 +394,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
356
394
|
}
|
|
357
395
|
if (gasValues) {
|
|
358
396
|
// Not good practice to reassign a parameter but temporarily avoiding a larger refactor.
|
|
359
|
-
gasValues = (0,
|
|
360
|
-
(0,
|
|
397
|
+
gasValues = (0, utils_2.normalizeGasFeeValues)(gasValues);
|
|
398
|
+
(0, utils_2.validateGasValues)(gasValues);
|
|
361
399
|
}
|
|
362
400
|
(0, logger_1.projectLogger)('Creating cancel transaction', transactionId, gasValues);
|
|
363
401
|
const transactionMeta = this.getTransaction(transactionId);
|
|
@@ -368,24 +406,24 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
368
406
|
throw new Error('No sign method defined.');
|
|
369
407
|
}
|
|
370
408
|
// gasPrice (legacy non EIP1559)
|
|
371
|
-
const minGasPrice = (0,
|
|
372
|
-
const gasPriceFromValues = (0,
|
|
409
|
+
const minGasPrice = (0, utils_2.getIncreasedPriceFromExisting)(transactionMeta.txParams.gasPrice, exports.CANCEL_RATE);
|
|
410
|
+
const gasPriceFromValues = (0, utils_2.isGasPriceValue)(gasValues) && gasValues.gasPrice;
|
|
373
411
|
const newGasPrice = (gasPriceFromValues &&
|
|
374
|
-
(0,
|
|
412
|
+
(0, utils_2.validateMinimumIncrease)(gasPriceFromValues, minGasPrice)) ||
|
|
375
413
|
minGasPrice;
|
|
376
414
|
// maxFeePerGas (EIP1559)
|
|
377
415
|
const existingMaxFeePerGas = (_a = transactionMeta.txParams) === null || _a === void 0 ? void 0 : _a.maxFeePerGas;
|
|
378
|
-
const minMaxFeePerGas = (0,
|
|
379
|
-
const maxFeePerGasValues = (0,
|
|
416
|
+
const minMaxFeePerGas = (0, utils_2.getIncreasedPriceFromExisting)(existingMaxFeePerGas, exports.CANCEL_RATE);
|
|
417
|
+
const maxFeePerGasValues = (0, utils_2.isFeeMarketEIP1559Values)(gasValues) && gasValues.maxFeePerGas;
|
|
380
418
|
const newMaxFeePerGas = (maxFeePerGasValues &&
|
|
381
|
-
(0,
|
|
419
|
+
(0, utils_2.validateMinimumIncrease)(maxFeePerGasValues, minMaxFeePerGas)) ||
|
|
382
420
|
(existingMaxFeePerGas && minMaxFeePerGas);
|
|
383
421
|
// maxPriorityFeePerGas (EIP1559)
|
|
384
422
|
const existingMaxPriorityFeePerGas = (_b = transactionMeta.txParams) === null || _b === void 0 ? void 0 : _b.maxPriorityFeePerGas;
|
|
385
|
-
const minMaxPriorityFeePerGas = (0,
|
|
386
|
-
const maxPriorityFeePerGasValues = (0,
|
|
423
|
+
const minMaxPriorityFeePerGas = (0, utils_2.getIncreasedPriceFromExisting)(existingMaxPriorityFeePerGas, exports.CANCEL_RATE);
|
|
424
|
+
const maxPriorityFeePerGasValues = (0, utils_2.isFeeMarketEIP1559Values)(gasValues) && gasValues.maxPriorityFeePerGas;
|
|
387
425
|
const newMaxPriorityFeePerGas = (maxPriorityFeePerGasValues &&
|
|
388
|
-
(0,
|
|
426
|
+
(0, utils_2.validateMinimumIncrease)(maxPriorityFeePerGasValues, minMaxPriorityFeePerGas)) ||
|
|
389
427
|
(existingMaxPriorityFeePerGas && minMaxPriorityFeePerGas);
|
|
390
428
|
const newTxParams = newMaxFeePerGas && newMaxPriorityFeePerGas
|
|
391
429
|
? {
|
|
@@ -406,9 +444,9 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
406
444
|
to: transactionMeta.txParams.from,
|
|
407
445
|
value: '0x0',
|
|
408
446
|
};
|
|
409
|
-
const unsignedEthTx = this.prepareUnsignedEthTx(newTxParams);
|
|
447
|
+
const unsignedEthTx = this.prepareUnsignedEthTx(transactionMeta.chainId, newTxParams);
|
|
410
448
|
const signedTx = yield this.sign(unsignedEthTx, transactionMeta.txParams.from);
|
|
411
|
-
const rawTx = (0,
|
|
449
|
+
const rawTx = (0, util_1.bufferToHex)(signedTx.serialize());
|
|
412
450
|
const newFee = (_c = newTxParams.maxFeePerGas) !== null && _c !== void 0 ? _c : newTxParams.gasPrice;
|
|
413
451
|
const oldFee = newTxParams.maxFeePerGas
|
|
414
452
|
? transactionMeta.txParams.maxFeePerGas
|
|
@@ -418,10 +456,15 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
418
456
|
newFee,
|
|
419
457
|
txParams: newTxParams,
|
|
420
458
|
});
|
|
421
|
-
const
|
|
459
|
+
const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
460
|
+
networkClientId: transactionMeta.networkClientId,
|
|
461
|
+
chainId: transactionMeta.chainId,
|
|
462
|
+
});
|
|
463
|
+
const hash = yield this.publishTransactionForRetry(ethQuery, rawTx, transactionMeta);
|
|
422
464
|
const cancelTransactionMeta = {
|
|
423
465
|
actionId,
|
|
424
466
|
chainId: transactionMeta.chainId,
|
|
467
|
+
networkClientId: transactionMeta.networkClientId,
|
|
425
468
|
estimatedBaseFee,
|
|
426
469
|
hash,
|
|
427
470
|
id: (0, uuid_1.v1)(),
|
|
@@ -462,8 +505,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
462
505
|
}
|
|
463
506
|
if (gasValues) {
|
|
464
507
|
// Not good practice to reassign a parameter but temporarily avoiding a larger refactor.
|
|
465
|
-
gasValues = (0,
|
|
466
|
-
(0,
|
|
508
|
+
gasValues = (0, utils_2.normalizeGasFeeValues)(gasValues);
|
|
509
|
+
(0, utils_2.validateGasValues)(gasValues);
|
|
467
510
|
}
|
|
468
511
|
(0, logger_1.projectLogger)('Creating speed up transaction', transactionId, gasValues);
|
|
469
512
|
const transactionMeta = this.state.transactions.find(({ id }) => id === transactionId);
|
|
@@ -476,37 +519,41 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
476
519
|
throw new Error('No sign method defined.');
|
|
477
520
|
}
|
|
478
521
|
// gasPrice (legacy non EIP1559)
|
|
479
|
-
const minGasPrice = (0,
|
|
480
|
-
const gasPriceFromValues = (0,
|
|
522
|
+
const minGasPrice = (0, utils_2.getIncreasedPriceFromExisting)(transactionMeta.txParams.gasPrice, exports.SPEED_UP_RATE);
|
|
523
|
+
const gasPriceFromValues = (0, utils_2.isGasPriceValue)(gasValues) && gasValues.gasPrice;
|
|
481
524
|
const newGasPrice = (gasPriceFromValues &&
|
|
482
|
-
(0,
|
|
525
|
+
(0, utils_2.validateMinimumIncrease)(gasPriceFromValues, minGasPrice)) ||
|
|
483
526
|
minGasPrice;
|
|
484
527
|
// maxFeePerGas (EIP1559)
|
|
485
528
|
const existingMaxFeePerGas = (_a = transactionMeta.txParams) === null || _a === void 0 ? void 0 : _a.maxFeePerGas;
|
|
486
|
-
const minMaxFeePerGas = (0,
|
|
487
|
-
const maxFeePerGasValues = (0,
|
|
529
|
+
const minMaxFeePerGas = (0, utils_2.getIncreasedPriceFromExisting)(existingMaxFeePerGas, exports.SPEED_UP_RATE);
|
|
530
|
+
const maxFeePerGasValues = (0, utils_2.isFeeMarketEIP1559Values)(gasValues) && gasValues.maxFeePerGas;
|
|
488
531
|
const newMaxFeePerGas = (maxFeePerGasValues &&
|
|
489
|
-
(0,
|
|
532
|
+
(0, utils_2.validateMinimumIncrease)(maxFeePerGasValues, minMaxFeePerGas)) ||
|
|
490
533
|
(existingMaxFeePerGas && minMaxFeePerGas);
|
|
491
534
|
// maxPriorityFeePerGas (EIP1559)
|
|
492
535
|
const existingMaxPriorityFeePerGas = (_b = transactionMeta.txParams) === null || _b === void 0 ? void 0 : _b.maxPriorityFeePerGas;
|
|
493
|
-
const minMaxPriorityFeePerGas = (0,
|
|
494
|
-
const maxPriorityFeePerGasValues = (0,
|
|
536
|
+
const minMaxPriorityFeePerGas = (0, utils_2.getIncreasedPriceFromExisting)(existingMaxPriorityFeePerGas, exports.SPEED_UP_RATE);
|
|
537
|
+
const maxPriorityFeePerGasValues = (0, utils_2.isFeeMarketEIP1559Values)(gasValues) && gasValues.maxPriorityFeePerGas;
|
|
495
538
|
const newMaxPriorityFeePerGas = (maxPriorityFeePerGasValues &&
|
|
496
|
-
(0,
|
|
539
|
+
(0, utils_2.validateMinimumIncrease)(maxPriorityFeePerGasValues, minMaxPriorityFeePerGas)) ||
|
|
497
540
|
(existingMaxPriorityFeePerGas && minMaxPriorityFeePerGas);
|
|
498
541
|
const txParams = newMaxFeePerGas && newMaxPriorityFeePerGas
|
|
499
542
|
? 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);
|
|
543
|
+
const unsignedEthTx = this.prepareUnsignedEthTx(transactionMeta.chainId, txParams);
|
|
501
544
|
const signedTx = yield this.sign(unsignedEthTx, transactionMeta.txParams.from);
|
|
502
545
|
yield this.updateTransactionMetaRSV(transactionMeta, signedTx);
|
|
503
|
-
const rawTx = (0,
|
|
546
|
+
const rawTx = (0, util_1.bufferToHex)(signedTx.serialize());
|
|
504
547
|
const newFee = (_c = txParams.maxFeePerGas) !== null && _c !== void 0 ? _c : txParams.gasPrice;
|
|
505
548
|
const oldFee = txParams.maxFeePerGas
|
|
506
549
|
? transactionMeta.txParams.maxFeePerGas
|
|
507
550
|
: transactionMeta.txParams.gasPrice;
|
|
508
551
|
(0, logger_1.projectLogger)('Submitting speed up transaction', { oldFee, newFee, txParams });
|
|
509
|
-
const
|
|
552
|
+
const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
553
|
+
networkClientId: transactionMeta.networkClientId,
|
|
554
|
+
chainId: transactionMeta.chainId,
|
|
555
|
+
});
|
|
556
|
+
const hash = yield this.publishTransactionForRetry(ethQuery, rawTx, transactionMeta);
|
|
510
557
|
const baseTransactionMeta = Object.assign(Object.assign({}, transactionMeta), { estimatedBaseFee, id: (0, uuid_1.v1)(), time: Date.now(), hash,
|
|
511
558
|
actionId, originalGasEstimate: transactionMeta.txParams.gas, type: types_1.TransactionType.retry, originalType: transactionMeta.type });
|
|
512
559
|
const newTransactionMeta = newMaxFeePerGas && newMaxPriorityFeePerGas
|
|
@@ -528,11 +575,15 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
528
575
|
* Estimates required gas for a given transaction.
|
|
529
576
|
*
|
|
530
577
|
* @param transaction - The transaction to estimate gas for.
|
|
578
|
+
* @param networkClientId - The network client id to use for the estimate.
|
|
531
579
|
* @returns The gas and gas price.
|
|
532
580
|
*/
|
|
533
|
-
estimateGas(transaction) {
|
|
581
|
+
estimateGas(transaction, networkClientId) {
|
|
534
582
|
return __awaiter(this, void 0, void 0, function* () {
|
|
535
|
-
const
|
|
583
|
+
const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
584
|
+
networkClientId,
|
|
585
|
+
});
|
|
586
|
+
const { estimatedGas, simulationFails } = yield (0, gas_1.estimateGas)(transaction, ethQuery);
|
|
536
587
|
return { gas: estimatedGas, simulationFails };
|
|
537
588
|
});
|
|
538
589
|
}
|
|
@@ -541,10 +592,14 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
541
592
|
*
|
|
542
593
|
* @param transaction - The transaction params to estimate gas for.
|
|
543
594
|
* @param multiplier - The multiplier to use for the gas buffer.
|
|
595
|
+
* @param networkClientId - The network client id to use for the estimate.
|
|
544
596
|
*/
|
|
545
|
-
estimateGasBuffered(transaction, multiplier) {
|
|
597
|
+
estimateGasBuffered(transaction, multiplier, networkClientId) {
|
|
546
598
|
return __awaiter(this, void 0, void 0, function* () {
|
|
547
|
-
const
|
|
599
|
+
const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
600
|
+
networkClientId,
|
|
601
|
+
});
|
|
602
|
+
const { blockGasLimit, estimatedGas, simulationFails } = yield (0, gas_1.estimateGas)(transaction, ethQuery);
|
|
548
603
|
const gas = (0, gas_1.addGasBuffer)(estimatedGas, blockGasLimit, multiplier);
|
|
549
604
|
return {
|
|
550
605
|
gas,
|
|
@@ -559,15 +614,10 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
559
614
|
* @param note - A note or update reason to include in the transaction history.
|
|
560
615
|
*/
|
|
561
616
|
updateTransaction(transactionMeta, note) {
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
(0, history_1.updateTransactionHistory)(transactionMeta, note);
|
|
567
|
-
}
|
|
568
|
-
const index = transactions.findIndex(({ id }) => transactionMeta.id === id);
|
|
569
|
-
transactions[index] = transactionMeta;
|
|
570
|
-
this.update({ transactions: this.trimTransactionsForState(transactions) });
|
|
617
|
+
__classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateTransactionInternal).call(this, transactionMeta, {
|
|
618
|
+
note,
|
|
619
|
+
skipHistory: this.isHistoryDisabled,
|
|
620
|
+
});
|
|
571
621
|
}
|
|
572
622
|
/**
|
|
573
623
|
* Update the security alert response for a transaction.
|
|
@@ -614,12 +664,6 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
614
664
|
transactions: this.trimTransactionsForState(newTransactions),
|
|
615
665
|
});
|
|
616
666
|
}
|
|
617
|
-
startIncomingTransactionProcessing() {
|
|
618
|
-
this.incomingTransactionHelper.start();
|
|
619
|
-
}
|
|
620
|
-
stopIncomingTransactionProcessing() {
|
|
621
|
-
this.incomingTransactionHelper.stop();
|
|
622
|
-
}
|
|
623
667
|
/**
|
|
624
668
|
* Adds external provided transaction to state as confirmed transaction.
|
|
625
669
|
*
|
|
@@ -673,7 +717,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
673
717
|
if (!transactionMeta) {
|
|
674
718
|
throw new Error(`Cannot update send flow history as no transaction metadata found`);
|
|
675
719
|
}
|
|
676
|
-
(0,
|
|
720
|
+
(0, utils_2.validateIfTransactionUnapproved)(transactionMeta, 'updateTransactionSendFlowHistory');
|
|
677
721
|
if (currentSendFlowHistoryLength ===
|
|
678
722
|
(((_a = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.sendFlowHistory) === null || _a === void 0 ? void 0 : _a.length) || 0)) {
|
|
679
723
|
transactionMeta.sendFlowHistory = [
|
|
@@ -707,7 +751,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
707
751
|
if (!transactionMeta) {
|
|
708
752
|
throw new Error(`Cannot update transaction as no transaction metadata found`);
|
|
709
753
|
}
|
|
710
|
-
(0,
|
|
754
|
+
(0, utils_2.validateIfTransactionUnapproved)(transactionMeta, 'updateTransactionGasFees');
|
|
711
755
|
let transactionGasFees = {
|
|
712
756
|
txParams: {
|
|
713
757
|
gas,
|
|
@@ -748,7 +792,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
748
792
|
if (!transactionMeta) {
|
|
749
793
|
throw new Error(`Cannot update transaction as no transaction metadata found`);
|
|
750
794
|
}
|
|
751
|
-
(0,
|
|
795
|
+
(0, utils_2.validateIfTransactionUnapproved)(transactionMeta, 'updatePreviousGasParams');
|
|
752
796
|
const transactionPreviousGas = {
|
|
753
797
|
previousGas: {
|
|
754
798
|
gasLimit,
|
|
@@ -765,16 +809,9 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
765
809
|
this.updateTransaction(updatedMeta, 'TransactionController:updatePreviousGasParams - Previous gas values updated');
|
|
766
810
|
return this.getTransaction(transactionId);
|
|
767
811
|
}
|
|
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) {
|
|
812
|
+
getNonceLock(address, networkClientId) {
|
|
776
813
|
return __awaiter(this, void 0, void 0, function* () {
|
|
777
|
-
return this.
|
|
814
|
+
return __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getNonceLock(address, networkClientId);
|
|
778
815
|
});
|
|
779
816
|
}
|
|
780
817
|
/**
|
|
@@ -796,7 +833,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
796
833
|
if (!transactionMeta) {
|
|
797
834
|
throw new Error(`Cannot update editable params as no transaction metadata found`);
|
|
798
835
|
}
|
|
799
|
-
(0,
|
|
836
|
+
(0, utils_2.validateIfTransactionUnapproved)(transactionMeta, 'updateEditableParams');
|
|
800
837
|
const editableParams = {
|
|
801
838
|
txParams: {
|
|
802
839
|
data,
|
|
@@ -809,7 +846,10 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
809
846
|
};
|
|
810
847
|
editableParams.txParams = (0, lodash_1.pickBy)(editableParams.txParams);
|
|
811
848
|
const updatedTransaction = (0, lodash_1.merge)(transactionMeta, editableParams);
|
|
812
|
-
const { type } = yield (0, transaction_type_1.determineTransactionType)(updatedTransaction.txParams, this.
|
|
849
|
+
const { type } = yield (0, transaction_type_1.determineTransactionType)(updatedTransaction.txParams, __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
850
|
+
networkClientId: transactionMeta.networkClientId,
|
|
851
|
+
chainId: transactionMeta.chainId,
|
|
852
|
+
}));
|
|
813
853
|
updatedTransaction.type = type;
|
|
814
854
|
this.updateTransaction(updatedTransaction, `Update Editable Params for ${txId}`);
|
|
815
855
|
return this.getTransaction(txId);
|
|
@@ -832,11 +872,23 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
832
872
|
return '';
|
|
833
873
|
}
|
|
834
874
|
const initialTx = listOfTxParams[0];
|
|
835
|
-
const common = this.getCommonConfiguration();
|
|
875
|
+
const common = this.getCommonConfiguration(initialTx.chainId);
|
|
876
|
+
// We need to ensure we get the nonce using the the NonceTracker on the chain matching
|
|
877
|
+
// the txParams. In this context we only have chainId available to us, but the
|
|
878
|
+
// NonceTrackers are keyed by networkClientId. To workaround this, we attempt to find
|
|
879
|
+
// a networkClientId that matches the chainId. As a fallback, the globally selected
|
|
880
|
+
// network's NonceTracker will be used instead.
|
|
881
|
+
let networkClientId;
|
|
882
|
+
try {
|
|
883
|
+
networkClientId = this.messagingSystem.call(`NetworkController:findNetworkClientIdByChainId`, initialTx.chainId);
|
|
884
|
+
}
|
|
885
|
+
catch (err) {
|
|
886
|
+
(0, logger_1.projectLogger)('failed to find networkClientId from chainId', err);
|
|
887
|
+
}
|
|
836
888
|
const initialTxAsEthTx = tx_1.TransactionFactory.fromTxData(initialTx, {
|
|
837
889
|
common,
|
|
838
890
|
});
|
|
839
|
-
const initialTxAsSerializedHex = (0,
|
|
891
|
+
const initialTxAsSerializedHex = (0, util_1.bufferToHex)(initialTxAsEthTx.serialize());
|
|
840
892
|
if (this.inProcessOfSigning.has(initialTxAsSerializedHex)) {
|
|
841
893
|
return '';
|
|
842
894
|
}
|
|
@@ -847,17 +899,17 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
847
899
|
const fromAddress = initialTx.from;
|
|
848
900
|
const requiresNonce = hasNonce !== true;
|
|
849
901
|
nonceLock = requiresNonce
|
|
850
|
-
? yield this.
|
|
902
|
+
? yield this.getNonceLock(fromAddress, networkClientId)
|
|
851
903
|
: undefined;
|
|
852
904
|
const nonce = nonceLock
|
|
853
|
-
? (0,
|
|
905
|
+
? (0, utils_1.add0x)(nonceLock.nextNonce.toString(16))
|
|
854
906
|
: initialTx.nonce;
|
|
855
907
|
if (nonceLock) {
|
|
856
908
|
(0, logger_1.projectLogger)('Using nonce from nonce tracker', nonce, nonceLock.nonceDetails);
|
|
857
909
|
}
|
|
858
910
|
rawTransactions = yield Promise.all(listOfTxParams.map((txParams) => {
|
|
859
911
|
txParams.nonce = nonce;
|
|
860
|
-
return this.signExternalTransaction(txParams);
|
|
912
|
+
return this.signExternalTransaction(txParams.chainId, txParams);
|
|
861
913
|
}));
|
|
862
914
|
}
|
|
863
915
|
catch (err) {
|
|
@@ -903,7 +955,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
903
955
|
updatedTransactionMeta.submittedTime = new Date().getTime();
|
|
904
956
|
}
|
|
905
957
|
if (status === types_1.TransactionStatus.failed) {
|
|
906
|
-
updatedTransactionMeta.error = (0,
|
|
958
|
+
updatedTransactionMeta.error = (0, utils_2.normalizeTxError)(new Error(errorMessage));
|
|
907
959
|
}
|
|
908
960
|
this.updateTransaction(updatedTransactionMeta, `TransactionController:updateCustodialTransaction - Custodial transaction updated`);
|
|
909
961
|
if ([types_1.TransactionStatus.submitted, types_1.TransactionStatus.failed].includes(status)) {
|
|
@@ -1015,22 +1067,21 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1015
1067
|
}
|
|
1016
1068
|
return filteredTransactions;
|
|
1017
1069
|
}
|
|
1018
|
-
signExternalTransaction(transactionParams) {
|
|
1070
|
+
signExternalTransaction(chainId, transactionParams) {
|
|
1019
1071
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1020
1072
|
if (!this.sign) {
|
|
1021
1073
|
throw new Error('No sign method defined.');
|
|
1022
1074
|
}
|
|
1023
|
-
const normalizedTransactionParams = (0,
|
|
1024
|
-
const
|
|
1025
|
-
const type = (0, utils_1.isEIP1559Transaction)(normalizedTransactionParams)
|
|
1075
|
+
const normalizedTransactionParams = (0, utils_2.normalizeTxParams)(transactionParams);
|
|
1076
|
+
const type = (0, utils_2.isEIP1559Transaction)(normalizedTransactionParams)
|
|
1026
1077
|
? types_1.TransactionEnvelopeType.feeMarket
|
|
1027
1078
|
: types_1.TransactionEnvelopeType.legacy;
|
|
1028
1079
|
const updatedTransactionParams = Object.assign(Object.assign({}, normalizedTransactionParams), { type, gasLimit: normalizedTransactionParams.gas, chainId });
|
|
1029
1080
|
const { from } = updatedTransactionParams;
|
|
1030
|
-
const common = this.getCommonConfiguration();
|
|
1081
|
+
const common = this.getCommonConfiguration(chainId);
|
|
1031
1082
|
const unsignedTransaction = tx_1.TransactionFactory.fromTxData(updatedTransactionParams, { common });
|
|
1032
1083
|
const signedTransaction = yield this.sign(unsignedTransaction, from);
|
|
1033
|
-
const rawTransaction = (0,
|
|
1084
|
+
const rawTransaction = (0, util_1.bufferToHex)(signedTransaction.serialize());
|
|
1034
1085
|
return rawTransaction;
|
|
1035
1086
|
});
|
|
1036
1087
|
}
|
|
@@ -1065,35 +1116,42 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1065
1116
|
}
|
|
1066
1117
|
updateGasProperties(transactionMeta) {
|
|
1067
1118
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1068
|
-
const isEIP1559Compatible = (yield this.getEIP1559Compatibility()) &&
|
|
1119
|
+
const isEIP1559Compatible = (yield this.getEIP1559Compatibility(transactionMeta.networkClientId)) &&
|
|
1069
1120
|
transactionMeta.txParams.type !== types_1.TransactionEnvelopeType.legacy;
|
|
1070
|
-
const chainId =
|
|
1121
|
+
const { networkClientId, chainId } = transactionMeta;
|
|
1122
|
+
const isCustomNetwork = networkClientId
|
|
1123
|
+
? this.messagingSystem.call(`NetworkController:getNetworkClientById`, networkClientId).configuration.type === network_controller_1.NetworkClientType.Custom
|
|
1124
|
+
: this.getNetworkState().providerConfig.type === controller_utils_1.NetworkType.rpc;
|
|
1071
1125
|
yield (0, gas_1.updateGas)({
|
|
1072
|
-
ethQuery: this.
|
|
1073
|
-
|
|
1126
|
+
ethQuery: __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
1127
|
+
networkClientId,
|
|
1128
|
+
chainId,
|
|
1129
|
+
}),
|
|
1130
|
+
chainId,
|
|
1131
|
+
isCustomNetwork,
|
|
1074
1132
|
txMeta: transactionMeta,
|
|
1075
1133
|
});
|
|
1076
1134
|
yield (0, gas_fees_1.updateGasFees)({
|
|
1077
1135
|
eip1559: isEIP1559Compatible,
|
|
1078
|
-
ethQuery: this.
|
|
1079
|
-
|
|
1080
|
-
|
|
1136
|
+
ethQuery: __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
1137
|
+
networkClientId,
|
|
1138
|
+
chainId,
|
|
1139
|
+
}),
|
|
1140
|
+
gasFeeFlows: this.gasFeeFlows,
|
|
1141
|
+
getGasFeeEstimates: this.getGasFeeEstimates,
|
|
1142
|
+
getSavedGasFees: this.getSavedGasFees.bind(this),
|
|
1081
1143
|
txMeta: transactionMeta,
|
|
1082
1144
|
});
|
|
1083
1145
|
});
|
|
1084
1146
|
}
|
|
1085
|
-
getCurrentChainTransactionsByStatus(status) {
|
|
1086
|
-
const chainId = this.getChainId();
|
|
1087
|
-
return this.state.transactions.filter((transaction) => transaction.status === status && transaction.chainId === chainId);
|
|
1088
|
-
}
|
|
1089
1147
|
onBootCleanup() {
|
|
1090
1148
|
this.submitApprovedTransactions();
|
|
1091
1149
|
}
|
|
1092
1150
|
/**
|
|
1093
|
-
* Force
|
|
1151
|
+
* Force submit approved transactions for all chains.
|
|
1094
1152
|
*/
|
|
1095
1153
|
submitApprovedTransactions() {
|
|
1096
|
-
const approvedTransactions = this.
|
|
1154
|
+
const approvedTransactions = this.state.transactions.filter((transaction) => transaction.status === types_1.TransactionStatus.approved);
|
|
1097
1155
|
for (const transactionMeta of approvedTransactions) {
|
|
1098
1156
|
if (this.beforeApproveOnInit(transactionMeta)) {
|
|
1099
1157
|
this.approveTransaction(transactionMeta.id).catch((error) => {
|
|
@@ -1187,10 +1245,9 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1187
1245
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1188
1246
|
const { transactions } = this.state;
|
|
1189
1247
|
const releaseLock = yield this.mutex.acquire();
|
|
1190
|
-
const chainId = this.getChainId();
|
|
1191
1248
|
const index = transactions.findIndex(({ id }) => transactionId === id);
|
|
1192
1249
|
const transactionMeta = transactions[index];
|
|
1193
|
-
const { txParams: { from }, } = transactionMeta;
|
|
1250
|
+
const { txParams: { from }, networkClientId, } = transactionMeta;
|
|
1194
1251
|
let releaseNonceLock;
|
|
1195
1252
|
try {
|
|
1196
1253
|
if (!this.sign) {
|
|
@@ -1198,7 +1255,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1198
1255
|
this.failTransaction(transactionMeta, new Error('No sign method defined.'));
|
|
1199
1256
|
return;
|
|
1200
1257
|
}
|
|
1201
|
-
else if (!chainId) {
|
|
1258
|
+
else if (!transactionMeta.chainId) {
|
|
1202
1259
|
releaseLock();
|
|
1203
1260
|
this.failTransaction(transactionMeta, new Error('No chainId defined.'));
|
|
1204
1261
|
return;
|
|
@@ -1207,15 +1264,15 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1207
1264
|
(0, logger_1.projectLogger)('Skipping approval as signing in progress', transactionId);
|
|
1208
1265
|
return;
|
|
1209
1266
|
}
|
|
1210
|
-
const [nonce, releaseNonce] = yield (0, nonce_1.getNextNonce)(transactionMeta, this.
|
|
1267
|
+
const [nonce, releaseNonce] = yield (0, nonce_1.getNextNonce)(transactionMeta, (address) => __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getNonceLock(address, networkClientId));
|
|
1211
1268
|
releaseNonceLock = releaseNonce;
|
|
1212
1269
|
transactionMeta.status = types_1.TransactionStatus.approved;
|
|
1213
1270
|
transactionMeta.txParams.nonce = nonce;
|
|
1214
|
-
transactionMeta.txParams.chainId = chainId;
|
|
1271
|
+
transactionMeta.txParams.chainId = transactionMeta.chainId;
|
|
1215
1272
|
const baseTxParams = Object.assign(Object.assign({}, transactionMeta.txParams), { gasLimit: transactionMeta.txParams.gas });
|
|
1216
1273
|
this.updateTransaction(transactionMeta, 'TransactionController#approveTransaction - Transaction approved');
|
|
1217
1274
|
this.onTransactionStatusChange(transactionMeta);
|
|
1218
|
-
const isEIP1559 = (0,
|
|
1275
|
+
const isEIP1559 = (0, utils_2.isEIP1559Transaction)(transactionMeta.txParams);
|
|
1219
1276
|
const txParams = isEIP1559
|
|
1220
1277
|
? Object.assign(Object.assign({}, baseTxParams), { estimatedBaseFee: transactionMeta.txParams.estimatedBaseFee, type: types_1.TransactionEnvelopeType.feeMarket }) : baseTxParams;
|
|
1221
1278
|
const rawTx = yield this.signTransaction(transactionMeta, txParams);
|
|
@@ -1227,16 +1284,20 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1227
1284
|
if (!rawTx) {
|
|
1228
1285
|
return;
|
|
1229
1286
|
}
|
|
1287
|
+
const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
1288
|
+
networkClientId: transactionMeta.networkClientId,
|
|
1289
|
+
chainId: transactionMeta.chainId,
|
|
1290
|
+
});
|
|
1230
1291
|
if (transactionMeta.type === types_1.TransactionType.swap) {
|
|
1231
1292
|
(0, logger_1.projectLogger)('Determining pre-transaction balance');
|
|
1232
|
-
const preTxBalance = yield (0, controller_utils_1.query)(
|
|
1293
|
+
const preTxBalance = yield (0, controller_utils_1.query)(ethQuery, 'getBalance', [from]);
|
|
1233
1294
|
transactionMeta.preTxBalance = preTxBalance;
|
|
1234
1295
|
(0, logger_1.projectLogger)('Updated pre-transaction balance', transactionMeta.preTxBalance);
|
|
1235
1296
|
}
|
|
1236
1297
|
(0, logger_1.projectLogger)('Publishing transaction', txParams);
|
|
1237
1298
|
let { transactionHash: hash } = yield this.publish(transactionMeta, rawTx);
|
|
1238
1299
|
if (hash === undefined) {
|
|
1239
|
-
hash = yield this.publishTransaction(rawTx);
|
|
1300
|
+
hash = yield this.publishTransaction(ethQuery, rawTx);
|
|
1240
1301
|
}
|
|
1241
1302
|
(0, logger_1.projectLogger)('Publish successful', hash);
|
|
1242
1303
|
transactionMeta.hash = hash;
|
|
@@ -1262,9 +1323,9 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1262
1323
|
}
|
|
1263
1324
|
});
|
|
1264
1325
|
}
|
|
1265
|
-
publishTransaction(rawTransaction) {
|
|
1326
|
+
publishTransaction(ethQuery, rawTransaction) {
|
|
1266
1327
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1267
|
-
return yield (0, controller_utils_1.query)(
|
|
1328
|
+
return yield (0, controller_utils_1.query)(ethQuery, 'sendRawTransaction', [rawTransaction]);
|
|
1268
1329
|
});
|
|
1269
1330
|
}
|
|
1270
1331
|
/**
|
|
@@ -1380,14 +1441,17 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1380
1441
|
const isCompleted = this.isLocalFinalState(transaction.status);
|
|
1381
1442
|
return { meta: transaction, isCompleted };
|
|
1382
1443
|
}
|
|
1383
|
-
getChainId() {
|
|
1444
|
+
getChainId(networkClientId) {
|
|
1445
|
+
if (networkClientId) {
|
|
1446
|
+
return this.messagingSystem.call(`NetworkController:getNetworkClientById`, networkClientId).configuration.chainId;
|
|
1447
|
+
}
|
|
1384
1448
|
const { providerConfig } = this.getNetworkState();
|
|
1385
1449
|
return providerConfig.chainId;
|
|
1386
1450
|
}
|
|
1387
|
-
prepareUnsignedEthTx(txParams) {
|
|
1451
|
+
prepareUnsignedEthTx(chainId, txParams) {
|
|
1388
1452
|
return tx_1.TransactionFactory.fromTxData(txParams, {
|
|
1389
|
-
common: this.getCommonConfiguration(),
|
|
1390
1453
|
freeze: false,
|
|
1454
|
+
common: this.getCommonConfiguration(chainId),
|
|
1391
1455
|
});
|
|
1392
1456
|
}
|
|
1393
1457
|
/**
|
|
@@ -1397,17 +1461,11 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1397
1461
|
* specified in txParams, @ethereumjs/tx is able to determine which EIP-2718
|
|
1398
1462
|
* transaction type to use.
|
|
1399
1463
|
*
|
|
1464
|
+
* @param chainId - The chainId to use for the configuration.
|
|
1400
1465
|
* @returns common configuration object
|
|
1401
1466
|
*/
|
|
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
|
-
}
|
|
1467
|
+
getCommonConfiguration(chainId) {
|
|
1409
1468
|
const customChainParams = {
|
|
1410
|
-
name,
|
|
1411
1469
|
chainId: parseInt(chainId, 16),
|
|
1412
1470
|
defaultHardfork: exports.HARDFORK,
|
|
1413
1471
|
};
|
|
@@ -1462,7 +1520,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1462
1520
|
*/
|
|
1463
1521
|
addExternalTransaction(transactionMeta) {
|
|
1464
1522
|
var _a, _b;
|
|
1465
|
-
const chainId =
|
|
1523
|
+
const { chainId } = transactionMeta;
|
|
1466
1524
|
const { transactions } = this.state;
|
|
1467
1525
|
const fromAddress = (_a = transactionMeta === null || transactionMeta === void 0 ? void 0 : transactionMeta.txParams) === null || _a === void 0 ? void 0 : _a.from;
|
|
1468
1526
|
const sameFromAndNetworkTransactions = transactions.filter((transaction) => transaction.txParams.from === fromAddress &&
|
|
@@ -1489,10 +1547,13 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1489
1547
|
*/
|
|
1490
1548
|
markNonceDuplicatesDropped(transactionId) {
|
|
1491
1549
|
var _a, _b;
|
|
1492
|
-
const chainId = this.getChainId();
|
|
1493
1550
|
const transactionMeta = this.getTransaction(transactionId);
|
|
1494
|
-
|
|
1495
|
-
|
|
1551
|
+
if (!transactionMeta) {
|
|
1552
|
+
return;
|
|
1553
|
+
}
|
|
1554
|
+
const nonce = (_a = transactionMeta.txParams) === null || _a === void 0 ? void 0 : _a.nonce;
|
|
1555
|
+
const from = (_b = transactionMeta.txParams) === null || _b === void 0 ? void 0 : _b.from;
|
|
1556
|
+
const { chainId } = transactionMeta;
|
|
1496
1557
|
const sameNonceTxs = this.state.transactions.filter((transaction) => transaction.id !== transactionId &&
|
|
1497
1558
|
transaction.txParams.from === from &&
|
|
1498
1559
|
transaction.txParams.nonce === nonce &&
|
|
@@ -1503,8 +1564,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1503
1564
|
}
|
|
1504
1565
|
// Mark all same nonce transactions as dropped and give it a replacedBy hash
|
|
1505
1566
|
for (const transaction of sameNonceTxs) {
|
|
1506
|
-
transaction.replacedBy = transactionMeta
|
|
1507
|
-
transaction.replacedById = transactionMeta
|
|
1567
|
+
transaction.replacedBy = transactionMeta.hash;
|
|
1568
|
+
transaction.replacedById = transactionMeta.id;
|
|
1508
1569
|
// Drop any transaction that wasn't previously failed (off chain failure)
|
|
1509
1570
|
if (transaction.status !== types_1.TransactionStatus.failed) {
|
|
1510
1571
|
this.setTransactionStatusDropped(transaction);
|
|
@@ -1556,27 +1617,21 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1556
1617
|
if (value === undefined || value === null) {
|
|
1557
1618
|
continue;
|
|
1558
1619
|
}
|
|
1559
|
-
transactionMeta[key] = (0,
|
|
1620
|
+
transactionMeta[key] = (0, utils_1.add0x)(value.toString(16));
|
|
1560
1621
|
}
|
|
1561
1622
|
});
|
|
1562
1623
|
}
|
|
1563
|
-
getEIP1559Compatibility() {
|
|
1624
|
+
getEIP1559Compatibility(networkClientId) {
|
|
1564
1625
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1565
|
-
const currentNetworkIsEIP1559Compatible = yield this.getCurrentNetworkEIP1559Compatibility();
|
|
1626
|
+
const currentNetworkIsEIP1559Compatible = yield this.getCurrentNetworkEIP1559Compatibility(networkClientId);
|
|
1566
1627
|
const currentAccountIsEIP1559Compatible = yield this.getCurrentAccountEIP1559Compatibility();
|
|
1567
1628
|
return (currentNetworkIsEIP1559Compatible && currentAccountIsEIP1559Compatible);
|
|
1568
1629
|
});
|
|
1569
1630
|
}
|
|
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
1631
|
signTransaction(transactionMeta, txParams) {
|
|
1577
1632
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1578
1633
|
(0, logger_1.projectLogger)('Signing transaction', txParams);
|
|
1579
|
-
const unsignedEthTx = this.prepareUnsignedEthTx(txParams);
|
|
1634
|
+
const unsignedEthTx = this.prepareUnsignedEthTx(transactionMeta.chainId, txParams);
|
|
1580
1635
|
this.inProcessOfSigning.add(transactionMeta.id);
|
|
1581
1636
|
const signedTx = yield new Promise((resolve, reject) => {
|
|
1582
1637
|
var _a;
|
|
@@ -1597,7 +1652,7 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1597
1652
|
transactionMeta.status = types_1.TransactionStatus.signed;
|
|
1598
1653
|
this.updateTransaction(transactionMeta, 'TransactionController#approveTransaction - Transaction signed');
|
|
1599
1654
|
this.onTransactionStatusChange(transactionMeta);
|
|
1600
|
-
const rawTx = (0,
|
|
1655
|
+
const rawTx = (0, util_1.bufferToHex)(signedTx.serialize());
|
|
1601
1656
|
transactionMeta.rawTx = rawTx;
|
|
1602
1657
|
this.updateTransaction(transactionMeta, 'TransactionController#approveTransaction - RawTransaction added');
|
|
1603
1658
|
return rawTx;
|
|
@@ -1606,14 +1661,8 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1606
1661
|
onTransactionStatusChange(transactionMeta) {
|
|
1607
1662
|
this.hub.emit('transaction-status-update', { transactionMeta });
|
|
1608
1663
|
}
|
|
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);
|
|
1664
|
+
getNonceTrackerTransactions(status, address, chainId = this.getChainId()) {
|
|
1665
|
+
return (0, nonce_1.getAndFormatTransactionsForNonceTracker)(chainId, address, status, this.state.transactions);
|
|
1617
1666
|
}
|
|
1618
1667
|
onConfirmedTransaction(transactionMeta) {
|
|
1619
1668
|
(0, logger_1.projectLogger)('Processing confirmed transaction', transactionMeta.id);
|
|
@@ -1631,8 +1680,12 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1631
1680
|
if (transactionMeta.type !== types_1.TransactionType.swap) {
|
|
1632
1681
|
return;
|
|
1633
1682
|
}
|
|
1683
|
+
const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
|
|
1684
|
+
networkClientId: transactionMeta.networkClientId,
|
|
1685
|
+
chainId: transactionMeta.chainId,
|
|
1686
|
+
});
|
|
1634
1687
|
const { updatedTransactionMeta, approvalTransactionMeta } = yield (0, swaps_1.updatePostTransactionBalance)(transactionMeta, {
|
|
1635
|
-
ethQuery
|
|
1688
|
+
ethQuery,
|
|
1636
1689
|
getTransaction: this.getTransaction.bind(this),
|
|
1637
1690
|
updateTransaction: this.updateTransaction.bind(this),
|
|
1638
1691
|
});
|
|
@@ -1647,10 +1700,10 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1647
1700
|
}
|
|
1648
1701
|
});
|
|
1649
1702
|
}
|
|
1650
|
-
publishTransactionForRetry(rawTx, transactionMeta) {
|
|
1703
|
+
publishTransactionForRetry(ethQuery, rawTx, transactionMeta) {
|
|
1651
1704
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1652
1705
|
try {
|
|
1653
|
-
const hash = yield this.publishTransaction(rawTx);
|
|
1706
|
+
const hash = yield this.publishTransaction(ethQuery, rawTx);
|
|
1654
1707
|
return hash;
|
|
1655
1708
|
}
|
|
1656
1709
|
catch (error) {
|
|
@@ -1678,4 +1731,87 @@ class TransactionController extends base_controller_1.BaseControllerV1 {
|
|
|
1678
1731
|
}
|
|
1679
1732
|
}
|
|
1680
1733
|
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, }) {
|
|
1735
|
+
return new nonce_tracker_1.NonceTracker({
|
|
1736
|
+
// TODO: Replace `any` with type
|
|
1737
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1738
|
+
provider: provider,
|
|
1739
|
+
blockTracker,
|
|
1740
|
+
getPendingTransactions: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getNonceTrackerPendingTransactions).bind(this, chainId),
|
|
1741
|
+
getConfirmedTransactions: this.getNonceTrackerTransactions.bind(this, types_1.TransactionStatus.confirmed),
|
|
1742
|
+
});
|
|
1743
|
+
}, _TransactionController_createIncomingTransactionHelper = function _TransactionController_createIncomingTransactionHelper({ blockTracker, etherscanRemoteTransactionSource, chainId, }) {
|
|
1744
|
+
const incomingTransactionHelper = new IncomingTransactionHelper_1.IncomingTransactionHelper({
|
|
1745
|
+
blockTracker,
|
|
1746
|
+
getCurrentAccount: this.getSelectedAddress,
|
|
1747
|
+
getLastFetchedBlockNumbers: () => this.state.lastFetchedBlockNumbers,
|
|
1748
|
+
getChainId: chainId ? () => chainId : this.getChainId.bind(this),
|
|
1749
|
+
isEnabled: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").isEnabled,
|
|
1750
|
+
queryEntireHistory: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").queryEntireHistory,
|
|
1751
|
+
remoteTransactionSource: etherscanRemoteTransactionSource,
|
|
1752
|
+
transactionLimit: this.config.txHistoryLimit,
|
|
1753
|
+
updateTransactions: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").updateTransactions,
|
|
1754
|
+
});
|
|
1755
|
+
__classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_addIncomingTransactionHelperListeners).call(this, incomingTransactionHelper);
|
|
1756
|
+
return incomingTransactionHelper;
|
|
1757
|
+
}, _TransactionController_createPendingTransactionTracker = function _TransactionController_createPendingTransactionTracker({ provider, blockTracker, chainId, }) {
|
|
1758
|
+
const ethQuery = new eth_query_1.default(provider);
|
|
1759
|
+
const getChainId = chainId ? () => chainId : this.getChainId.bind(this);
|
|
1760
|
+
const pendingTransactionTracker = new PendingTransactionTracker_1.PendingTransactionTracker({
|
|
1761
|
+
approveTransaction: this.approveTransaction.bind(this),
|
|
1762
|
+
blockTracker,
|
|
1763
|
+
getChainId,
|
|
1764
|
+
getEthQuery: () => ethQuery,
|
|
1765
|
+
getTransactions: () => this.state.transactions,
|
|
1766
|
+
isResubmitEnabled: __classPrivateFieldGet(this, _TransactionController_pendingTransactionOptions, "f").isResubmitEnabled,
|
|
1767
|
+
getGlobalLock: () => __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").acquireNonceLockForChainIdKey({
|
|
1768
|
+
chainId: getChainId(),
|
|
1769
|
+
}),
|
|
1770
|
+
publishTransaction: this.publishTransaction.bind(this),
|
|
1771
|
+
hooks: {
|
|
1772
|
+
beforeCheckPendingTransaction: this.beforeCheckPendingTransaction.bind(this),
|
|
1773
|
+
beforePublish: this.beforePublish.bind(this),
|
|
1774
|
+
},
|
|
1775
|
+
});
|
|
1776
|
+
__classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_addPendingTransactionTrackerListeners).call(this, pendingTransactionTracker);
|
|
1777
|
+
return pendingTransactionTracker;
|
|
1778
|
+
}, _TransactionController_stopAllTracking = function _TransactionController_stopAllTracking() {
|
|
1779
|
+
this.pendingTransactionTracker.stop();
|
|
1780
|
+
__classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removePendingTransactionTrackerListeners).call(this, this.pendingTransactionTracker);
|
|
1781
|
+
this.incomingTransactionHelper.stop();
|
|
1782
|
+
__classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removeIncomingTransactionHelperListeners).call(this, this.incomingTransactionHelper);
|
|
1783
|
+
__classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopAllTracking();
|
|
1784
|
+
}, _TransactionController_removeIncomingTransactionHelperListeners = function _TransactionController_removeIncomingTransactionHelperListeners(incomingTransactionHelper) {
|
|
1785
|
+
incomingTransactionHelper.hub.removeAllListeners('transactions');
|
|
1786
|
+
incomingTransactionHelper.hub.removeAllListeners('updatedLastFetchedBlockNumbers');
|
|
1787
|
+
}, _TransactionController_addIncomingTransactionHelperListeners = function _TransactionController_addIncomingTransactionHelperListeners(incomingTransactionHelper) {
|
|
1788
|
+
incomingTransactionHelper.hub.on('transactions', this.onIncomingTransactions.bind(this));
|
|
1789
|
+
incomingTransactionHelper.hub.on('updatedLastFetchedBlockNumbers', this.onUpdatedLastFetchedBlockNumbers.bind(this));
|
|
1790
|
+
}, _TransactionController_removePendingTransactionTrackerListeners = function _TransactionController_removePendingTransactionTrackerListeners(pendingTransactionTracker) {
|
|
1791
|
+
pendingTransactionTracker.hub.removeAllListeners('transaction-confirmed');
|
|
1792
|
+
pendingTransactionTracker.hub.removeAllListeners('transaction-dropped');
|
|
1793
|
+
pendingTransactionTracker.hub.removeAllListeners('transaction-failed');
|
|
1794
|
+
pendingTransactionTracker.hub.removeAllListeners('transaction-updated');
|
|
1795
|
+
}, _TransactionController_addPendingTransactionTrackerListeners = function _TransactionController_addPendingTransactionTrackerListeners(pendingTransactionTracker) {
|
|
1796
|
+
pendingTransactionTracker.hub.on('transaction-confirmed', this.onConfirmedTransaction.bind(this));
|
|
1797
|
+
pendingTransactionTracker.hub.on('transaction-dropped', this.setTransactionStatusDropped.bind(this));
|
|
1798
|
+
pendingTransactionTracker.hub.on('transaction-failed', this.failTransaction.bind(this));
|
|
1799
|
+
pendingTransactionTracker.hub.on('transaction-updated', this.updateTransaction.bind(this));
|
|
1800
|
+
}, _TransactionController_getNonceTrackerPendingTransactions = function _TransactionController_getNonceTrackerPendingTransactions(chainId, address) {
|
|
1801
|
+
const standardPendingTransactions = this.getNonceTrackerTransactions(types_1.TransactionStatus.submitted, address, chainId);
|
|
1802
|
+
const externalPendingTransactions = this.getExternalPendingTransactions(address, chainId);
|
|
1803
|
+
return [...standardPendingTransactions, ...externalPendingTransactions];
|
|
1804
|
+
}, _TransactionController_getGasFeeFlows = function _TransactionController_getGasFeeFlows() {
|
|
1805
|
+
return [new LineaGasFeeFlow_1.LineaGasFeeFlow(), new DefaultGasFeeFlow_1.DefaultGasFeeFlow()];
|
|
1806
|
+
}, _TransactionController_updateTransactionInternal = function _TransactionController_updateTransactionInternal(transactionMeta, { note, skipHistory }) {
|
|
1807
|
+
const { transactions } = this.state;
|
|
1808
|
+
transactionMeta.txParams = (0, utils_2.normalizeTxParams)(transactionMeta.txParams);
|
|
1809
|
+
(0, validation_1.validateTxParams)(transactionMeta.txParams);
|
|
1810
|
+
if (skipHistory !== true) {
|
|
1811
|
+
(0, history_1.updateTransactionHistory)(transactionMeta, note !== null && note !== void 0 ? note : 'Transaction updated');
|
|
1812
|
+
}
|
|
1813
|
+
const index = transactions.findIndex(({ id }) => transactionMeta.id === id);
|
|
1814
|
+
transactions[index] = transactionMeta;
|
|
1815
|
+
this.update({ transactions: this.trimTransactionsForState(transactions) });
|
|
1816
|
+
};
|
|
1681
1817
|
//# sourceMappingURL=TransactionController.js.map
|