@metamask-previews/bridge-status-controller 66.0.2-preview-254d7df → 66.0.2-preview-b32f1a3ca

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Added
11
+
12
+ - Added `location` property to `BridgeHistoryItem` to persist the entry point across the transaction lifecycle ([#7931](https://github.com/MetaMask/core/pull/7931))
13
+ - Added `location` parameter to `StartPollingForBridgeTxStatusArgs` ([#7931](https://github.com/MetaMask/core/pull/7931))
14
+ - Added optional `location` parameter to `submitTx` method ([#7931](https://github.com/MetaMask/core/pull/7931))
15
+
16
+ ### Changed
17
+
18
+ - All post-submission events (`Submitted`, `Completed`, `Failed`, `PollingStatusUpdated`, `StatusValidationFailed`) now include the `location` property from `BridgeHistoryItem` ([#7931](https://github.com/MetaMask/core/pull/7931))
19
+
10
20
  ## [66.0.2]
11
21
 
12
22
  ### Changed
@@ -159,6 +159,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
159
159
  action_type: bridge_controller_1.MetricsActionType.SWAPBRIDGE_V1,
160
160
  polling_status: bridge_controller_1.PollingStatus.ManuallyRestarted,
161
161
  retry_attempts: previousAttempts,
162
+ location: historyItem.location ?? bridge_controller_1.MetaMetricsSwapsEventSource.MainView,
162
163
  });
163
164
  }
164
165
  }
@@ -207,7 +208,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
207
208
  });
208
209
  });
209
210
  _BridgeStatusController_addTxToHistory.set(this, (startPollingForBridgeTxStatusArgs, actionId) => {
210
- const { bridgeTxMeta, statusRequest, quoteResponse, startTime, slippagePercentage, initialDestAssetBalance, targetContractAddress, approvalTxId, isStxEnabled, accountAddress: selectedAddress, } = startPollingForBridgeTxStatusArgs;
211
+ const { bridgeTxMeta, statusRequest, quoteResponse, startTime, slippagePercentage, initialDestAssetBalance, targetContractAddress, approvalTxId, isStxEnabled, location, accountAddress: selectedAddress, } = startPollingForBridgeTxStatusArgs;
211
212
  // Determine the key for this history item:
212
213
  // - For pre-submission (non-batch EVM): use actionId
213
214
  // - For post-submission or other cases: use bridgeTxMeta.id
@@ -247,6 +248,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
247
248
  approvalTxId,
248
249
  isStxEnabled: isStxEnabled ?? false,
249
250
  featureId: quoteResponse.featureId,
251
+ location,
250
252
  };
251
253
  this.update((state) => {
252
254
  // Use actionId as key for pre-submission, or txMeta.id for post-submission
@@ -355,6 +357,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
355
357
  action_type: bridge_controller_1.MetricsActionType.SWAPBRIDGE_V1,
356
358
  polling_status: bridge_controller_1.PollingStatus.MaxPollingReached,
357
359
  retry_attempts: newAttempts.counter,
360
+ location: historyItem.location ?? bridge_controller_1.MetaMetricsSwapsEventSource.MainView,
358
361
  });
359
362
  }
360
363
  }
@@ -406,6 +409,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
406
409
  if (validationFailures.length > 0) {
407
410
  __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.StatusValidationFailed, bridgeTxMetaId, {
408
411
  failures: validationFailures,
412
+ location: historyItem.location ?? bridge_controller_1.MetaMetricsSwapsEventSource.MainView,
409
413
  });
410
414
  throw new Error(`Bridge status validation failed: ${validationFailures.join(', ')}`);
411
415
  }
@@ -701,9 +705,10 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
701
705
  * @param quoteResponse - The quote response
702
706
  * @param isStxEnabledOnClient - Whether smart transactions are enabled on the client, for example the getSmartTransactionsEnabled selector value from the extension
703
707
  * @param quotesReceivedContext - The context for the QuotesReceived event
708
+ * @param location - The entry point from which the user initiated the swap or bridge (e.g. Main View, Token View, trending_explore)
704
709
  * @returns The transaction meta
705
710
  */
