@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
@@ -9,7 +9,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
10
10
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
11
11
  };
12
- 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;
12
+ 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;
13
13
  function $importDefault(module) {
14
14
  if (module?.__esModule) {
15
15
  return module.default;
@@ -28,19 +28,20 @@ const EthQuery = $importDefault($EthQuery);
28
28
  import { NetworkClientType } from "@metamask/network-controller";
29
29
  import { NonceTracker } from "@metamask/nonce-tracker";
30
30
  import { errorCodes, rpcErrors, providerErrors } from "@metamask/rpc-errors";
31
- import { add0x } from "@metamask/utils";
31
+ import { add0x, hexToNumber } from "@metamask/utils";
32
32
  import { Mutex } from "async-mutex";
33
33
  import { MethodRegistry } from "eth-method-registry";
34
34
  import { EventEmitter } from "events";
35
35
  import $lodash from "lodash";
36
36
  const { cloneDeep, mapValues, merge, pickBy, sortBy } = $lodash;
37
37
  import { v1 as random } from "uuid";
38
+ import { getAccountAddressRelationship } from "./api/accounts-api.mjs";
38
39
  import { DefaultGasFeeFlow } from "./gas-flows/DefaultGasFeeFlow.mjs";
39
40
  import { LineaGasFeeFlow } from "./gas-flows/LineaGasFeeFlow.mjs";
40
41
  import { OptimismLayer1GasFeeFlow } from "./gas-flows/OptimismLayer1GasFeeFlow.mjs";
41
42
  import { ScrollLayer1GasFeeFlow } from "./gas-flows/ScrollLayer1GasFeeFlow.mjs";
42
43
  import { TestGasFeeFlow } from "./gas-flows/TestGasFeeFlow.mjs";
43
- import { EtherscanRemoteTransactionSource } from "./helpers/EtherscanRemoteTransactionSource.mjs";
44
+ import { AccountsApiRemoteTransactionSource } from "./helpers/AccountsApiRemoteTransactionSource.mjs";
44
45
  import { GasFeePoller } from "./helpers/GasFeePoller.mjs";
45
46
  import { IncomingTransactionHelper } from "./helpers/IncomingTransactionHelper.mjs";
46
47
  import { MultichainTrackingHelper } from "./helpers/MultichainTrackingHelper.mjs";
@@ -60,7 +61,7 @@ import { getSimulationData } from "./utils/simulation.mjs";
60
61
  import { updatePostTransactionBalance, updateSwapsTransaction } from "./utils/swaps.mjs";
61
62
  import { determineTransactionType } from "./utils/transaction-type.mjs";
62
63
  import { normalizeTransactionParams, isEIP1559Transaction, validateGasValues, validateIfTransactionUnapproved, normalizeTxError, normalizeGasFeeValues } from "./utils/utils.mjs";
63
- import { validateTransactionOrigin, validateTxParams } from "./utils/validation.mjs";
64
+ import { validateParamTo, validateTransactionOrigin, validateTxParams } from "./utils/validation.mjs";
64
65
  /**
65
66
  * Metadata for the TransactionController state, describing how to "anonymize"
66
67
  * the state and which parts should be persisted.
@@ -181,6 +182,7 @@ export class TransactionController extends BaseController {
181
182
  * @param options.getSavedGasFees - Gets the saved gas fee config.
182
183
  * @param options.incomingTransactions - Configuration options for incoming transaction support.
183
184
  * @param options.isMultichainEnabled - Enable multichain support.
185
+ * @param options.isFirstTimeInteractionEnabled - Whether first time interaction checks are enabled.
184
186
  * @param options.isSimulationEnabled - Whether new transactions will be automatically simulated.
185
187
  * @param options.messenger - The controller messenger.
186
188
  * @param options.onNetworkStateChange - Allows subscribing to network controller state changes.
@@ -194,7 +196,7 @@ export class TransactionController extends BaseController {
194
196
  * @param options.transactionHistoryLimit - Transaction history limit.
195
197
  * @param options.hooks - The controller hooks.
196
198
  */
197
- 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, }) {
199
+ 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, }) {
198
200
  super({
199
201
  name: controllerName,
200
202
  metadata,
@@ -213,6 +215,7 @@ export class TransactionController extends BaseController {
213
215
  this.signAbortCallbacks = new Map();
214
216
  _TransactionController_trace.set(this, void 0);
215
217
  _TransactionController_transactionHistoryLimit.set(this, void 0);
218
+ _TransactionController_isFirstTimeInteractionEnabled.set(this, void 0);
216
219
  _TransactionController_isSimulationEnabled.set(this, void 0);
217
220
  _TransactionController_testGasFeeFlows.set(this, void 0);
218
221
  _TransactionController_multichainTrackingHelper.set(this, void 0);
@@ -226,6 +229,7 @@ export class TransactionController extends BaseController {
226
229
  this.isSendFlowHistoryDisabled = disableSendFlowHistory ?? false;
227
230
  this.isHistoryDisabled = disableHistory ?? false;
228
231
  this.isSwapsDisabled = disableSwaps ?? false;
232
+ __classPrivateFieldSet(this, _TransactionController_isFirstTimeInteractionEnabled, isFirstTimeInteractionEnabled ?? (() => true), "f");
229
233
  __classPrivateFieldSet(this, _TransactionController_isSimulationEnabled, isSimulationEnabled ?? (() => true), "f");
230
234
  // @ts-expect-error the type in eth-method-registry is inappropriate and should be changed
231
235
  this.registry = new MethodRegistry({ provider });
@@ -267,30 +271,20 @@ export class TransactionController extends BaseController {
267
271
  isMultichainEnabled,
268
272
  provider,
269
273
  nonceTracker: this.nonceTracker,
270
- incomingTransactionOptions: incomingTransactions,
271
274
  findNetworkClientIdByChainId,
272
275
  getNetworkClientById: ((networkClientId) => {
273
276
  return this.messagingSystem.call(`NetworkController:getNetworkClientById`, networkClientId);
274
277
  }),
275
278
  getNetworkClientRegistry,
276
- removeIncomingTransactionHelperListeners: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removeIncomingTransactionHelperListeners).bind(this),
277
279
  removePendingTransactionTrackerListeners: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_removePendingTransactionTrackerListeners).bind(this),
278
280
  createNonceTracker: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createNonceTracker).bind(this),
279
- createIncomingTransactionHelper: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createIncomingTransactionHelper).bind(this),
280
281
  createPendingTransactionTracker: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createPendingTransactionTracker).bind(this),
281
282
  onNetworkStateChange: (listener) => {
282
283
  this.messagingSystem.subscribe('NetworkController:stateChange', listener);
283
284
  },
284
285
  }), "f");
