@metamask/transaction-controller 40.0.0 → 41.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.
Files changed (88) hide show
  1. package/CHANGELOG.md +33 -1
  2. package/dist/TransactionController.cjs +169 -230
  3. package/dist/TransactionController.cjs.map +1 -1
  4. package/dist/TransactionController.d.cts +98 -52
  5. package/dist/TransactionController.d.cts.map +1 -1
  6. package/dist/TransactionController.d.mts +98 -52
  7. package/dist/TransactionController.d.mts.map +1 -1
  8. package/dist/TransactionController.mjs +172 -233
  9. package/dist/TransactionController.mjs.map +1 -1
  10. package/dist/api/accounts-api.cjs +47 -0
  11. package/dist/api/accounts-api.cjs.map +1 -0
  12. package/dist/api/accounts-api.d.cts +43 -0
  13. package/dist/api/accounts-api.d.cts.map +1 -0
  14. package/dist/api/accounts-api.d.mts +43 -0
  15. package/dist/api/accounts-api.d.mts.map +1 -0
  16. package/dist/api/accounts-api.mjs +43 -0
  17. package/dist/api/accounts-api.mjs.map +1 -0
  18. package/dist/errors.cjs +8 -1
  19. package/dist/errors.cjs.map +1 -1
  20. package/dist/errors.d.cts +4 -0
  21. package/dist/errors.d.cts.map +1 -1
  22. package/dist/errors.d.mts +4 -0
  23. package/dist/errors.d.mts.map +1 -1
  24. package/dist/errors.mjs +6 -0
  25. package/dist/errors.mjs.map +1 -1
  26. package/dist/helpers/EtherscanRemoteTransactionSource.cjs +13 -12
  27. package/dist/helpers/EtherscanRemoteTransactionSource.cjs.map +1 -1
  28. package/dist/helpers/EtherscanRemoteTransactionSource.d.cts.map +1 -1
  29. package/dist/helpers/EtherscanRemoteTransactionSource.d.mts.map +1 -1
  30. package/dist/helpers/EtherscanRemoteTransactionSource.mjs +13 -12
  31. package/dist/helpers/EtherscanRemoteTransactionSource.mjs.map +1 -1
  32. package/dist/helpers/GasFeePoller.cjs +4 -4
  33. package/dist/helpers/GasFeePoller.cjs.map +1 -1
  34. package/dist/helpers/GasFeePoller.d.cts +1 -1
  35. package/dist/helpers/GasFeePoller.d.cts.map +1 -1
  36. package/dist/helpers/GasFeePoller.d.mts +1 -1
  37. package/dist/helpers/GasFeePoller.d.mts.map +1 -1
  38. package/dist/helpers/GasFeePoller.mjs +4 -4
  39. package/dist/helpers/GasFeePoller.mjs.map +1 -1
  40. package/dist/helpers/IncomingTransactionHelper.cjs +18 -11
  41. package/dist/helpers/IncomingTransactionHelper.cjs.map +1 -1
  42. package/dist/helpers/IncomingTransactionHelper.d.cts.map +1 -1
  43. package/dist/helpers/IncomingTransactionHelper.d.mts.map +1 -1
  44. package/dist/helpers/IncomingTransactionHelper.mjs +19 -12
  45. package/dist/helpers/IncomingTransactionHelper.mjs.map +1 -1
  46. package/dist/helpers/MethodDataHelper.cjs +78 -0
  47. package/dist/helpers/MethodDataHelper.cjs.map +1 -0
  48. package/dist/helpers/MethodDataHelper.d.cts +14 -0
  49. package/dist/helpers/MethodDataHelper.d.cts.map +1 -0
  50. package/dist/helpers/MethodDataHelper.d.mts +14 -0
  51. package/dist/helpers/MethodDataHelper.d.mts.map +1 -0
  52. package/dist/helpers/MethodDataHelper.mjs +71 -0
  53. package/dist/helpers/MethodDataHelper.mjs.map +1 -0
  54. package/dist/helpers/MultichainTrackingHelper.cjs +87 -104
  55. package/dist/helpers/MultichainTrackingHelper.cjs.map +1 -1
  56. package/dist/helpers/MultichainTrackingHelper.d.cts +16 -22
  57. package/dist/helpers/MultichainTrackingHelper.d.cts.map +1 -1
  58. package/dist/helpers/MultichainTrackingHelper.d.mts +16 -22
  59. package/dist/helpers/MultichainTrackingHelper.d.mts.map +1 -1
  60. package/dist/helpers/MultichainTrackingHelper.mjs +88 -109
  61. package/dist/helpers/MultichainTrackingHelper.mjs.map +1 -1
  62. package/dist/helpers/PendingTransactionTracker.cjs +24 -22
  63. package/dist/helpers/PendingTransactionTracker.cjs.map +1 -1
  64. package/dist/helpers/PendingTransactionTracker.d.cts.map +1 -1
  65. package/dist/helpers/PendingTransactionTracker.d.mts.map +1 -1
  66. package/dist/helpers/PendingTransactionTracker.mjs +24 -22
  67. package/dist/helpers/PendingTransactionTracker.mjs.map +1 -1
  68. package/dist/types.cjs.map +1 -1
  69. package/dist/types.d.cts +7 -3
  70. package/dist/types.d.cts.map +1 -1
  71. package/dist/types.d.mts +7 -3
  72. package/dist/types.d.mts.map +1 -1
  73. package/dist/types.mjs.map +1 -1
  74. package/dist/utils/etherscan.cjs +2 -1
  75. package/dist/utils/etherscan.cjs.map +1 -1
  76. package/dist/utils/etherscan.d.cts.map +1 -1
  77. package/dist/utils/etherscan.d.mts.map +1 -1
  78. package/dist/utils/etherscan.mjs +3 -2
  79. package/dist/utils/etherscan.mjs.map +1 -1
  80. package/dist/utils/validation.cjs +13 -1
  81. package/dist/utils/validation.cjs.map +1 -1
  82. package/dist/utils/validation.d.cts +7 -0
  83. package/dist/utils/validation.d.cts.map +1 -1
  84. package/dist/utils/validation.d.mts +7 -0
  85. package/dist/utils/validation.d.mts.map +1 -1
  86. package/dist/utils/validation.mjs +11 -0
  87. package/dist/utils/validation.mjs.map +1 -1
  88. package/package.json +1 -1
@@ -13,7 +13,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
13
13
  var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
15
  };
