@metamask-previews/bridge-status-controller 67.0.1-preview-4c504af → 67.0.1-preview-702bd3940

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,13 @@ 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 optional `abTests` property to `BridgeHistoryItem` to persist A/B test context across the transaction lifecycle ([#8007](https://github.com/MetaMask/core/pull/8007))
13
+ - Added optional `abTests` parameter to `StartPollingForBridgeTxStatusArgs` ([#8007](https://github.com/MetaMask/core/pull/8007))
14
+ - Added optional `abTests` parameter to `submitTx` and `submitIntent` methods for A/B test experiment attribution ([#8007](https://github.com/MetaMask/core/pull/8007))
15
+ - `trackUnifiedSwapBridgeEvent` now resolves `ab_tests` from event properties or transaction history and includes it in emitted events ([#8007](https://github.com/MetaMask/core/pull/8007))
16
+
10
17
  ### Changed
11
18
 
12
19
  - Bump `@metamask/bridge-controller` from `^67.1.1` to `^67.2.0` ([#8024](https://github.com/MetaMask/core/pull/8024))
@@ -207,7 +207,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
207
207
  });
208
208
  });
209
209
  _BridgeStatusController_addTxToHistory.set(this, (startPollingForBridgeTxStatusArgs, actionId) => {
210
- const { bridgeTxMeta, statusRequest, quoteResponse, startTime, slippagePercentage, initialDestAssetBalance, targetContractAddress, approvalTxId, isStxEnabled, location, accountAddress: selectedAddress, } = startPollingForBridgeTxStatusArgs;
210
+ const { bridgeTxMeta, statusRequest, quoteResponse, startTime, slippagePercentage, initialDestAssetBalance, targetContractAddress, approvalTxId, isStxEnabled, location, abTests, accountAddress: selectedAddress, } = startPollingForBridgeTxStatusArgs;
211
211
  // Determine the key for this history item:
212
212
  // - For pre-submission (non-batch EVM): use actionId
213
213
  // - For post-submission or other cases: use bridgeTxMeta.id
@@ -248,6 +248,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
248
248
  isStxEnabled: isStxEnabled ?? false,
249
249
  featureId: quoteResponse.featureId,
250
250
  location,
251
+ ...(abTests && { abTests }),
251
252
  };
252
253
  this.update((state) => {
253
254
  // Use actionId as key for pre-submission, or txMeta.id for post-submission
@@ -714,9 +715,10 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
714
715
  * @param isStxEnabledOnClient - Whether smart transactions are enabled on the client, for example the getSmartTransactionsEnabled selector value from the extension
715
716
  * @param quotesReceivedContext - The context for the QuotesReceived event
716
717
  * @param location - The entry point from which the user initiated the swap or bridge (e.g. Main View, Token View, Trending Explore)
718
+ * @param abTests - A/B test context to attribute events to specific experiments
717
719
  * @returns The transaction meta
718
720
  */
719
- this.submitTx = async (accountAddress, quoteResponse, isStxEnabledOnClient, quotesReceivedContext, location = bridge_controller_1.MetaMetricsSwapsEventSource.MainView) => {
721
+ this.submitTx = async (accountAddress, quoteResponse, isStxEnabledOnClient, quotesReceivedContext, location = bridge_controller_1.MetaMetricsSwapsEventSource.MainView, abTests) => {
720
722
  this.messenger.call('BridgeController:stopPollingForQuotes', bridge_controller_1.AbortReason.TransactionSubmitted,
721
723
  // If trade is submitted before all quotes are loaded, the QuotesReceived event is published
722
724
  // 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
@@ -726,7 +728,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
726
728
  throw new Error('Failed to submit cross-chain swap transaction: undefined multichain account');
727
729
  }
728
730
  const isHardwareAccount = (0, bridge_controller_1.isHardwareWallet)(selectedAccount);
729
- const preConfirmationProperties = (0, metrics_1.getPreConfirmationPropertiesFromQuote)(quoteResponse, isStxEnabledOnClient, isHardwareAccount, location);
731
+ const preConfirmationProperties = (0, metrics_1.getPreConfirmationPropertiesFromQuote)(quoteResponse, isStxEnabledOnClient, isHardwareAccount, location, abTests);
730
732
  // Emit Submitted event after submit button is clicked
731
733
  !quoteResponse.featureId &&
732
734
  __classPrivateFieldGet(this, _BridgeStatusController_trackUnifiedSwapBridgeEvent, "f").call(this, bridge_controller_1.UnifiedSwapBridgeEventName.Submitted, undefined, preConfirmationProperties);
@@ -848,6 +850,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
848
850
  startTime,
849
851
  approvalTxId,
850
852
  location,
853
+ abTests,
851
854
  }, actionId);
852
855
  // Pass txFee when gasIncluded is true to use the quote's gas fees
853
856
  // instead of re-estimating (which would fail for max native token swaps)
@@ -888,6 +891,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
888
891
  startTime,
889
892
  approvalTxId,
890
893
  location,
894
+ abTests,
891
895
  });
892
896
  }
893
897
  if ((0, bridge_controller_1.isNonEvmChainId)(quoteResponse.quote.srcChainId)) {
@@ -913,15 +917,16 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
913
917
  * @param params.signature - Hex signature produced by eth_signTypedData_v4
914
918
  * @param params.accountAddress - The EOA submitting the order
915
919
  * @param params.location - The entry point from which the user initiated the swap or bridge
920
+ * @param params.abTests - A/B test context to attribute events to specific experiments
916
921
  * @returns A lightweight TransactionMeta-like object for history linking
917
922
  */
918
923
  this.submitIntent = async (params) => {
919
- const { quoteResponse, signature, accountAddress, location } = params;
924
+ const { quoteResponse, signature, accountAddress, location, abTests } = params;
920
925
  this.messenger.call('BridgeController:stopPollingForQuotes', bridge_controller_1.AbortReason.TransactionSubmitted);
921
926
  // Build pre-confirmation properties for error tracking parity with submitTx
922
927
  const account = __classPrivateFieldGet(this, _BridgeStatusController_instances, "m", _BridgeStatusController_getMultichainSelectedAccount).call(this, accountAddress);
923
928
  const isHardwareAccount = Boolean(account) && (0, bridge_controller_1.isHardwareWallet)(account);
924
- const preConfirmationProperties = (0, metrics_1.getPreConfirmationPropertiesFromQuote)(quoteResponse, false, isHardwareAccount, location);
929
+ const preConfirmationProperties = (0, metrics_1.getPreConfirmationPropertiesFromQuote)(quoteResponse, false, isHardwareAccount, location, abTests);
925
930
  try {
926
931
  const intent = (0, transaction_1.getIntentFromQuote)(quoteResponse);
927
932
  // If backend provided an approval tx for this intent quote, submit it first (on-chain),
@@ -1017,6 +1022,7 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
1017
1022
  approvalTxId,
1018
1023
  startTime,
1019
1024
  location,
1025
+ abTests,
1020
1026
  });
1021
1027
  // Start polling using the orderId key to route to intent manager
1022
1028
  __classPrivateFieldGet(this, _BridgeStatusController_startPollingForTxId, "f").call(this, bridgeHistoryKey);
@@ -1043,12 +1049,20 @@ class BridgeStatusController extends (0, polling_controller_1.StaticIntervalPoll
1043
1049
  * @param eventProperties - The properties for the event
1044
1050
  */
1045
1051
  _BridgeStatusController_trackUnifiedSwapBridgeEvent.set(this, (eventName, txMetaId, eventProperties) => {
1052
+ const historyAbTests = txMetaId
1053
+ ? this.state.txHistory?.[txMetaId]?.abTests
1054
+ : undefined;
1055
+ const resolvedAbTests = eventProperties?.ab_tests ?? historyAbTests ?? undefined;
1046
1056
  const baseProperties = {
1047
1057
  action_type: bridge_controller_1.MetricsActionType.SWAPBRIDGE_V1,
1048
1058
  location: eventProperties?.location ??
1049
1059
  (txMetaId ? this.state.txHistory?.[txMetaId]?.location : undefined) ??
1050
1060
  bridge_controller_1.MetaMetricsSwapsEventSource.MainView,
1051
1061
  ...(eventProperties ?? {}),
1062
+ ...(resolvedAbTests &&
1063
+ Object.keys(resolvedAbTests).length > 0 && {
1064
+ ab_tests: resolvedAbTests,
1065
+ }),
1052
1066
  };
1053
1067
  // This will publish events for PERPS dropped tx failures as well
1054
1068
  if (!txMetaId) {