285
286
  __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").initialize();
286
- const etherscanRemoteTransactionSource = new EtherscanRemoteTransactionSource({
287
- apiKeysByChainId: incomingTransactions.etherscanApiKeysByChainId,
288
- includeTokenTransfers: incomingTransactions.includeTokenTransfers,
289
- });
290
- this.incomingTransactionHelper = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createIncomingTransactionHelper).call(this, {
291
- blockTracker,
292
- etherscanRemoteTransactionSource,
293
- });
287
+ this.incomingTransactionHelper = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createIncomingTransactionHelper).call(this);
294
288
  this.pendingTransactionTracker = __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_createPendingTransactionTracker).call(this, {
295
289
  provider,
296
290
  blockTracker,
@@ -407,15 +401,16 @@ export class TransactionController extends BaseController {
407
401
  dappSuggestedGasFees,
408
402
  deviceConfirmedOn,
409
403
  id: random(),
404
+ isFirstTimeInteraction: undefined,
405
+ networkClientId,
410
406
  origin,
411
407
  securityAlertResponse,
412
408
  status: TransactionStatus.unapproved,
413
409
  time: Date.now(),
414
410
  txParams,
411
+ type: transactionType,
415
412
  userEditedGasLimit: false,
416
413
  verifiedOnBlockchain: false,
417
- type: transactionType,
418
- networkClientId,
419
414
  };
420
415
  await __classPrivateFieldGet(this, _TransactionController_trace, "f").call(this, { name: 'Estimate Gas Properties', parentContext: traceContext }, (context) => this.updateGasProperties(addedTransactionMeta, {
421
416
  traceContext: context,
@@ -448,9 +443,14 @@ export class TransactionController extends BaseController {
448
443
  log('Error while updating simulation data', error);
449
444
  throw error;
450
445
  });
446
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateFirstTimeInteraction).call(this, addedTransactionMeta, {
447
+ traceContext,
448
+ }).catch((error) => {
449
+ log('Error while updating first interaction properties', error);
450
+ });
451
451
  }
452
452
  else {
453
- log('Skipping simulation as approval not required');
453
+ log('Skipping simulation & first interaction update as approval not required');
454
454
  }
455
455
  this.messagingSystem.publish(`${controllerName}:unapprovedTransactionAdded`, addedTransactionMeta);
456
456
  }
@@ -467,27 +467,20 @@ export class TransactionController extends BaseController {
467
467
  startIncomingTransactionPolling(networkClientIds = []) {
468
468
  if (networkClientIds.length === 0) {
469
469
  this.incomingTransactionHelper.start();
470
- return;
471
470
  }
472
- __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").startIncomingTransactionPolling(networkClientIds);
473
471
  }
474
472
  stopIncomingTransactionPolling(networkClientIds = []) {
475
473
  if (networkClientIds.length === 0) {
476
474
  this.incomingTransactionHelper.stop();
477
- return;
478
475
  }
479
- __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopIncomingTransactionPolling(networkClientIds);
480
476
  }
481
477
  stopAllIncomingTransactionPolling() {
482
478
  this.incomingTransactionHelper.stop();
483
- __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopAllIncomingTransactionPolling();
484
479
  }
485
480
  async updateIncomingTransactions(networkClientIds = []) {
486
481
  if (networkClientIds.length === 0) {
487
482
  await this.incomingTransactionHelper.update();
488
- return;
489
483
  }
490
- await __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").updateIncomingTransactions(networkClientIds);
491
484
  }
492
485
  /**
493
486
  * Attempts to cancel a transaction based on its ID by setting its status to "rejected"
@@ -615,23 +608,33 @@ export class TransactionController extends BaseController {
615
608
  * wiped on current network.
616
609
  */
617
610
  wipeTransactions(ignoreNetwork, address) {
611
+ log('Wiping transactions', { ignoreNetwork, address });
618
612
  /* istanbul ignore next */
619
613
  if (ignoreNetwork && !address) {
620
614
  this.update((state) => {
621
615
  state.transactions = [];
616
+ state.lastFetchedBlockNumbers = {};
622
617
  });
623
618
  return;
624
619
  }
625
620
  const currentChainId = this.getChainId();
626
- const newTransactions = this.state.transactions.filter(({ chainId, txParams }) => {
621
+ const { transactions } = this.state;
622
+ const newTransactions = transactions.filter((tx) => {
623
+ const { chainId, txParams } = tx;
627
624
  const isMatchingNetwork = ignoreNetwork || chainId === currentChainId;
628
625
  if (!isMatchingNetwork) {
629
626
  return true;
630
627
  }
631
- const isMatchingAddress = !address || txParams.from?.toLowerCase() === address.toLowerCase();
628
+ const isMatchingAddress = !address ||
629
+ txParams.from?.toLowerCase() === address.toLowerCase() ||
630
+ txParams.to?.toLowerCase() === address.toLowerCase();
631
+ if (isMatchingAddress) {
632
+ log('Removing transaction', tx);
633
+ }
632
634
  return !isMatchingAddress;
633
635
  });
634
636
  this.update((state) => {
637
+ state.lastFetchedBlockNumbers = {};
635
638
  state.transactions = this.trimTransactionsForState(newTransactions);
636
639
  });
637
640
  }
@@ -1522,24 +1525,28 @@ export class TransactionController extends BaseController {
1522
1525
  };
1523
1526
  return Common.custom(customChainParams);
1524
1527
  }
1525
- onIncomingTransactions({ added, updated, }) {
1528
+ onIncomingTransactions(transactions) {
1529
+ let newTransactions = [];
1526
1530
  this.update((state) => {
1527
1531
  const { transactions: currentTransactions } = state;
1528
- const updatedTransactions = [
1529
- ...added,
1530
- ...currentTransactions.map((originalTransaction) => {
1531
- const updatedTransaction = updated.find(({ hash }) => hash === originalTransaction.hash);
1532
- return updatedTransaction ?? originalTransaction;
1533
- }),
1534
- ];
1535
- state.transactions = this.trimTransactionsForState(updatedTransactions);
1536
- });
1537
- }
1538
- onUpdatedLastFetchedBlockNumbers({ lastFetchedBlockNumbers, blockNumber, }) {
1539
- this.update((state) => {
1540
- state.lastFetchedBlockNumbers = lastFetchedBlockNumbers;
1532
+ newTransactions = transactions.filter((tx) => !currentTransactions.some((currentTx) => currentTx.hash?.toLowerCase() === tx.hash?.toLowerCase() &&
1533
+ currentTx.txParams.from?.toLowerCase() ===
1534
+ tx.txParams.from?.toLowerCase()));
1535
+ if (!newTransactions.length) {
1536
+ return;
1537
+ }
1538
+ log('Adding incoming transactions to state', newTransactions.length, {
1539
+ newTransactions,
1540
+ });
1541
+ state.transactions = this.trimTransactionsForState([
1542
+ ...newTransactions,
1543
+ ...currentTransactions,
1544
+ ]);
1541
1545
  });
1542
- this.messagingSystem.publish(`${controllerName}:incomingTransactionBlockReceived`, blockNumber);
1546
+ if (!newTransactions.length) {
1547
+ return;
1548
+ }
1549
+ this.messagingSystem.publish(`${controllerName}:incomingTransactionsReceived`, newTransactions);
1543
1550
  }
1544
1551
  generateDappSuggestedGasFees(txParams, origin) {
1545
1552
  if (!origin || origin === ORIGIN_METAMASK) {
@@ -1788,7 +1795,7 @@ export class TransactionController extends BaseController {
1788
1795
  error?.data?.message?.includes('nonce too low'));
1789
1796
  }
1790
1797
  }
1791
- _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, }) {
1798
+ _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, }) {
1792
1799
  // If transaction is found for same action id, do not create a new transaction.
1793
1800
  if (this.getTransactionWithActionId(actionId)) {
1794
1801
  return;
@@ -1865,17 +1872,21 @@ _TransactionController_internalEvents = new WeakMap(), _TransactionController_in
1865
1872
  getPendingTransactions: __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getNonceTrackerPendingTransactions).bind(this, chainId),
1866
1873
  getConfirmedTransactions: this.getNonceTrackerTransactions.bind(this, TransactionStatus.confirmed),
1867
1874
  });