16
- var _TransactionController_instances, _TransactionController_internalEvents, _TransactionController_incomingTransactionOptions, _TransactionController_pendingTransactionOptions, _TransactionController_trace, _TransactionController_transactionHistoryLimit, _TransactionController_isSimulationEnabled, _TransactionController_testGasFeeFlows, _TransactionController_multichainTrackingHelper, _TransactionController_retryTransaction, _TransactionController_createNonceTracker, _TransactionController_createIncomingTransactionHelper, _TransactionController_createPendingTransactionTracker, _TransactionController_checkForPendingTransactionAndStartPolling, _TransactionController_stopAllTracking, _TransactionController_removeIncomingTransactionHelperListeners, _TransactionController_addIncomingTransactionHelperListeners, _TransactionController_removePendingTransactionTrackerListeners, _TransactionController_addPendingTransactionTrackerListeners, _TransactionController_getNonceTrackerPendingTransactions, _TransactionController_getGasFeeFlows, _TransactionController_getLayer1GasFeeFlows, _TransactionController_updateTransactionInternal, _TransactionController_updateSimulationData, _TransactionController_onGasFeePollerTransactionUpdate, _TransactionController_getNetworkClientId, _TransactionController_getGlobalNetworkClientId, _TransactionController_getGlobalChainId, _TransactionController_isCustomNetwork, _TransactionController_getSelectedAccount, _TransactionController_updateSubmitHistory;
16
+ var _TransactionController_instances, _TransactionController_internalEvents, _TransactionController_methodDataHelper, _TransactionController_incomingTransactionOptions, _TransactionController_pendingTransactionOptions, _TransactionController_trace, _TransactionController_transactionHistoryLimit, _TransactionController_isFirstTimeInteractionEnabled, _TransactionController_isSimulationEnabled, _TransactionController_testGasFeeFlows, _TransactionController_multichainTrackingHelper, _TransactionController_retryTransaction, _TransactionController_getChainId, _TransactionController_getNetworkClientId, _TransactionController_getEthQuery, _TransactionController_getProvider, _TransactionController_createNonceTracker, _TransactionController_createRemoteTransactionSource, _TransactionController_createIncomingTransactionHelper, _TransactionController_createPendingTransactionTracker, _TransactionController_checkForPendingTransactionAndStartPolling, _TransactionController_stopAllTracking, _TransactionController_removeIncomingTransactionHelperListeners, _TransactionController_addIncomingTransactionHelperListeners, _TransactionController_removePendingTransactionTrackerListeners, _TransactionController_addPendingTransactionTrackerListeners, _TransactionController_getNonceTrackerPendingTransactions, _TransactionController_getGasFeeFlows, _TransactionController_getLayer1GasFeeFlows, _TransactionController_updateTransactionInternal, _TransactionController_updateFirstTimeInteraction, _TransactionController_updateSimulationData, _TransactionController_onGasFeePollerTransactionUpdate, _TransactionController_getSelectedAccount, _TransactionController_updateSubmitHistory;
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.TransactionController = exports.ApprovalState = exports.SPEED_UP_RATE = exports.CANCEL_RATE = exports.HARDFORK = void 0;
19
19
  const common_1 = require("@ethereumjs/common");
@@ -27,10 +27,10 @@ const nonce_tracker_1 = require("@metamask/nonce-tracker");
27
27
  const rpc_errors_1 = require("@metamask/rpc-errors");
28
28
  const utils_1 = require("@metamask/utils");
29
29
  const async_mutex_1 = require("async-mutex");
30
- const eth_method_registry_1 = require("eth-method-registry");
31
30
  const events_1 = require("events");
32
31
  const lodash_1 = require("lodash");
33
32
  const uuid_1 = require("uuid");
33
+ const accounts_api_1 = require("./api/accounts-api.cjs");
34
34
  const DefaultGasFeeFlow_1 = require("./gas-flows/DefaultGasFeeFlow.cjs");
35
35
  const LineaGasFeeFlow_1 = require("./gas-flows/LineaGasFeeFlow.cjs");
36
36
  const OptimismLayer1GasFeeFlow_1 = require("./gas-flows/OptimismLayer1GasFeeFlow.cjs");
@@ -39,6 +39,7 @@ const TestGasFeeFlow_1 = require("./gas-flows/TestGasFeeFlow.cjs");
39
39
  const EtherscanRemoteTransactionSource_1 = require("./helpers/EtherscanRemoteTransactionSource.cjs");
40
40
  const GasFeePoller_1 = require("./helpers/GasFeePoller.cjs");
41
41
  const IncomingTransactionHelper_1 = require("./helpers/IncomingTransactionHelper.cjs");
42
+ const MethodDataHelper_1 = require("./helpers/MethodDataHelper.cjs");
42
43
  const MultichainTrackingHelper_1 = require("./helpers/MultichainTrackingHelper.cjs");
43
44
  const PendingTransactionTracker_1 = require("./helpers/PendingTransactionTracker.cjs");
44
45
  const logger_1 = require("./logger.cjs");
@@ -148,22 +149,10 @@ class TransactionController extends base_controller_1.BaseController {
148
149
  this.messagingSystem.publish(`${controllerName}:transactionFinished`, newTransactionMeta);
149
150
  __classPrivateFieldGet(this, _TransactionController_internalEvents, "f").emit(`${transactionMeta.id}:finished`, newTransactionMeta);
150
151
  }
151
- async registryLookup(fourBytePrefix) {
152
- const registryMethod = await this.registry.lookup(fourBytePrefix);
153
- if (!registryMethod) {
154
- return {
155
- registryMethod: '',
156
- parsedRegistryMethod: { name: undefined, args: undefined },
157
- };
158
- }
159
- const parsedRegistryMethod = this.registry.parse(registryMethod);
160
- return { registryMethod, parsedRegistryMethod };
161
- }
162
152
  /**
163
153
  * Constructs a TransactionController.
164
154
  *
165
155
  * @param options - The controller options.
166
- * @param options.blockTracker - The block tracker used to poll for new blocks data.
167
156
  * @param options.disableHistory - Whether to disable storing history in transaction metadata.
168
157
  * @param options.disableSendFlowHistory - Explicitly disable transaction metadata history.
169
158
  * @param options.disableSwaps - Whether to disable additional processing on swaps transactions.
@@ -176,12 +165,10 @@ class TransactionController extends base_controller_1.BaseController {
176
165
  * @param options.getPermittedAccounts - Get accounts that a given origin has permissions for.
177
166
  * @param options.getSavedGasFees - Gets the saved gas fee config.
178
167
  * @param options.incomingTransactions - Configuration options for incoming transaction support.
179
- * @param options.isMultichainEnabled - Enable multichain support.
168
+ * @param options.isFirstTimeInteractionEnabled - Whether first time interaction checks are enabled.
180
169
  * @param options.isSimulationEnabled - Whether new transactions will be automatically simulated.
181
170
  * @param options.messenger - The controller messenger.
182
- * @param options.onNetworkStateChange - Allows subscribing to network controller state changes.
183
171
  * @param options.pendingTransactions - Configuration options for pending transaction support.
184
- * @param options.provider - The provider used to create the underlying EthQuery instance.
185
172
  * @param options.securityProviderRequest - A function for verifying a transaction, whether it is malicious or not.
186
173
  * @param options.sign - Function used to sign transactions.
187
174
  * @param options.state - Initial state to set on this controller.
@@ -190,7 +177,7 @@ class TransactionController extends base_controller_1.BaseController {
190
177
  * @param options.transactionHistoryLimit - Transaction history limit.
191
178
  * @param options.hooks - The controller hooks.
192
179
  */
