@metamask-previews/transaction-controller 40.0.0-preview-ebca6967 → 40.1.0-preview-6879d4ce

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 (96) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/dist/TransactionController.cjs +103 -51
  3. package/dist/TransactionController.cjs.map +1 -1
  4. package/dist/TransactionController.d.cts +10 -9
  5. package/dist/TransactionController.d.cts.map +1 -1
  6. package/dist/TransactionController.d.mts +10 -9
  7. package/dist/TransactionController.d.mts.map +1 -1
  8. package/dist/TransactionController.mjs +105 -53
  9. package/dist/TransactionController.mjs.map +1 -1
  10. package/dist/api/accounts-api.cjs +92 -0
  11. package/dist/api/accounts-api.cjs.map +1 -0
  12. package/dist/api/accounts-api.d.cts +92 -0
  13. package/dist/api/accounts-api.d.cts.map +1 -0
  14. package/dist/api/accounts-api.d.mts +92 -0
  15. package/dist/api/accounts-api.d.mts.map +1 -0
  16. package/dist/api/accounts-api.mjs +87 -0
  17. package/dist/api/accounts-api.mjs.map +1 -0
  18. package/dist/constants.cjs +1 -85
  19. package/dist/constants.cjs.map +1 -1
  20. package/dist/constants.d.cts +0 -84
  21. package/dist/constants.d.cts.map +1 -1
  22. package/dist/constants.d.mts +0 -84
  23. package/dist/constants.d.mts.map +1 -1
  24. package/dist/constants.mjs +0 -84
  25. package/dist/constants.mjs.map +1 -1
  26. package/dist/errors.cjs +8 -1
  27. package/dist/errors.cjs.map +1 -1
  28. package/dist/errors.d.cts +4 -0
  29. package/dist/errors.d.cts.map +1 -1
  30. package/dist/errors.d.mts +4 -0
  31. package/dist/errors.d.mts.map +1 -1
  32. package/dist/errors.mjs +6 -0
  33. package/dist/errors.mjs.map +1 -1
  34. package/dist/helpers/AccountsApiRemoteTransactionSource.cjs +181 -0
  35. package/dist/helpers/AccountsApiRemoteTransactionSource.cjs.map +1 -0
  36. package/dist/helpers/AccountsApiRemoteTransactionSource.d.cts +12 -0
  37. package/dist/helpers/AccountsApiRemoteTransactionSource.d.cts.map +1 -0
  38. package/dist/helpers/AccountsApiRemoteTransactionSource.d.mts +12 -0
  39. package/dist/helpers/AccountsApiRemoteTransactionSource.d.mts.map +1 -0
  40. package/dist/helpers/AccountsApiRemoteTransactionSource.mjs +181 -0
  41. package/dist/helpers/AccountsApiRemoteTransactionSource.mjs.map +1 -0
  42. package/dist/helpers/IncomingTransactionHelper.cjs +68 -139
  43. package/dist/helpers/IncomingTransactionHelper.cjs.map +1 -1
  44. package/dist/helpers/IncomingTransactionHelper.d.cts +9 -16
  45. package/dist/helpers/IncomingTransactionHelper.d.cts.map +1 -1
  46. package/dist/helpers/IncomingTransactionHelper.d.mts +9 -16
  47. package/dist/helpers/IncomingTransactionHelper.d.mts.map +1 -1
  48. package/dist/helpers/IncomingTransactionHelper.mjs +68 -139
  49. package/dist/helpers/IncomingTransactionHelper.mjs.map +1 -1
  50. package/dist/helpers/MultichainTrackingHelper.cjs +3 -66
  51. package/dist/helpers/MultichainTrackingHelper.cjs.map +1 -1
  52. package/dist/helpers/MultichainTrackingHelper.d.cts +1 -14
  53. package/dist/helpers/MultichainTrackingHelper.d.cts.map +1 -1
  54. package/dist/helpers/MultichainTrackingHelper.d.mts +1 -14
  55. package/dist/helpers/MultichainTrackingHelper.d.mts.map +1 -1
  56. package/dist/helpers/MultichainTrackingHelper.mjs +3 -66
  57. package/dist/helpers/MultichainTrackingHelper.mjs.map +1 -1
  58. package/dist/index.cjs +3 -2
  59. package/dist/index.cjs.map +1 -1
  60. package/dist/index.d.cts +3 -3
  61. package/dist/index.d.cts.map +1 -1
  62. package/dist/index.d.mts +3 -3
  63. package/dist/index.d.mts.map +1 -1
  64. package/dist/index.mjs +2 -1
  65. package/dist/index.mjs.map +1 -1
  66. package/dist/types.cjs.map +1 -1
  67. package/dist/types.d.cts +25 -14
  68. package/dist/types.d.cts.map +1 -1
  69. package/dist/types.d.mts +25 -14
  70. package/dist/types.d.mts.map +1 -1
  71. package/dist/types.mjs.map +1 -1
  72. package/dist/utils/validation.cjs +13 -1
  73. package/dist/utils/validation.cjs.map +1 -1
  74. package/dist/utils/validation.d.cts +7 -0
  75. package/dist/utils/validation.d.cts.map +1 -1
  76. package/dist/utils/validation.d.mts +7 -0
  77. package/dist/utils/validation.d.mts.map +1 -1
  78. package/dist/utils/validation.mjs +11 -0
  79. package/dist/utils/validation.mjs.map +1 -1
  80. package/package.json +1 -1
  81. package/dist/helpers/EtherscanRemoteTransactionSource.cjs +0 -157
  82. package/dist/helpers/EtherscanRemoteTransactionSource.cjs.map +0 -1
  83. package/dist/helpers/EtherscanRemoteTransactionSource.d.cts +0 -16
  84. package/dist/helpers/EtherscanRemoteTransactionSource.d.cts.map +0 -1
  85. package/dist/helpers/EtherscanRemoteTransactionSource.d.mts +0 -16
  86. package/dist/helpers/EtherscanRemoteTransactionSource.d.mts.map +0 -1
  87. package/dist/helpers/EtherscanRemoteTransactionSource.mjs +0 -157
  88. package/dist/helpers/EtherscanRemoteTransactionSource.mjs.map +0 -1
  89. package/dist/utils/etherscan.cjs +0 -115
  90. package/dist/utils/etherscan.cjs.map +0 -1
  91. package/dist/utils/etherscan.d.cts +0 -74
  92. package/dist/utils/etherscan.d.cts.map +0 -1
  93. package/dist/utils/etherscan.d.mts +0 -74
  94. package/dist/utils/etherscan.d.mts.map +0 -1
  95. package/dist/utils/etherscan.mjs +0 -109
  96. package/dist/utils/etherscan.mjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [40.1.0]