1868
- }, _TransactionController_createIncomingTransactionHelper = function _TransactionController_createIncomingTransactionHelper({ blockTracker, etherscanRemoteTransactionSource, chainId, }) {
1875
+ }, _TransactionController_createIncomingTransactionHelper = function _TransactionController_createIncomingTransactionHelper({ chainId, } = {}) {
1876
+ const updateCache = (fn) => {
1877
+ this.update((state) => {
1878
+ fn(state.lastFetchedBlockNumbers);
1879
+ });
1880
+ };
1869
1881
  const incomingTransactionHelper = new IncomingTransactionHelper({
1870
- blockTracker,
1871
1882
  getCurrentAccount: () => __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_getSelectedAccount).call(this),
1872
- getLastFetchedBlockNumbers: () => this.state.lastFetchedBlockNumbers,
1873
- getLocalTransactions: () => this.state.transactions,
1874
- getChainId: chainId ? () => chainId : this.getChainId.bind(this),
1883
+ getCache: () => this.state.lastFetchedBlockNumbers,
1884
+ getChainIds: chainId ? () => [chainId] : () => [this.getChainId()],
1885
+ includeTokenTransfers: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").includeTokenTransfers,
1875
1886
  isEnabled: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").isEnabled,
1876
1887
  queryEntireHistory: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").queryEntireHistory,
1877
- remoteTransactionSource: etherscanRemoteTransactionSource,
1878
- transactionLimit: __classPrivateFieldGet(this, _TransactionController_transactionHistoryLimit, "f"),
1888
+ remoteTransactionSource: new AccountsApiRemoteTransactionSource(),
1889
+ updateCache,
1879
1890
  updateTransactions: __classPrivateFieldGet(this, _TransactionController_incomingTransactionOptions, "f").updateTransactions,
1880
1891
  });