193
- constructor({ blockTracker, disableHistory, disableSendFlowHistory, disableSwaps, getCurrentAccountEIP1559Compatibility, getCurrentNetworkEIP1559Compatibility, getExternalPendingTransactions, getGasFeeEstimates, getNetworkClientRegistry, getNetworkState, getPermittedAccounts, getSavedGasFees, incomingTransactions = {}, isMultichainEnabled = false, isSimulationEnabled, messenger, onNetworkStateChange, pendingTransactions = {}, provider, securityProviderRequest, sign, state, testGasFeeFlows, trace, transactionHistoryLimit = 40, hooks, }) {
180
+ constructor({ disableHistory, disableSendFlowHistory, disableSwaps, getCurrentAccountEIP1559Compatibility, getCurrentNetworkEIP1559Compatibility, getExternalPendingTransactions, getGasFeeEstimates, getNetworkClientRegistry, getNetworkState, getPermittedAccounts, getSavedGasFees, incomingTransactions = {}, isFirstTimeInteractionEnabled, isSimulationEnabled, messenger, pendingTransactions = {}, securityProviderRequest, sign, state, testGasFeeFlows, trace, transactionHistoryLimit = 40, hooks, }) {
194
181
  super({
195
182
  name: controllerName,
196
183
  metadata,
@@ -203,18 +190,18 @@ class TransactionController extends base_controller_1.BaseController {
203
190
  _TransactionController_instances.add(this);
204
191
  _TransactionController_internalEvents.set(this, new events_1.EventEmitter());
205
192
  this.approvingTransactionIds = new Set();
193
+ _TransactionController_methodDataHelper.set(this, void 0);
206
194
  this.mutex = new async_mutex_1.Mutex();
207
195
  _TransactionController_incomingTransactionOptions.set(this, void 0);
208
196
  _TransactionController_pendingTransactionOptions.set(this, void 0);
209
197
  this.signAbortCallbacks = new Map();
210
198
  _TransactionController_trace.set(this, void 0);
211
199
  _TransactionController_transactionHistoryLimit.set(this, void 0);
200
+ _TransactionController_isFirstTimeInteractionEnabled.set(this, void 0);
212
201
  _TransactionController_isSimulationEnabled.set(this, void 0);
213
202
  _TransactionController_testGasFeeFlows.set(this, void 0);
214
203
  _TransactionController_multichainTrackingHelper.set(this, void 0);
215
204
  _TransactionController_checkForPendingTransactionAndStartPolling.set(this, () => {
216
- // PendingTransactionTracker reads state through its getTransactions hook
217
- this.pendingTransactionTracker.startIfPendingTransactions();
218
205
  __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").checkForPendingTransactionAndStartPolling();
219
206
  });
220
207
  this.messagingSystem = messenger;
@@ -222,9 +209,8 @@ class TransactionController extends base_controller_1.BaseController {
222
209
  this.isSendFlowHistoryDisabled = disableSendFlowHistory ?? false;
223
210
  this.isHistoryDisabled = disableHistory ?? false;
224
211
  this.isSwapsDisabled = disableSwaps ?? false;
212
+ __classPrivateFieldSet(this, _TransactionController_isFirstTimeInteractionEnabled, isFirstTimeInteractionEnabled ?? (() => true), "f");
225
213
  __classPrivateFieldSet(this, _TransactionController_isSimulationEnabled, isSimulationEnabled ?? (() => true), "f");
226
- // @ts-expect-error the type in eth-method-registry is inappropriate and should be changed
227
- this.registry = new eth_method_registry_1.MethodRegistry({ provider });
228
214
  this.getSavedGasFees = getSavedGasFees ?? ((_chainId) => undefined);
229
215
  this.getCurrentAccountEIP1559Compatibility =
230
216
  getCurrentAccountEIP1559Compatibility ?? (() => Promise.resolve(true));
@@ -252,18 +238,10 @@ class TransactionController extends base_controller_1.BaseController {
252
238
  hooks?.getAdditionalSignArguments ?? (() => []);
253
239
  this.publish =
254
240
  hooks?.publish ?? (() => Promise.resolve({ transactionHash: undefined }));
255
- this.nonceTracker = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createNonceTracker).call(this, {
256
- provider,
257
- blockTracker,
258
- });
259
241
  const findNetworkClientIdByChainId = (chainId) => {
260
242
  return this.messagingSystem.call(`NetworkController:findNetworkClientIdByChainId`, chainId);
261
243
  };
262
244
  __classPrivateFieldSet(this, _TransactionController_multichainTrackingHelper, new MultichainTrackingHelper_1.MultichainTrackingHelper({
263
- isMultichainEnabled,
264
- provider,
265
- nonceTracker: this.nonceTracker,
266
- incomingTransactionOptions: incomingTransactions,
267
245
  findNetworkClientIdByChainId,
268
246
  getNetworkClientById: ((networkClientId) => {
269
247
  return this.messagingSystem.call(`NetworkController:getNetworkClientById`, networkClientId);
@@ -274,33 +252,19 @@ class TransactionController extends base_controller_1.BaseController {
274
252
  createNonceTracker: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createNonceTracker).bind(this),
275
253
  createIncomingTransactionHelper: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createIncomingTransactionHelper).bind(this),
276
254
  createPendingTransactionTracker: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createPendingTransactionTracker).bind(this),
255
+ createRemoteTransactionSource: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createRemoteTransactionSource).bind(this),
277
256
  onNetworkStateChange: (listener) => {
278
257
  this.messagingSystem.subscribe('NetworkController:stateChange', listener);
279
258
  },
280
259
  }), "f");
281
260
  __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").initialize();
282
- const etherscanRemoteTransactionSource = new EtherscanRemoteTransactionSource_1.EtherscanRemoteTransactionSource({
283
- apiKeysByChainId: incomingTransactions.etherscanApiKeysByChainId,
284
- includeTokenTransfers: incomingTransactions.includeTokenTransfers,
285
- });
286
- this.incomingTransactionHelper = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createIncomingTransactionHelper).call(this, {
287
- blockTracker,
288
- etherscanRemoteTransactionSource,
289
- });
290
- this.pendingTransactionTracker = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createPendingTransactionTracker).call(this, {
291
- provider,
292
- blockTracker,
293
- });
294
261
  this.gasFeeFlows = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getGasFeeFlows).call(this);
295
262
  this.layer1GasFeeFlows = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getLayer1GasFeeFlows).call(this);
296
263
  const gasFeePoller = new GasFeePoller_1.GasFeePoller({
297
264
  findNetworkClientIdByChainId,
298
265
  gasFeeFlows: this.gasFeeFlows,
299
266
  getGasFeeControllerEstimates: this.getGasFeeEstimates,
300
- getProvider: (chainId, networkClientId) => __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getProvider({
301
- networkClientId,
302
- chainId,
303
- }),
267
+ getProvider: (networkClientId) => __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getProvider).call(this, { networkClientId }),
304
268
  getTransactions: () => this.state.transactions,
305
269
  layer1GasFeeFlows: this.layer1GasFeeFlows,
306
270
  onStateChange: (listener) => {
@@ -308,15 +272,18 @@ class TransactionController extends base_controller_1.BaseController {
308
272
  },
309
273
  });
310
274
  gasFeePoller.hub.on('transaction-updated', __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_onGasFeePollerTransactionUpdate).bind(this));
275
+ __classPrivateFieldSet(this, _TransactionController_methodDataHelper, new MethodDataHelper_1.MethodDataHelper({
276
+ getProvider: (networkClientId) => __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getProvider).call(this, { networkClientId }),
277
+ getState: () => this.state.methodData,
278
+ }), "f");
279
+ __classPrivateFieldGet(this, _TransactionController_methodDataHelper, "f").hub.on('update', ({ fourBytePrefix, methodData }) => {
280
+ this.update((_state) => {
281
+ _state.methodData[fourBytePrefix] = methodData;
282
+ });
283
+ });
311
284
  // when transactionsController state changes
312
285
  // check for pending transactions and start polling if there are any
313
286
  this.messagingSystem.subscribe('TransactionController:stateChange', __classPrivateFieldGet(this, _TransactionController_checkForPendingTransactionAndStartPolling, "f"));
314
- // TODO once v2 is merged make sure this only runs when
315
- // selectedNetworkClientId changes
316
- onNetworkStateChange(() => {
317
- (0, logger_1.projectLogger)('Detected network change', this.getChainId());
318
- this.pendingTransactionTracker.startIfPendingTransactions();
319
- });
320
287
  this.onBootCleanup();
321
288
  __classPrivateFieldGet(this, _TransactionController_checkForPendingTransactionAndStartPolling, "f").call(this);