11
+
12
+ ### Added
13
+
14
+ - Add `firstTimeInteraction` to transaction meta ([#4895](https://github.com/MetaMask/core/pull/4895))
15
+ - This is a boolean value that indicates whether the transaction is the first time the user has interacted with it.
16
+ - Add `isFirstTimeInteractionEnabled` callback constructor option ([#4895](https://github.com/MetaMask/core/pull/4895))
17
+ - This is a function that returns a boolean value indicating whether the first time interaction check should be enabled.
18
+
10
19
  ## [40.0.0]
11
20
 
12
21
  ### Changed
@@ -1133,7 +1142,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1133
1142
 
1134
1143
  All changes listed after this point were applied to this package following the monorepo conversion.
1135
1144
 
1136
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@40.0.0...HEAD
1145
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@40.1.0...HEAD
1146
+ [40.1.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@40.0.0...@metamask/transaction-controller@40.1.0
1137
1147
  [40.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@39.1.0...@metamask/transaction-controller@40.0.0
1138
1148
  [39.1.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@39.0.0...@metamask/transaction-controller@39.1.0
1139
1149
  [39.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@38.3.0...@metamask/transaction-controller@39.0.0
@@ -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_incomingTransactionOptions, _TransactionController_pendingTransactionOptions, _TransactionController_trace, _TransactionController_transactionHistoryLimit, _TransactionController_isFirstTimeInteractionEnabled, _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_updateFirstTimeInteraction, _TransactionController_updateSimulationData, _TransactionController_onGasFeePollerTransactionUpdate, _TransactionController_getNetworkClientId, _TransactionController_getGlobalNetworkClientId, _TransactionController_getGlobalChainId, _TransactionController_isCustomNetwork, _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");
@@ -31,12 +31,13 @@ const eth_method_registry_1 = require("eth-method-registry");
31
31
  const events_1 = require("events");
32
32
  const lodash_1 = require("lodash");
33
33
  const uuid_1 = require("uuid");
34
+ const accounts_api_1 = require("./api/accounts-api.cjs");
34
35
  const DefaultGasFeeFlow_1 = require("./gas-flows/DefaultGasFeeFlow.cjs");
35
36
  const LineaGasFeeFlow_1 = require("./gas-flows/LineaGasFeeFlow.cjs");
36
37
  const OptimismLayer1GasFeeFlow_1 = require("./gas-flows/OptimismLayer1GasFeeFlow.cjs");
37
38
  const ScrollLayer1GasFeeFlow_1 = require("./gas-flows/ScrollLayer1GasFeeFlow.cjs");
38
39
  const TestGasFeeFlow_1 = require("./gas-flows/TestGasFeeFlow.cjs");
39
- const EtherscanRemoteTransactionSource_1 = require("./helpers/EtherscanRemoteTransactionSource.cjs");
40
+ const AccountsApiRemoteTransactionSource_1 = require("./helpers/AccountsApiRemoteTransactionSource.cjs");
40
41
  const GasFeePoller_1 = require("./helpers/GasFeePoller.cjs");
41
42
  const IncomingTransactionHelper_1 = require("./helpers/IncomingTransactionHelper.cjs");
42
43
  const MultichainTrackingHelper_1 = require("./helpers/MultichainTrackingHelper.cjs");
@@ -177,6 +178,7 @@ class TransactionController extends base_controller_1.BaseController {
177
178
  * @param options.getSavedGasFees - Gets the saved gas fee config.
178
179
  * @param options.incomingTransactions - Configuration options for incoming transaction support.
179
180
  * @param options.isMultichainEnabled - Enable multichain support.
181
+ * @param options.isFirstTimeInteractionEnabled - Whether first time interaction checks are enabled.
180
182
  * @param options.isSimulationEnabled - Whether new transactions will be automatically simulated.
181
183
  * @param options.messenger - The controller messenger.
182
184
  * @param options.onNetworkStateChange - Allows subscribing to network controller state changes.
@@ -190,7 +192,7 @@ class TransactionController extends base_controller_1.BaseController {
190
192
  * @param options.transactionHistoryLimit - Transaction history limit.
191
193
  * @param options.hooks - The controller hooks.
192
194
  */
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, }) {
195
+ constructor({ blockTracker, disableHistory, disableSendFlowHistory, disableSwaps, getCurrentAccountEIP1559Compatibility, getCurrentNetworkEIP1559Compatibility, getExternalPendingTransactions, getGasFeeEstimates, getNetworkClientRegistry, getNetworkState, getPermittedAccounts, getSavedGasFees, incomingTransactions = {}, isMultichainEnabled = false, isFirstTimeInteractionEnabled, isSimulationEnabled, messenger, onNetworkStateChange, pendingTransactions = {}, provider, securityProviderRequest, sign, state, testGasFeeFlows, trace, transactionHistoryLimit = 40, hooks, }) {
194
196
  super({
195
197
  name: controllerName,
196
198
  metadata,
@@ -209,6 +211,7 @@ class TransactionController extends base_controller_1.BaseController {
209
211
  this.signAbortCallbacks = new Map();
210
212
  _TransactionController_trace.set(this, void 0);
211
213
  _TransactionController_transactionHistoryLimit.set(this, void 0);
214
+ _TransactionController_isFirstTimeInteractionEnabled.set(this, void 0);
212
215
  _TransactionController_isSimulationEnabled.set(this, void 0);
213
216
  _TransactionController_testGasFeeFlows.set(this, void 0);
214
217
  _TransactionController_multichainTrackingHelper.set(this, void 0);
@@ -222,6 +225,7 @@ class TransactionController extends base_controller_1.BaseController {
222
225
  this.isSendFlowHistoryDisabled = disableSendFlowHistory ?? false;
223
226
  this.isHistoryDisabled = disableHistory ?? false;
224
227
  this.isSwapsDisabled = disableSwaps ?? false;
228
+ __classPrivateFieldSet(this, _TransactionController_isFirstTimeInteractionEnabled, isFirstTimeInteractionEnabled ?? (() => true), "f");
225
229
  __classPrivateFieldSet(this, _TransactionController_isSimulationEnabled, isSimulationEnabled ?? (() => true), "f");
226
230
  // @ts-expect-error the type in eth-method-registry is inappropriate and should be changed
227
231
  this.registry = new eth_method_registry_1.MethodRegistry({ provider });
@@ -263,30 +267,20 @@ class TransactionController extends base_controller_1.BaseController {
263
267
  isMultichainEnabled,
264
268
  provider,
265
269
  nonceTracker: this.nonceTracker,
266
- incomingTransactionOptions: incomingTransactions,
267
270
  findNetworkClientIdByChainId,
268
271
  getNetworkClientById: ((networkClientId) => {
269
272
  return this.messagingSystem.call(`NetworkController:getNetworkClientById`, networkClientId);
270
273
  }),
271
274
  getNetworkClientRegistry,
272
- removeIncomingTransactionHelperListeners: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removeIncomingTransactionHelperListeners).bind(this),
273
275
  removePendingTransactionTrackerListeners: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removePendingTransactionTrackerListeners).bind(this),
274
276
  createNonceTracker: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createNonceTracker).bind(this),
275
- createIncomingTransactionHelper: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createIncomingTransactionHelper).bind(this),
276
277
  createPendingTransactionTracker: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createPendingTransactionTracker).bind(this),
277
278
  onNetworkStateChange: (listener) => {
278
279
  this.messagingSystem.subscribe('NetworkController:stateChange', listener);
279
280
  },
280
281
  }), "f");
281
282
  __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
- });
283
+ this.incomingTransactionHelper = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createIncomingTransactionHelper).call(this);
290
284
  this.pendingTransactionTracker = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createPendingTransactionTracker).call(this, {
291
285
  provider,
292
286
  blockTracker,
@@ -403,15 +397,16 @@ class TransactionController extends base_controller_1.BaseController {
403
397
  dappSuggestedGasFees,
404
398
  deviceConfirmedOn,
405
399
  id: (0, uuid_1.v1)(),
400
+ isFirstTimeInteraction: undefined,
401
+ networkClientId,
406
402
  origin,
407
403
  securityAlertResponse,
408
404
  status: types_1.TransactionStatus.unapproved,
409
405
  time: Date.now(),
410
406
  txParams,
407
+ type: transactionType,
411
408
  userEditedGasLimit: false,
412
409
  verifiedOnBlockchain: false,
413
- type: transactionType,
414
- networkClientId,
415
410
  };
416
411
  await __classPrivateFieldGet(this, _TransactionController_trace, "f").call(this, { name: 'Estimate Gas Properties', parentContext: traceContext }, (context) => this.updateGasProperties(addedTransactionMeta, {
417
412
  traceContext: context,
@@ -444,9 +439,14 @@ class TransactionController extends base_controller_1.BaseController {
444
439
  (0, logger_1.projectLogger)('Error while updating simulation data', error);
445
440
  throw error;
446
441
  });
442
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateFirstTimeInteraction).call(this, addedTransactionMeta, {
443
+ traceContext,
444
+ }).catch((error) => {
445
+ (0, logger_1.projectLogger)('Error while updating first interaction properties', error);
446
+ });
447
447
  }
448
448
  else {
449
- (0, logger_1.projectLogger)('Skipping simulation as approval not required');
449
+ (0, logger_1.projectLogger)('Skipping simulation & first interaction update as approval not required');
450
450
  }
451
451
  this.messagingSystem.publish(`${controllerName}:unapprovedTransactionAdded`, addedTransactionMeta);
452
452
  }
@@ -463,27 +463,20 @@ class TransactionController extends base_controller_1.BaseController {
463
463
  startIncomingTransactionPolling(networkClientIds = []) {
464
464
  if (networkClientIds.length === 0) {
465
465
  this.incomingTransactionHelper.start();
466
- return;
467
466
  }
468
- __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").startIncomingTransactionPolling(networkClientIds);
469
467
  }
470
468
  stopIncomingTransactionPolling(networkClientIds = []) {
471
469
  if (networkClientIds.length === 0) {
472
470
  this.incomingTransactionHelper.stop();
473
- return;
474
471
  }
475
- __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopIncomingTransactionPolling(networkClientIds);
476
472
  }
477
473
  stopAllIncomingTransactionPolling() {
478
474
  this.incomingTransactionHelper.stop();
479
- __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopAllIncomingTransactionPolling();
480
475
  }
481
476
  async updateIncomingTransactions(networkClientIds = []) {
482
477
  if (networkClientIds.length === 0) {
483
478
  await this.incomingTransactionHelper.update();
484
- return;
485
479
  }
486
- await __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").updateIncomingTransactions(networkClientIds);
487
480
  }
488
481
  /**
489
482
  * Attempts to cancel a transaction based on its ID by setting its status to "rejected"
@@ -611,23 +604,33 @@ class TransactionController extends base_controller_1.BaseController {
611
604
  * wiped on current network.
612
605
  */
613
606
  wipeTransactions(ignoreNetwork, address) {
607
+ (0, logger_1.projectLogger)('Wiping transactions', { ignoreNetwork, address });
614
608
  /* istanbul ignore next */
615
609
  if (ignoreNetwork && !address) {
616
610
  this.update((state) => {
617
611
  state.transactions = [];
612
+ state.lastFetchedBlockNumbers = {};
618
613
  });
619
614
  return;
620
615
  }
621
616
  const currentChainId = this.getChainId();
622
- const newTransactions = this.state.transactions.filter(({ chainId, txParams }) => {
617
+ const { transactions } = this.state;
618
+ const newTransactions = transactions.filter((tx) => {
619
+ const { chainId, txParams } = tx;
623
620
  const isMatchingNetwork = ignoreNetwork || chainId === currentChainId;
624
621
  if (!isMatchingNetwork) {
625
622
  return true;
626
623
  }
627
- const isMatchingAddress = !address || txParams.from?.toLowerCase() === address.toLowerCase();
624
+ const isMatchingAddress = !address ||
625
+ txParams.from?.toLowerCase() === address.toLowerCase() ||
626
+ txParams.to?.toLowerCase() === address.toLowerCase();
627
+ if (isMatchingAddress) {
628
+ (0, logger_1.projectLogger)('Removing transaction', tx);
629
+ }
628
630
  return !isMatchingAddress;
629
631
  });
630
632
  this.update((state) => {
633
+ state.lastFetchedBlockNumbers = {};
631
634
  state.transactions = this.trimTransactionsForState(newTransactions);
632
635
  });
633
636
  }
@@ -1518,24 +1521,28 @@ class TransactionController extends base_controller_1.BaseController {
1518
1521
  };
1519
1522
  return common_1.Common.custom(customChainParams);
1520
1523
  }
1521
- onIncomingTransactions({ added, updated, }) {
1524
+ onIncomingTransactions(transactions) {
1525
+ let newTransactions = [];
1522
1526
  this.update((state) => {
1523
1527
  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
- ];
1531
- state.transactions = this.trimTransactionsForState(updatedTransactions);
1532
- });
1533
- }
1534
- onUpdatedLastFetchedBlockNumbers({ lastFetchedBlockNumbers, blockNumber, }) {
1535
- this.update((state) => {
1536
- state.lastFetchedBlockNumbers = lastFetchedBlockNumbers;
1528
+ newTransactions = transactions.filter((tx) => !currentTransactions.some((currentTx) => currentTx.hash?.toLowerCase() === tx.hash?.toLowerCase() &&
1529
+ currentTx.txParams.from?.toLowerCase() ===
1530
+ tx.txParams.from?.toLowerCase()));
1531
+ if (!newTransactions.length) {
1532
+ return;
1533
+ }
1534
+ (0, logger_1.projectLogger)('Adding incoming transactions to state', newTransactions.length, {
1535
+ newTransactions,
1536
+ });
1537
+ state.transactions = this.trimTransactionsForState([
1538
+ ...newTransactions,
1539
+ ...currentTransactions,
1540
+ ]);
1537
1541
  });
1538
- this.messagingSystem.publish(`${controllerName}:incomingTransactionBlockReceived`, blockNumber);
1542
+ if (!newTransactions.length) {
1543
+ return;
1544
+ }
1545
+ this.messagingSystem.publish(`${controllerName}:incomingTransactionsReceived`, newTransactions);
1539
1546
  }
1540
1547
  generateDappSuggestedGasFees(txParams, origin) {
1541
1548
  if (!origin || origin === controller_utils_1.ORIGIN_METAMASK) {
@@ -1785,7 +1792,7 @@ class TransactionController extends base_controller_1.BaseController {
1785
1792
  }
1786
1793
  }
1787
1794
  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, }) {
1795
+ _TransactionController_internalEvents = 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
1796
  // If transaction is found for same action id, do not create a new transaction.
1790
1797
  if (this.getTransactionWithActionId(actionId)) {
1791
1798
  return;
@@ -1862,17 +1869,21 @@ _TransactionController_internalEvents = new WeakMap(), _TransactionController_in
1862
1869
  getPendingTransactions: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getNonceTrackerPendingTransactions).bind(this, chainId),
1863
1870
  getConfirmedTransactions: this.getNonceTrackerTransactions.bind(this, types_1.TransactionStatus.confirmed),
1864
1871
  });
1865
- }, _TransactionController_createIncomingTransactionHelper = function _TransactionController_createIncomingTransactionHelper({ blockTracker, etherscanRemoteTransactionSource, chainId, }) {
1872
+ }, _TransactionController_createIncomingTransactionHelper = function _TransactionController_createIncomingTransactionHelper({ chainId, } = {}) {
1873
+ const updateCache = (fn) => {
1874
+ this.update((state) => {
1875
+ fn(state.lastFetchedBlockNumbers);
1876
+ });
1877
+ };
1866
1878
  const incomingTransactionHelper = new IncomingTransactionHelper_1.IncomingTransactionHelper({
1867
- blockTracker,
1868
1879
  getCurrentAccount: () => __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getSelectedAccount).call(this),
1869
- getLastFetchedBlockNumbers: () => this.state.lastFetchedBlockNumbers,
1870
- getLocalTransactions: () => this.state.transactions,
1871
- getChainId: chainId ? () => chainId : this.getChainId.bind(this),
1880
+ getCache: () => this.state.lastFetchedBlockNumbers,
1881
+ getChainIds: chainId ? () => [chainId] : () => [this.getChainId()],
1882
+ includeTokenTransfers: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").includeTokenTransfers,
1872
1883
  isEnabled: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").isEnabled,
1873
1884
  queryEntireHistory: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").queryEntireHistory,
1874
- remoteTransactionSource: etherscanRemoteTransactionSource,
1875
- transactionLimit: __classPrivateFieldGet(this, _TransactionController_transactionHistoryLimit, "f"),
1885
+ remoteTransactionSource: new AccountsApiRemoteTransactionSource_1.AccountsApiRemoteTransactionSource(),
1886
+ updateCache,
1876
1887
  updateTransactions: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").updateTransactions,
1877
1888
  });
1878
1889
  __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_addIncomingTransactionHelperListeners).call(this, incomingTransactionHelper);
@@ -1907,10 +1918,9 @@ _TransactionController_internalEvents = new WeakMap(), _TransactionController_in
1907
1918
  __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopAllTracking();
1908
1919
  }, _TransactionController_removeIncomingTransactionHelperListeners = function _TransactionController_removeIncomingTransactionHelperListeners(incomingTransactionHelper) {
1909
1920
  incomingTransactionHelper.hub.removeAllListeners('transactions');
1910
- incomingTransactionHelper.hub.removeAllListeners('updatedLastFetchedBlockNumbers');
1921
+ incomingTransactionHelper.hub.removeAllListeners('updated-last-fetched-timestamp');
1911
1922
  }, _TransactionController_addIncomingTransactionHelperListeners = function _TransactionController_addIncomingTransactionHelperListeners(incomingTransactionHelper) {
1912
1923
  incomingTransactionHelper.hub.on('transactions', this.onIncomingTransactions.bind(this));
1913
- incomingTransactionHelper.hub.on('updatedLastFetchedBlockNumbers', this.onUpdatedLastFetchedBlockNumbers.bind(this));
1914
1924
  }, _TransactionController_removePendingTransactionTrackerListeners = function _TransactionController_removePendingTransactionTrackerListeners(pendingTransactionTracker) {
1915
1925
  pendingTransactionTracker.hub.removeAllListeners('transaction-confirmed');
1916
1926
  pendingTransactionTracker.hub.removeAllListeners('transaction-dropped');
@@ -1963,6 +1973,48 @@ _TransactionController_internalEvents = new WeakMap(), _TransactionController_in
1963
1973
  });