1881
1892
  __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_addIncomingTransactionHelperListeners).call(this, incomingTransactionHelper);
@@ -1910,10 +1921,9 @@ _TransactionController_internalEvents = new WeakMap(), _TransactionController_in
1910
1921
  __classPrivateFieldGet(this, _TransactionController_multichainTrackingHelper, "f").stopAllTracking();
1911
1922
  }, _TransactionController_removeIncomingTransactionHelperListeners = function _TransactionController_removeIncomingTransactionHelperListeners(incomingTransactionHelper) {
1912
1923
  incomingTransactionHelper.hub.removeAllListeners('transactions');
1913
- incomingTransactionHelper.hub.removeAllListeners('updatedLastFetchedBlockNumbers');
1924
+ incomingTransactionHelper.hub.removeAllListeners('updated-last-fetched-timestamp');
1914
1925
  }, _TransactionController_addIncomingTransactionHelperListeners = function _TransactionController_addIncomingTransactionHelperListeners(incomingTransactionHelper) {
1915
1926
  incomingTransactionHelper.hub.on('transactions', this.onIncomingTransactions.bind(this));
1916
- incomingTransactionHelper.hub.on('updatedLastFetchedBlockNumbers', this.onUpdatedLastFetchedBlockNumbers.bind(this));
1917
1927
  }, _TransactionController_removePendingTransactionTrackerListeners = function _TransactionController_removePendingTransactionTrackerListeners(pendingTransactionTracker) {
1918
1928
  pendingTransactionTracker.hub.removeAllListeners('transaction-confirmed');
1919
1929
  pendingTransactionTracker.hub.removeAllListeners('transaction-dropped');
@@ -1966,6 +1976,48 @@ _TransactionController_internalEvents = new WeakMap(), _TransactionController_in
1966
1976
  });