706
- this.submitTx = async (accountAddress, quoteResponse, isStxEnabledOnClient, quotesReceivedContext) => {
711
+ this.submitTx = async (accountAddress, quoteResponse, isStxEnabledOnClient, quotesReceivedContext, location) => {
707
712
  this.messenger.call('BridgeController:stopPollingForQuotes', bridge_controller_1.AbortReason.TransactionSubmitted,
708
713
  // If trade is submitted before all quotes are loaded, the QuotesReceived event is published
709
714
  // If the trade has a featureId, it means it was submitted outside of the Unified Swap and Bridge experience, so no QuotesReceived event is published
@@ -716,7 +721,10 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
716
721
  const preConfirmationProperties = (0, metrics_1.getPreConfirmationPropertiesFromQuote)(quoteResponse, isStxEnabledOnClient, isHardwareAccount);
717
722
  // Emit Submitted event after submit button is clicked
718
723
  !quoteResponse.featureId &&
719
- __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Submitted, undefined, preConfirmationProperties);
724
+ __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Submitted, undefined, {
725
+ ...preConfirmationProperties,
726
+ location: location ?? bridge_controller_1.MetaMetricsSwapsEventSource.MainView,
727
+ });
720
728
  let txMeta;
721
729
  let approvalTxId;
722
730
  const startTime = Date.now();
@@ -746,6 +754,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
746
754
  __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Failed, undefined, {
747
755
  error_message: error?.message,
748
756
  ...preConfirmationProperties,
757
+ location: location ?? bridge_controller_1.MetaMetricsSwapsEventSource.MainView,
749
758
  });
750
759
  throw error;
751
760
  }
@@ -776,6 +785,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
776
785
  __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Failed, txMeta?.id, {
777
786
  error_message: error?.message,
778
787
  ...preConfirmationProperties,
788
+ location: location ?? bridge_controller_1.MetaMetricsSwapsEventSource.MainView,
779
789
  });
780
790
  throw error;
781
791
  }
@@ -834,6 +844,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
834
844
  isStxEnabled: isStxEnabledOnClient,
835
845
  startTime,
836
846
  approvalTxId,
847
+ location,
837
848
  }, actionId);
838
849
  // Pass txFee when gasIncluded is true to use the quote's gas fees
839
850
  // instead of re-estimating (which would fail for max native token swaps)
@@ -873,6 +884,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
873
884
  isStxEnabled: isStxEnabledOnClient,
874
885
  startTime,
875
886
  approvalTxId,
887
+ location,
876
888
  });
877
889
  }
878
890
  if ((0, bridge_controller_1.isNonEvmChainId)(quoteResponse.quote.srcChainId)) {
@@ -897,10 +909,11 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
897
909
  * @param params.quoteResponse - Quote carrying intent data
898
910
  * @param params.signature - Hex signature produced by eth_signTypedData_v4
899
911
  * @param params.accountAddress - The EOA submitting the order
912
+ * @param params.location - The entry point from which the user initiated the swap or bridge
900
913
  * @returns A lightweight TransactionMeta-like object for history linking
901
914
  */
902
915
  this.submitIntent = async (params) => {
903
- const { quoteResponse, signature, accountAddress } = params;
916
+ const { quoteResponse, signature, accountAddress, location } = params;
904
917
  this.messenger.call('BridgeController:stopPollingForQuotes', bridge_controller_1.AbortReason.TransactionSubmitted);
905
918
  // Build pre-confirmation properties for error tracking parity with submitTx
906
919
  const account = __classPrivateFieldGet(this, _BridgeStatusController_instances, "m", _BridgeStatusController_getMultichainSelectedAccount).call(this, accountAddress);
@@ -1000,6 +1013,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
1000
1013
  isStxEnabled: false,
1001
1014
  approvalTxId,
1002
1015
  startTime,
1016
+ location,
1003
1017
  });
1004
1018
  // Start polling using the orderId key to route to intent manager
1005
1019
  __classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, bridgeHistoryKey);
@@ -1014,6 +1028,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
1014
1028
  __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Failed, undefined, {
1015
1029
  error_message: error?.message,
1016
1030
  ...preConfirmationProperties,
1031
+ location: location ?? bridge_controller_1.MetaMetricsSwapsEventSource.MainView,
1017
1032
  });