1964
1974
  }
1965
1975
  return transactionMeta;
1976
+ }, _TransactionController_updateFirstTimeInteraction = async function _TransactionController_updateFirstTimeInteraction(transactionMeta, { traceContext, } = {}) {
1977
+ if (!__classPrivateFieldGet(this, _TransactionController_isFirstTimeInteractionEnabled, "f").call(this)) {
1978
+ return;
1979
+ }
1980
+ const { chainId, id: transactionId, txParams: { to, from }, } = transactionMeta;
1981
+ const request = {
1982
+ chainId: (0, utils_1.hexToNumber)(chainId),
1983
+ to: to,
1984
+ from,
1985
+ };
1986
+ (0, validation_1.validateParamTo)(to);
1987
+ const existingTransaction = this.state.transactions.find((tx) => tx.chainId === chainId &&
1988
+ tx.txParams.from === from &&
1989
+ tx.txParams.to === to &&
1990
+ tx.id !== transactionId);
1991
+ // Check if there is an existing transaction with the same from, to, and chainId
1992
+ // else we continue to check the account address relationship from API
1993
+ if (existingTransaction) {
1994
+ return;
1995
+ }
1996
+ try {
1997
+ const { count } = await __classPrivateFieldGet(this, _TransactionController_trace, "f").call(this, { name: 'Account Address Relationship', parentContext: traceContext }, () => (0, accounts_api_1.getAccountAddressRelationship)(request));
1998
+ const isFirstTimeInteraction = count === undefined ? undefined : count === 0;
1999
+ const finalTransactionMeta = this.getTransaction(transactionId);
2000
+ /* istanbul ignore if */
2001
+ if (!finalTransactionMeta) {
2002
+ (0, logger_1.projectLogger)('Cannot update first time interaction as transaction not found', transactionId);
2003
+ return;
2004
+ }
2005
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateTransactionInternal).call(this, {
2006
+ transactionId,
2007
+ note: 'TransactionController#updateFirstInteraction - Update first time interaction',
2008
+ }, (txMeta) => {
2009
+ txMeta.isFirstTimeInteraction = isFirstTimeInteraction;
2010
+ });
2011
+ (0, logger_1.projectLogger)('Updated first time interaction', transactionId, {
2012
+ isFirstTimeInteraction,
2013
+ });
2014
+ }
2015
+ catch (error) {
2016
+ (0, logger_1.projectLogger)('Error fetching account address relationship, skipping first time interaction update', error);
2017
+ }
1966
2018
  }, _TransactionController_updateSimulationData = async function _TransactionController_updateSimulationData(transactionMeta, { blockTime, traceContext, } = {}) {
1967
2019
  const { id: transactionId, chainId, txParams, simulationData: prevSimulationData, } = transactionMeta;
1968
2020
  const { from, to, value, data } = txParams;