322
289
  }
@@ -330,25 +297,11 @@ class TransactionController extends base_controller_1.BaseController {
330
297
  * Handle new method data request.
331
298
  *
332
299
  * @param fourBytePrefix - The method prefix.
300
+ * @param networkClientId - The ID of the network client used to fetch the method data.
333
301
  * @returns The method data object corresponding to the given signature prefix.
334
302
  */
335
- async handleMethodData(fourBytePrefix) {
336
- const releaseLock = await this.mutex.acquire();
337
- try {
338
- const { methodData } = this.state;
339
- const knownMethod = Object.keys(methodData).find((knownFourBytePrefix) => fourBytePrefix === knownFourBytePrefix);
340
- if (knownMethod) {
341
- return methodData[fourBytePrefix];
342
- }
343
- const registry = await this.registryLookup(fourBytePrefix);
344
- this.update((state) => {
345
- state.methodData[fourBytePrefix] = registry;
346
- });
347
- return registry;
348
- }
349
- finally {
350
- releaseLock();
351
- }
303
+ async handleMethodData(fourBytePrefix, networkClientId) {
304
+ return __classPrivateFieldGet(this, _TransactionController_methodDataHelper, "f").lookup(fourBytePrefix, networkClientId);
352
305
  }
353
306
  /**
354
307
  * Add a new unapproved transaction to state. Parameters will be validated, a
@@ -356,40 +309,38 @@ class TransactionController extends base_controller_1.BaseController {
356
309
  * if not provided. If A `<tx.id>:unapproved` hub event will be emitted once added.
357
310
  *
358
311
  * @param txParams - Standard parameters for an Ethereum transaction.
359
- * @param opts - Additional options to control how the transaction is added.
360
- * @param opts.actionId - Unique ID to prevent duplicate requests.
361
- * @param opts.deviceConfirmedOn - An enum to indicate what device confirmed the transaction.
362
- * @param opts.method - RPC method that requested the transaction.
363
- * @param opts.origin - The origin of the transaction request, such as a dApp hostname.
364
- * @param opts.requireApproval - Whether the transaction requires approval by the user, defaults to true unless explicitly disabled.
365
- * @param opts.securityAlertResponse - Response from security validator.
366
- * @param opts.sendFlowHistory - The sendFlowHistory entries to add.
367
- * @param opts.type - Type of transaction to add, such as 'cancel' or 'swap'.
368
- * @param opts.swaps - Options for swaps transactions.
369
- * @param opts.swaps.hasApproveTx - Whether the transaction has an approval transaction.
370
- * @param opts.swaps.meta - Metadata for swap transaction.
371
- * @param opts.networkClientId - The id of the network client for this transaction.
372
- * @param opts.traceContext - The parent context for any new traces.
312
+ * @param options - Additional options to control how the transaction is added.
313
+ * @param options.actionId - Unique ID to prevent duplicate requests.
314
+ * @param options.deviceConfirmedOn - An enum to indicate what device confirmed the transaction.
315
+ * @param options.method - RPC method that requested the transaction.
316
+ * @param options.origin - The origin of the transaction request, such as a dApp hostname.
317
+ * @param options.requireApproval - Whether the transaction requires approval by the user, defaults to true unless explicitly disabled.
318
+ * @param options.securityAlertResponse - Response from security validator.
319
+ * @param options.sendFlowHistory - The sendFlowHistory entries to add.
320
+ * @param options.type - Type of transaction to add, such as 'cancel' or 'swap'.
321
+ * @param options.swaps - Options for swaps transactions.
322
+ * @param options.swaps.hasApproveTx - Whether the transaction has an approval transaction.
323
+ * @param options.swaps.meta - Metadata for swap transaction.
324
+ * @param options.networkClientId - The id of the network client for this transaction.
325
+ * @param options.traceContext - The parent context for any new traces.
373
326
  * @returns Object containing a promise resolving to the transaction hash if approved.
374
327
  */
375
- async addTransaction(txParams, { actionId, deviceConfirmedOn, method, origin, requireApproval, securityAlertResponse, sendFlowHistory, swaps = {}, traceContext, type, networkClientId: requestNetworkClientId, } = {}) {
376
- (0, logger_1.projectLogger)('Adding transaction', txParams);
328
+ async addTransaction(txParams, options) {
329
+ (0, logger_1.projectLogger)('Adding transaction', txParams, options);
330
+ const { actionId, deviceConfirmedOn, method, networkClientId, origin, requireApproval, securityAlertResponse, sendFlowHistory, swaps = {}, traceContext, type, } = options;
377
331
  txParams = (0, utils_2.normalizeTransactionParams)(txParams);
378
- if (requestNetworkClientId &&
379
- !__classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").has(requestNetworkClientId)) {
380
- throw new Error('The networkClientId for this transaction could not be found');
332
+ if (!__classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").has(networkClientId)) {
333
+ throw new Error(`Network client not found - ${networkClientId}`);
381
334
  }
382
- const networkClientId = requestNetworkClientId ?? __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getGlobalNetworkClientId).call(this);
383
335
  const isEIP1559Compatible = await this.getEIP1559Compatibility(networkClientId);
384
336
  (0, validation_1.validateTxParams)(txParams, isEIP1559Compatible);
385
337
  if (origin && this.getPermittedAccounts) {
386
338
  await (0, validation_1.validateTransactionOrigin)(await this.getPermittedAccounts(origin), __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getSelectedAccount).call(this).address, txParams.from, origin);
387
339
  }
388
340
  const dappSuggestedGasFees = this.generateDappSuggestedGasFees(txParams, origin);
389
- const chainId = this.getChainId(networkClientId);
390
- const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
341
+ const chainId = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getChainId).call(this, networkClientId);
342
+ const ethQuery = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getEthQuery).call(this, {
391
343
  networkClientId,
392
- chainId,
393
344
  });
394
345
  const transactionType = type ?? (await (0, transaction_type_1.determineTransactionType)(txParams, ethQuery)).type;
395
346
  const existingTransactionMeta = this.getTransactionWithActionId(actionId);
@@ -403,15 +354,16 @@ class TransactionController extends base_controller_1.BaseController {
403
354
  dappSuggestedGasFees,
404
355
  deviceConfirmedOn,
405
356
  id: (0, uuid_1.v1)(),
357
+ isFirstTimeInteraction: undefined,
358
+ networkClientId,
406
359
  origin,
407
360
  securityAlertResponse,
408
361
  status: types_1.TransactionStatus.unapproved,
409
362
  time: Date.now(),
410
363
  txParams,
364
+ type: transactionType,
411
365
  userEditedGasLimit: false,
412
366
  verifiedOnBlockchain: false,
413
- type: transactionType,
414
- networkClientId,
415
367
  };
416
368
  await __classPrivateFieldGet(this, _TransactionController_trace, "f").call(this, { name: 'Estimate Gas Properties', parentContext: traceContext }, (context) => this.updateGasProperties(addedTransactionMeta, {
417
369
  traceContext: context,
@@ -444,9 +396,14 @@ class TransactionController extends base_controller_1.BaseController {
444
396
  (0, logger_1.projectLogger)('Error while updating simulation data', error);
445
397
  throw error;
446
398
  });
399
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateFirstTimeInteraction).call(this, addedTransactionMeta, {
400
+ traceContext,
401
+ }).catch((error) => {
402
+ (0, logger_1.projectLogger)('Error while updating first interaction properties', error);
403
+ });
447
404
  }
448
405
  else {
449
- (0, logger_1.projectLogger)('Skipping simulation as approval not required');
406
+ (0, logger_1.projectLogger)('Skipping simulation & first interaction update as approval not required');
450
407
  }
451
408
  this.messagingSystem.publish(`${controllerName}:unapprovedTransactionAdded`, addedTransactionMeta);
452
409
  }