1018
1033
  throw error;
1019
1034
  }
@@ -1030,26 +1045,32 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
1030
1045
  action_type: bridge_controller_1.MetricsActionType.SWAPBRIDGE_V1,
1031
1046
  ...(eventProperties ?? {}),
1032
1047
  };
1048
+ // The messenger.call for trackUnifiedSwapBridgeEvent is generic but TypeScript
1049
+ // can't narrow EventName within this method's body, so we use `any` for the
1050
+ // properties argument. The real type safety comes from the external call sites.
1051
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1052
+ const callTrack = (properties) => this.messenger.call('BridgeController:trackUnifiedSwapBridgeEvent', eventName, properties);
1033
1053
  // This will publish events for PERPS dropped tx failures as well
1034
1054
  if (!txMetaId) {
1035
- this.messenger.call('BridgeController:trackUnifiedSwapBridgeEvent', eventName, baseProperties);
1055
+ callTrack(baseProperties);
1036
1056
  return;
1037
1057
  }
1038
1058
  const historyItem = this.state.txHistory[txMetaId];
1039
1059
  if (!historyItem) {
1040
- this.messenger.call('BridgeController:trackUnifiedSwapBridgeEvent', eventName, eventProperties ?? {});
1060
+ callTrack(eventProperties ?? {});
1041
1061
  return;
1042
1062
  }
1043
1063
  const requestParamProperties = (0, metrics_1.getRequestParamFromHistory)(historyItem);
1044
1064
  // Always publish StatusValidationFailed event, regardless of featureId
1045
1065
  if (eventName === bridge_controller_1.UnifiedSwapBridgeEventName.StatusValidationFailed) {
1046
- this.messenger.call('BridgeController:trackUnifiedSwapBridgeEvent', eventName, {
1066
+ callTrack({
1047
1067
  ...baseProperties,
1048
1068
  chain_id_source: requestParamProperties.chain_id_source,
1049
1069
  chain_id_destination: requestParamProperties.chain_id_destination,
1050
1070
  token_address_source: requestParamProperties.token_address_source,
1051
1071
  token_address_destination: requestParamProperties.token_address_destination,
1052
1072
  refresh_count: historyItem.attempts?.counter ?? 0,
1073
+ location: historyItem.location ?? bridge_controller_1.MetaMetricsSwapsEventSource.MainView,
1053
1074
  });
1054
1075
  return;
1055
1076
  }
@@ -1069,8 +1090,9 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
1069
1090
  ...(0, metrics_1.getTxStatusesFromHistory)(historyItem),
1070
1091
  ...(0, metrics_1.getFinalizedTxProperties)(historyItem, txMeta, approvalTxMeta),
1071
1092
  ...(0, metrics_1.getPriceImpactFromQuote)(historyItem.quote),
1093
+ location: historyItem.location ?? bridge_controller_1.MetaMetricsSwapsEventSource.MainView,
1072
1094
  };
1073
- this.messenger.call('BridgeController:trackUnifiedSwapBridgeEvent', eventName, requiredEventProperties);
1095
+ callTrack(requiredEventProperties);
1074
1096
  });
1075
1097
  __classPrivateFieldSet(this, _BridgeStatusController_clientId, clientId, "f");
1076
1098
  __classPrivateFieldSet(this, _BridgeStatusController_fetchFn, fetchFn, "f");
@@ -1122,7 +1144,11 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
1122
1144
  else if (actionId && this.state.txHistory[actionId]) {
1123
1145
  historyKey = actionId;
1124
1146
  }
1125
- __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Failed, historyKey ?? txMetaId, (0, metrics_1.getEVMTxPropertiesFromTransactionMeta)(transactionMeta));
1147
+ const historyLocation = this.state.txHistory[historyKey ?? txMetaId]?.location;
1148
+ __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Failed, historyKey ?? txMetaId, {
1149
+ ...(0, metrics_1.getEVMTxPropertiesFromTransactionMeta)(transactionMeta),
1150
+ location: historyLocation ?? bridge_controller_1.MetaMetricsSwapsEventSource.MainView,
1151
+ });
1126
1152
  }
1127
1153
  }
1128
1154
  });