1967
1977
  }
1968
1978
  return transactionMeta;
1979
+ }, _TransactionController_updateFirstTimeInteraction = async function _TransactionController_updateFirstTimeInteraction(transactionMeta, { traceContext, } = {}) {
1980
+ if (!__classPrivateFieldGet(this, _TransactionController_isFirstTimeInteractionEnabled, "f").call(this)) {
1981
+ return;
1982
+ }
1983
+ const { chainId, id: transactionId, txParams: { to, from }, } = transactionMeta;
1984
+ const request = {
1985
+ chainId: hexToNumber(chainId),
1986
+ to: to,
1987
+ from,
1988
+ };
1989
+ validateParamTo(to);
1990
+ const existingTransaction = this.state.transactions.find((tx) => tx.chainId === chainId &&
1991
+ tx.txParams.from === from &&
1992
+ tx.txParams.to === to &&
1993
+ tx.id !== transactionId);
1994
+ // Check if there is an existing transaction with the same from, to, and chainId
1995
+ // else we continue to check the account address relationship from API
1996
+ if (existingTransaction) {
1997
+ return;
1998
+ }
1999
+ try {
2000
+ const { count } = await __classPrivateFieldGet(this, _TransactionController_trace, "f").call(this, { name: 'Account Address Relationship', parentContext: traceContext }, () => getAccountAddressRelationship(request));
2001
+ const isFirstTimeInteraction = count === undefined ? undefined : count === 0;
2002
+ const finalTransactionMeta = this.getTransaction(transactionId);
2003
+ /* istanbul ignore if */
2004
+ if (!finalTransactionMeta) {
2005
+ log('Cannot update first time interaction as transaction not found', transactionId);
2006
+ return;
2007
+ }
2008
+ __classPrivateFieldGet(this, _TransactionController_instances, "m", _TransactionController_updateTransactionInternal).call(this, {
2009
+ transactionId,
2010
+ note: 'TransactionController#updateFirstInteraction - Update first time interaction',
2011
+ }, (txMeta) => {
2012
+ txMeta.isFirstTimeInteraction = isFirstTimeInteraction;
2013
+ });
2014
+ log('Updated first time interaction', transactionId, {
2015
+ isFirstTimeInteraction,
2016
+ });
2017
+ }
2018
+ catch (error) {
2019
+ log('Error fetching account address relationship, skipping first time interaction update', error);
2020
+ }
1969
2021
  }, _TransactionController_updateSimulationData = async function _TransactionController_updateSimulationData(transactionMeta, { blockTime, traceContext, } = {}) {
1970
2022
  const { id: transactionId, chainId, txParams, simulationData: prevSimulationData, } = transactionMeta;
1971
2023
  const { from, to, value, data } = txParams;