@@ -460,29 +417,13 @@ class TransactionController extends base_controller_1.BaseController {
460
417
  transactionMeta: addedTransactionMeta,
461
418
  };
462
419
  }
463
- startIncomingTransactionPolling(networkClientIds = []) {
464
- if (networkClientIds.length === 0) {
465
- this.incomingTransactionHelper.start();
466
- return;
467
- }
420
+ startIncomingTransactionPolling(networkClientIds) {
468
421
  __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").startIncomingTransactionPolling(networkClientIds);
469
422
  }
470
- stopIncomingTransactionPolling(networkClientIds = []) {
471
- if (networkClientIds.length === 0) {
472
- this.incomingTransactionHelper.stop();
473
- return;
474
- }
423
+ stopIncomingTransactionPolling(networkClientIds) {
475
424
  __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopIncomingTransactionPolling(networkClientIds);
476
425
  }
477
- stopAllIncomingTransactionPolling() {
478
- this.incomingTransactionHelper.stop();
479
- __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopAllIncomingTransactionPolling();
480
- }
481
426
  async updateIncomingTransactions(networkClientIds = []) {
482
- if (networkClientIds.length === 0) {
483
- await this.incomingTransactionHelper.update();
484
- return;
485
- }
486
427
  await __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").updateIncomingTransactions(networkClientIds);
487
428
  }
488
429
  /**
@@ -546,7 +487,7 @@ class TransactionController extends base_controller_1.BaseController {
546
487
  * @returns The gas and gas price.
547
488
  */
548
489
  async estimateGas(transaction, networkClientId) {
549
- const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
490
+ const ethQuery = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getEthQuery).call(this, {
550
491
  networkClientId,
551
492
  });
552
493
  const { estimatedGas, simulationFails } = await (0, gas_1.estimateGas)(transaction, ethQuery);
@@ -560,7 +501,7 @@ class TransactionController extends base_controller_1.BaseController {
560
501
  * @param networkClientId - The network client id to use for the estimate.
561
502
  */
562
503
  async estimateGasBuffered(transaction, multiplier, networkClientId) {
563
- const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
504
+ const ethQuery = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getEthQuery).call(this, {
564
505
  networkClientId,
565
506
  });
566
507
  const { blockGasLimit, estimatedGas, simulationFails } = await (0, gas_1.estimateGas)(transaction, ethQuery);
@@ -603,24 +544,21 @@ class TransactionController extends base_controller_1.BaseController {
603
544
  this.updateTransaction(updatedTransactionMeta, `${controllerName}:updatesecurityAlertResponse - securityAlertResponse updated`);
604
545
  }
605
546
  /**
606
- * Removes all transactions from state, optionally based on the current network.
547
+ * Remove transactions from state.
607
548
  *
608
- * @param ignoreNetwork - Determines whether to wipe all transactions, or just those on the
609
- * current network. If `true`, all transactions are wiped.
610
- * @param address - If specified, only transactions originating from this address will be
611
- * wiped on current network.
549
+ * @param options - The options bag.
550
+ * @param options.address - Remove transactions from this account only. Defaults to all accounts.
551
+ * @param options.chainId - Remove transactions for the specified chain only. Defaults to all chains.
612
552
  */
613
- wipeTransactions(ignoreNetwork, address) {
614
- /* istanbul ignore next */
615
- if (ignoreNetwork && !address) {
553
+ wipeTransactions({ address, chainId, } = {}) {
554
+ if (!chainId && !address) {
616
555
  this.update((state) => {
617
556
  state.transactions = [];
618
557
  });
619
558
  return;
620
559
  }
621
- const currentChainId = this.getChainId();
622
- const newTransactions = this.state.transactions.filter(({ chainId, txParams }) => {
623
- const isMatchingNetwork = ignoreNetwork || chainId === currentChainId;
560
+ const newTransactions = this.state.transactions.filter(({ chainId: txChainId, txParams }) => {
561
+ const isMatchingNetwork = !chainId || chainId === txChainId;
624
562
  if (!isMatchingNetwork) {
625
563
  return true;
626
564
  }
@@ -810,10 +748,8 @@ class TransactionController extends base_controller_1.BaseController {
810
748
  };
811
749
  editableParams.txParams = (0, lodash_1.pickBy)(editableParams.txParams);
812
750
  const updatedTransaction = (0, lodash_1.merge)({}, transactionMeta, editableParams);
813
- const provider = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getProvider({
814
- chainId: transactionMeta.chainId,
815
- networkClientId: transactionMeta.networkClientId,
816
- });
751
+ const { networkClientId } = transactionMeta;
752
+ const provider = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getProvider).call(this, { networkClientId });
817
753
  const ethQuery = new eth_query_1.default(provider);
818
754
  const { type } = await (0, transaction_type_1.determineTransactionType)(updatedTransaction.txParams, ethQuery);
819
755
  updatedTransaction.type = type;
@@ -841,19 +777,9 @@ class TransactionController extends base_controller_1.BaseController {
841
777
  return '';
842
778
  }
843
779
  const initialTx = listOfTxParams[0];
844
- const common = this.getCommonConfiguration(initialTx.chainId);
845
- // We need to ensure we get the nonce using the the NonceTracker on the chain matching
846
- // the txParams. In this context we only have chainId available to us, but the
847
- // NonceTrackers are keyed by networkClientId. To workaround this, we attempt to find
848
- // a networkClientId that matches the chainId. As a fallback, the globally selected
849
- // network's NonceTracker will be used instead.
850
- let networkClientId;
851
- try {
852
- networkClientId = this.messagingSystem.call(`NetworkController:findNetworkClientIdByChainId`, initialTx.chainId);
853
- }
854
- catch (err) {
855
- (0, logger_1.projectLogger)('failed to find networkClientId from chainId', err);
856
- }
780
+ const { chainId } = initialTx;
781
+ const common = this.getCommonConfiguration(chainId);
782
+ const networkClientId = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getNetworkClientId).call(this, { chainId });
857
783
  const initialTxAsEthTx = tx_1.TransactionFactory.fromTxData(initialTx, {
858
784
  common,
859
785
  });
@@ -935,14 +861,12 @@ class TransactionController extends base_controller_1.BaseController {
935
861
  * Search transaction metadata for matching entries.
936
862
  *
937
863
  * @param opts - Options bag.
938
- * @param opts.searchCriteria - An object containing values or functions for transaction properties to filter transactions with.
939
864
  * @param opts.initialList - The transactions to search. Defaults to the current state.
940
- * @param opts.filterToCurrentNetwork - Whether to filter the results to the current network. Defaults to true.
941
865
  * @param opts.limit - The maximum number of transactions to return. No limit by default.
866
+ * @param opts.searchCriteria - An object containing values or functions for transaction properties to filter transactions with.
942
867
  * @returns An array of transactions matching the provided options.
943
868
  */
944
- getTransactions({ searchCriteria = {}, initialList, filterToCurrentNetwork = true, limit, } = {}) {
945
- const chainId = this.getChainId();
869
+ getTransactions({ initialList, limit, searchCriteria = {}, } = {}) {
946
870
  // searchCriteria is an object that might have values that aren't predicate
947
871
  // methods. When providing any other value type (string, number, etc), we
948
872
  // consider this shorthand for "check the value at key for strict equality
@@ -960,9 +884,6 @@ class TransactionController extends base_controller_1.BaseController {
960
884
  // Combine sortBy and pickBy to transform our state object into an array of
961
885
  // matching transactions that are sorted by time.
962
886
  const filteredTransactions = (0, lodash_1.sortBy)((0, lodash_1.pickBy)(transactionsToFilter, (transaction) => {
963
- if (filterToCurrentNetwork && transaction.chainId !== chainId) {
964
- return false;
965
- }
966
887
  // iterate over the predicateMethods keys to check if the transaction
967
888
  // matches the searchCriteria
968
889
  for (const [key, predicate] of Object.entries(predicateMethods)) {
@@ -1018,9 +939,9 @@ class TransactionController extends base_controller_1.BaseController {
1018
939
  return filteredTransactions;
1019
940
  }
1020
941
  async estimateGasFee({ transactionParams, chainId, networkClientId: requestNetworkClientId, }) {
1021
- const networkClientId = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getNetworkClientId).call(this, {
1022
- networkClientId: requestNetworkClientId,
942
+ const { id: networkClientId, provider } = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getNetworkClient({
1023
943
  chainId,
944
+ networkClientId: requestNetworkClientId,
1024
945
  });
1025
946
  const transactionMeta = {
1026
947
  txParams: transactionParams,
@@ -1029,10 +950,7 @@ class TransactionController extends base_controller_1.BaseController {
1029
950
  };
1030
951
  // Guaranteed as the default gas fee flow matches all transactions.
1031
952
  const gasFeeFlow = (0, gas_flow_1.getGasFeeFlow)(transactionMeta, this.gasFeeFlows);
1032
- const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
1033
- networkClientId,
1034
- chainId,
1035
- });
953
+ const ethQuery = new eth_query_1.default(provider);
1036
954
  const gasFeeControllerData = await this.getGasFeeEstimates({
1037
955
  networkClientId,
1038
956
  });
@@ -1051,9 +969,9 @@ class TransactionController extends base_controller_1.BaseController {
1051
969
  * @param request.networkClientId - The ID of a specific network client to process the transaction.
1052
970
  */
1053
971
  async getLayer1GasFee({ transactionParams, chainId, networkClientId, }) {
1054
- const provider = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getProvider({
1055
- networkClientId,
972
+ const provider = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getProvider).call(this, {
1056
973
  chainId,
974
+ networkClientId,
1057
975
  });
1058
976
  return await (0, layer1_gas_fee_flow_1.getTransactionLayer1GasFee)({
1059
977
  layer1GasFeeFlows: this.layer1GasFeeFlows,
@@ -1124,15 +1042,10 @@ class TransactionController extends base_controller_1.BaseController {
1124
1042
  const isEIP1559Compatible = transactionMeta.txParams.type !== types_1.TransactionEnvelopeType.legacy &&
1125
1043
  (await this.getEIP1559Compatibility(transactionMeta.networkClientId));
1126
1044
  const { networkClientId, chainId } = transactionMeta;
1127
- const isCustomNetwork = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_isCustomNetwork).call(this, networkClientId);
1128
- const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
1129
- networkClientId,
1130
- chainId,
1131
- });
1132
- const provider = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getProvider({
1133
- networkClientId,
1134
- chainId,
1135
- });
1045
+ const isCustomNetwork = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getNetworkClient({ networkClientId })
1046
+ .configuration.type === network_controller_1.NetworkClientType.Custom;
1047
+ const ethQuery = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getEthQuery).call(this, { networkClientId });
1048
+ const provider = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getProvider).call(this, { networkClientId });
1136
1049
  await __classPrivateFieldGet(this, _TransactionController_trace, "f").call(this, { name: 'Update Gas', parentContext: traceContext }, async () => {
1137
1050
  await (0, gas_1.updateGas)({
1138
1051
  ethQuery,
@@ -1290,10 +1203,8 @@ class TransactionController extends base_controller_1.BaseController {
1290
1203
  if (!rawTx) {
1291
1204
  return ApprovalState.NotApproved;
1292
1205
  }
1293
- const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
1294
- networkClientId: transactionMeta.networkClientId,
1295
- chainId: transactionMeta.chainId,
1296
- });
1206
+ const { networkClientId } = transactionMeta;
1207
+ const ethQuery = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getEthQuery).call(this, { networkClientId });
1297
1208
  let preTxBalance;
1298
1209
  const shouldUpdatePreTxBalance = transactionMeta.type === types_1.TransactionType.swap;
1299
1210
  if (shouldUpdatePreTxBalance) {
@@ -1487,14 +1398,6 @@ class TransactionController extends base_controller_1.BaseController {
1487
1398
  const isCompleted = this.isLocalFinalState(transaction.status);
1488
1399
  return { meta: transaction, isCompleted };
1489
1400
  }
1490
- getChainId(networkClientId) {
1491
- const globalChainId = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getGlobalChainId).call(this);
1492
- const globalNetworkClientId = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getGlobalNetworkClientId).call(this);
1493
- if (!networkClientId || networkClientId === globalNetworkClientId) {
1494
- return globalChainId;
1495
- }
1496
- return this.messagingSystem.call(`NetworkController:getNetworkClientById`, networkClientId).configuration.chainId;
1497
- }
1498
1401
  prepareUnsignedEthTx(chainId, txParams) {
1499
1402
  return tx_1.TransactionFactory.fromTxData(txParams, {
1500
1403
  freeze: false,
@@ -1520,14 +1423,16 @@ class TransactionController extends base_controller_1.BaseController {
1520
1423
  }
1521
1424
  onIncomingTransactions({ added, updated, }) {
1522
1425
  this.update((state) => {
1523
- const { transactions: currentTransactions } = state;
1524
- const updatedTransactions = [
1525
- ...added,
1526
- ...currentTransactions.map((originalTransaction) => {
1527
- const updatedTransaction = updated.find(({ hash }) => hash === originalTransaction.hash);
1528
- return updatedTransaction ?? originalTransaction;
1529
- }),
1530
- ];
1426
+ const { transactions } = state;
1427
+ const existingTransactions = transactions.map((tx) => updated.find(({ hash }) => hash === tx.hash) ?? tx);
1428
+ const updatedTransactions = [...added, ...existingTransactions].map((tx) => {
1429
+ const { chainId } = tx;
1430
+ const networkClientId = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getNetworkClientId).call(this, { chainId });
1431
+ return {
1432
+ ...tx,
1433
+ networkClientId,
1434
+ };
1435
+ });
1531
1436
  state.transactions = this.trimTransactionsForState(updatedTransactions);
1532
1437
  });
1533
1438
  }
@@ -1720,7 +1625,7 @@ class TransactionController extends base_controller_1.BaseController {
1720
1625
  transactionMeta,
1721
1626
  });
1722
1627
  }
1723
- getNonceTrackerTransactions(status, address, chainId = this.getChainId()) {
1628
+ getNonceTrackerTransactions(status, address, chainId) {
1724
1629
  return (0, nonce_1.getAndFormatTransactionsForNonceTracker)(chainId, address, status, this.state.transactions);
1725
1630
  }
1726
1631
  onConfirmedTransaction(transactionMeta) {
@@ -1736,13 +1641,11 @@ class TransactionController extends base_controller_1.BaseController {
1736
1641
  }
1737
1642
  async updatePostBalance(transactionMeta) {
1738
1643
  try {
1739
- if (transactionMeta.type !== types_1.TransactionType.swap) {
1644
+ const { networkClientId, type } = transactionMeta;
1645
+ if (type !== types_1.TransactionType.swap) {
1740
1646
  return;
1741
1647
  }
1742
- const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
1743
- networkClientId: transactionMeta.networkClientId,
1744
- chainId: transactionMeta.chainId,
1745
- });
1648
+ const ethQuery = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getEthQuery).call(this, { networkClientId });
1746
1649
  const { updatedTransactionMeta, approvalTransactionMeta } = await (0, swaps_1.updatePostTransactionBalance)(transactionMeta, {
1747
1650
  ethQuery,
1748
1651
  getTransaction: this.getTransaction.bind(this),
@@ -1764,7 +1667,6 @@ class TransactionController extends base_controller_1.BaseController {
1764
1667
  }
1765
1668
  catch (error) {
1766
1669
  if (this.isTransactionAlreadyConfirmedError(error)) {
1767
- await this.pendingTransactionTracker.forceCheckTransaction(transactionMeta);
1768
1670
  throw new Error('Previous transaction is already confirmed');
1769
1671
  }
1770
1672
  throw error;
@@ -1785,7 +1687,7 @@ class TransactionController extends base_controller_1.BaseController {
1785
1687
  }
1786
1688
  }
1787
1689
  exports.TransactionController = TransactionController;
1788
- _TransactionController_internalEvents = new WeakMap(), _TransactionController_incomingTransactionOptions = new WeakMap(), _TransactionController_pendingTransactionOptions = new WeakMap(), _TransactionController_trace = new WeakMap(), _TransactionController_transactionHistoryLimit = new WeakMap(), _TransactionController_isSimulationEnabled = new WeakMap(), _TransactionController_testGasFeeFlows = new WeakMap(), _TransactionController_multichainTrackingHelper = new WeakMap(), _TransactionController_checkForPendingTransactionAndStartPolling = new WeakMap(), _TransactionController_instances = new WeakSet(), _TransactionController_retryTransaction = async function _TransactionController_retryTransaction({ actionId, afterSubmit, estimatedBaseFee, gasValues, label, prepareTransactionParams, rate, transactionId, transactionType, }) {
1690
+ _TransactionController_internalEvents = new WeakMap(), _TransactionController_methodDataHelper = new WeakMap(), _TransactionController_incomingTransactionOptions = new WeakMap(), _TransactionController_pendingTransactionOptions = new WeakMap(), _TransactionController_trace = new WeakMap(), _TransactionController_transactionHistoryLimit = new WeakMap(), _TransactionController_isFirstTimeInteractionEnabled = new WeakMap(), _TransactionController_isSimulationEnabled = new WeakMap(), _TransactionController_testGasFeeFlows = new WeakMap(), _TransactionController_multichainTrackingHelper = new WeakMap(), _TransactionController_checkForPendingTransactionAndStartPolling = new WeakMap(), _TransactionController_instances = new WeakSet(), _TransactionController_retryTransaction = async function _TransactionController_retryTransaction({ actionId, afterSubmit, estimatedBaseFee, gasValues, label, prepareTransactionParams, rate, transactionId, transactionType, }) {
1789
1691
  // If transaction is found for same action id, do not create a new transaction.
1790
1692
  if (this.getTransactionWithActionId(actionId)) {
1791
1693
  return;
@@ -1820,10 +1722,8 @@ _TransactionController_internalEvents = new WeakMap(), _TransactionController_in
1820
1722
  newFee,
1821
1723
  txParams: newTxParams,
1822
1724
  });
1823
- const ethQuery = __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getEthQuery({
1824
- networkClientId: transactionMeta.networkClientId,
1825
- chainId: transactionMeta.chainId,
1826
- });
1725
+ const { networkClientId } = transactionMeta;
1726
+ const ethQuery = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getEthQuery).call(this, { networkClientId });
1827
1727
  const newTransactionMeta = {
1828
1728
  ...transactionMetaWithRsv,
1829
1729
  actionId,
@@ -1852,6 +1752,23 @@ _TransactionController_internalEvents = new WeakMap(), _TransactionController_in
1852
1752
  actionId,
1853
1753
  });
1854
1754
  afterSubmit?.(newTransactionMeta);
1755
+ }, _TransactionController_getChainId = function _TransactionController_getChainId(networkClientId) {
1756
+ return __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getNetworkClient({ networkClientId })
1757
+ .configuration.chainId;
1758
+ }, _TransactionController_getNetworkClientId = function _TransactionController_getNetworkClientId({ chainId, networkClientId, }) {
1759
+ if (networkClientId) {
1760
+ return networkClientId;
1761
+ }
1762
+ return __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getNetworkClient({
1763
+ chainId,
1764
+ }).id;
1765
+ }, _TransactionController_getEthQuery = function _TransactionController_getEthQuery({ chainId, networkClientId, }) {
1766
+ return new eth_query_1.default(__classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getProvider).call(this, { chainId, networkClientId }));
1767
+ }, _TransactionController_getProvider = function _TransactionController_getProvider({ chainId, networkClientId, }) {
1768
+ return __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").getNetworkClient({
1769
+ chainId,
1770
+ networkClientId,
1771
+ }).provider;
1855
1772
  }, _TransactionController_createNonceTracker = function _TransactionController_createNonceTracker({ provider, blockTracker, chainId, }) {
1856
1773
  return new nonce_tracker_1.NonceTracker({
1857
1774
  // TODO: Fix types
@@ -1860,18 +1777,23 @@ _TransactionController_internalEvents = new WeakMap(), _TransactionController_in
1860
1777
  // TODO: Fix types
1861
1778
  blockTracker,
1862
1779
  getPendingTransactions: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getNonceTrackerPendingTransactions).bind(this, chainId),
1863
- getConfirmedTransactions: this.getNonceTrackerTransactions.bind(this, types_1.TransactionStatus.confirmed),
1780
+ getConfirmedTransactions: this.getNonceTrackerTransactions.bind(this, types_1.TransactionStatus.confirmed, chainId),
1781
+ });
1782
+ }, _TransactionController_createRemoteTransactionSource = function _TransactionController_createRemoteTransactionSource() {
1783
+ return new EtherscanRemoteTransactionSource_1.EtherscanRemoteTransactionSource({
1784
+ apiKeysByChainId: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").etherscanApiKeysByChainId,
1785
+ includeTokenTransfers: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").includeTokenTransfers,
1864
1786
  });
1865
- }, _TransactionController_createIncomingTransactionHelper = function _TransactionController_createIncomingTransactionHelper({ blockTracker, etherscanRemoteTransactionSource, chainId, }) {
1787
+ }, _TransactionController_createIncomingTransactionHelper = function _TransactionController_createIncomingTransactionHelper({ blockTracker, remoteTransactionSource, chainId, }) {
1866
1788
  const incomingTransactionHelper = new IncomingTransactionHelper_1.IncomingTransactionHelper({
1867
1789
  blockTracker,
1868
1790
  getCurrentAccount: () => __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getSelectedAccount).call(this),
1869
1791
  getLastFetchedBlockNumbers: () => this.state.lastFetchedBlockNumbers,
1870
1792
  getLocalTransactions: () => this.state.transactions,
1871
- getChainId: chainId ? () => chainId : this.getChainId.bind(this),
1793
+ getChainId: () => chainId,
1872
1794
  isEnabled: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").isEnabled,
1873
1795
  queryEntireHistory: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").queryEntireHistory,
1874
- remoteTransactionSource: etherscanRemoteTransactionSource,
1796
+ remoteTransactionSource,
1875
1797
  transactionLimit: __classPrivateFieldGet(this, _TransactionController_transactionHistoryLimit, "f"),
1876
1798
  updateTransactions: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").updateTransactions,
1877
1799
  });
@@ -1879,15 +1801,14 @@ _TransactionController_internalEvents = new WeakMap(), _TransactionController_in
1879
1801
  return incomingTransactionHelper;
1880
1802
  }, _TransactionController_createPendingTransactionTracker = function _TransactionController_createPendingTransactionTracker({ provider, blockTracker, chainId, }) {
1881
1803
  const ethQuery = new eth_query_1.default(provider);
1882
- const getChainId = chainId ? () => chainId : this.getChainId.bind(this);
1883
1804
  const pendingTransactionTracker = new PendingTransactionTracker_1.PendingTransactionTracker({
1884
1805
  blockTracker,
1885
- getChainId,
1806
+ getChainId: () => chainId,
1886
1807
  getEthQuery: () => ethQuery,
1887
1808
  getTransactions: () => this.state.transactions,
1888
1809
  isResubmitEnabled: __classPrivateFieldGet(this, _TransactionController_pendingTransactionOptions, "f").isResubmitEnabled,
1889
1810
  getGlobalLock: () => __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").acquireNonceLockForChainIdKey({
1890
- chainId: getChainId(),
1811
+ chainId,
1891
1812
  }),
1892
1813
  publishTransaction: (_ethQuery, transactionMeta) => this.publishTransaction(_ethQuery, transactionMeta, {
1893
1814
  skipSubmitHistory: true,
@@ -1900,10 +1821,6 @@ _TransactionController_internalEvents = new WeakMap(), _TransactionController_in
1900
1821
  __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_addPendingTransactionTrackerListeners).call(this, pendingTransactionTracker);
1901
1822
  return pendingTransactionTracker;
1902
1823
  }, _TransactionController_stopAllTracking = function _TransactionController_stopAllTracking() {
1903
- this.pendingTransactionTracker.stop();
1904
- __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removePendingTransactionTrackerListeners).call(this, this.pendingTransactionTracker);
1905
- this.incomingTransactionHelper.stop();
1906
- __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removeIncomingTransactionHelperListeners).call(this, this.incomingTransactionHelper);
1907
1824
  __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopAllTracking();
1908
1825
  }, _TransactionController_removeIncomingTransactionHelperListeners = function _TransactionController_removeIncomingTransactionHelperListeners(incomingTransactionHelper) {
1909
1826
  incomingTransactionHelper.hub.removeAllListeners('transactions');
@@ -1963,6 +1880,48 @@ _TransactionController_internalEvents = new WeakMap(), _TransactionController_in
1963
1880
  });
1964
1881
  }
1965
1882
  return transactionMeta;
1883
+ }, _TransactionController_updateFirstTimeInteraction = async function _TransactionController_updateFirstTimeInteraction(transactionMeta, { traceContext, } = {}) {
1884
+ if (!__classPrivateFieldGet(this, _TransactionController_isFirstTimeInteractionEnabled, "f").call(this)) {
1885
+ return;
1886
+ }
1887
+ const { chainId, id: transactionId, txParams: { to, from }, } = transactionMeta;
1888
+ const request = {
1889
+ chainId: (0, utils_1.hexToNumber)(chainId),
1890
+ to: to,
1891
+ from,
1892
+ };
1893
+ (0, validation_1.validateParamTo)(to);
1894
+ const existingTransaction = this.state.transactions.find((tx) => tx.chainId === chainId &&
1895
+ tx.txParams.from === from &&
1896
+ tx.txParams.to === to &&
1897
+ tx.id !== transactionId);
1898
+ // Check if there is an existing transaction with the same from, to, and chainId
1899
+ // else we continue to check the account address relationship from API
1900
+ if (existingTransaction) {
1901
+ return;
1902
+ }
1903
+ try {
1904
+ const { count } = await __classPrivateFieldGet(this, _TransactionController_trace, "f").call(this, { name: 'Account Address Relationship', parentContext: traceContext }, () => (0, accounts_api_1.getAccountAddressRelationship)(request));
1905
+ const isFirstTimeInteraction = count === undefined ? undefined : count === 0;
1906
+ const finalTransactionMeta = this.getTransaction(transactionId);
1907
+ /* istanbul ignore if */
1908
+ if (!finalTransactionMeta) {
1909
+ (0, logger_1.projectLogger)('Cannot update first time interaction as transaction not found', transactionId);
1910
+ return;
1911
+ }
1912
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateTransactionInternal).call(this, {
1913
+ transactionId,
1914
+ note: 'TransactionController#updateFirstInteraction - Update first time interaction',
1915
+ }, (txMeta) => {
1916
+ txMeta.isFirstTimeInteraction = isFirstTimeInteraction;
1917
+ });
1918
+ (0, logger_1.projectLogger)('Updated first time interaction', transactionId, {
1919
+ isFirstTimeInteraction,
1920
+ });
1921
+ }
1922
+ catch (error) {
1923
+ (0, logger_1.projectLogger)('Error fetching account address relationship, skipping first time interaction update', error);
1924
+ }
1966
1925
  }, _TransactionController_updateSimulationData = async function _TransactionController_updateSimulationData(transactionMeta, { blockTime, traceContext, } = {}) {
1967
1926
  const { id: transactionId, chainId, txParams, simulationData: prevSimulationData, } = transactionMeta;
1968
1927
  const { from, to, value, data } = txParams;
@@ -2018,26 +1977,6 @@ _TransactionController_internalEvents = new WeakMap(), _TransactionController_in
2018
1977
  txMeta.layer1GasFee = layer1GasFee;
2019
1978
  }
2020
1979
  });
2021
- }, _TransactionController_getNetworkClientId = function _TransactionController_getNetworkClientId({ networkClientId: requestNetworkClientId, chainId, }) {
2022
- const globalChainId = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getGlobalChainId).call(this);
2023
- const globalNetworkClientId = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getGlobalNetworkClientId).call(this);
2024
- if (requestNetworkClientId) {
2025
- return requestNetworkClientId;
2026
- }
2027
- if (!chainId || chainId === globalChainId) {
2028
- return globalNetworkClientId;
2029
- }
2030
- return this.messagingSystem.call(`NetworkController:findNetworkClientIdByChainId`, chainId);
2031
- }, _TransactionController_getGlobalNetworkClientId = function _TransactionController_getGlobalNetworkClientId() {
2032
- return this.getNetworkState().selectedNetworkClientId;
2033
- }, _TransactionController_getGlobalChainId = function _TransactionController_getGlobalChainId() {
2034
- return this.messagingSystem.call(`NetworkController:getNetworkClientById`, this.getNetworkState().selectedNetworkClientId).configuration.chainId;
2035
- }, _TransactionController_isCustomNetwork = function _TransactionController_isCustomNetwork(networkClientId) {
2036
- const globalNetworkClientId = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getGlobalNetworkClientId).call(this);
2037
- if (!networkClientId || networkClientId === globalNetworkClientId) {
2038
- return !(0, controller_utils_1.isInfuraNetworkType)(this.getNetworkState().selectedNetworkClientId);
2039
- }
2040
- return (this.messagingSystem.call(`NetworkController:getNetworkClientById`, networkClientId).configuration.type === network_controller_1.NetworkClientType.Custom);
2041
1980
  }, _TransactionController_getSelectedAccount = function _TransactionController_getSelectedAccount() {
2042
1981
  return this.messagingSystem.call('AccountsController:getSelectedAccount');
2043
1982
  }, _TransactionController_updateSubmitHistory = function _TransactionController_updateSubmitHistory(transactionMeta, hash) {