Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

chore: add optional abtest property event for swap events#8007

Merged
sahar-fehri merged 5 commits intomain from
fix/add-optional-abtest-context-for-tookendetails
Feb 25, 2026
Merged

chore: add optional abtest property event for swap events #8007
sahar-fehri merged 5 commits intomain from
fix/add-optional-abtest-context-for-tookendetails

Conversation

@sahar-fehri
Copy link
Contributor

@sahar-fehri sahar-fehri commented Feb 20, 2026
edited by cursor bot
Loading

Explanation

Adds optional ab_tests context to swap/bridge metrics events, allowing attribution to specific A/B test experiments

References

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Low Risk
Primarily adds optional metadata fields and propagation for analytics; behavioral changes are limited to event payload composition and should not affect transaction execution.

Overview
Adds optional A/B test attribution to Unified Swap/Bridge metrics by introducing ab_tests on bridge-controller event context/types and an abTests field on bridge-status-controller history items.

Bridge Status flows (startPollingForBridgeTxStatus, submitTx, submitIntent) now accept/propagate abTests, persist it in txHistory, and #trackUnifiedSwapBridgeEvent resolves ab_tests from either the call-site properties or stored history before emitting events; getPreConfirmationPropertiesFromQuote also conditionally includes ab_tests. Includes a unit test to verify ab_tests is pulled from history for tracked failure events, and updates both packages’ changelogs.

Written by Cursor Bugbot for commit 5d63280. This will update automatically on new commits. Configure here.

@sahar-fehri sahar-fehri marked this pull request as ready for review February 24, 2026 13:22
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

@sahar-fehri sahar-fehri added this pull request to the merge queue Feb 25, 2026
Merged via the queue into main with commit 539de20 Feb 25, 2026
310 checks passed
@sahar-fehri sahar-fehri deleted the fix/add-optional-abtest-context-for-tookendetails branch February 25, 2026 15:04
github-merge-queue bot pushed a commit to MetaMask/metamask-mobile that referenced this pull request Feb 25, 2026
...6354)
## **Description**
Core PR related: MetaMask/core#8007
The Token Details page is running an A/B test (`tokenDetailsV2AbTest`)
that compares a control layout vs. a treatment layout for action buttons
(Swap, buy, sell, long, short). To make conversion measurement easier,
we need to know whether users who **completed** a swap or perps trade
were in the control or treatment group.
Currently on `main`, only page-level view events carry the `ab_tests`
property. Completion events (swap confirmed, perps trade executed) do
not.
### What this PR does
**1. Swaps: Thread `ab_tests` through `BridgeStatusController` (via
patch)**
The `ab_tests` context is read from the Redux `bridge` slice in
`useSubmitBridgeTx` and passed through to
`BridgeStatusController.submitTx` / `submitIntent`.
**2. Perps: Thread `ab_tests` through `OrderParams.trackingData`**
The `ab_tests` context (already available in `PerpsOrderView` via
navigation params) is passed through the existing `trackingData`
mechanism to `TradingService.#trackOrderResult`, which includes it in
`PERPS_TRADE_TRANSACTION` events.
### Events carrying `ab_tests` — before vs. after
#### Already on `main` (no changes needed)
| Event | Flow | Where |
|-------|------|-------|
| `SWAP_PAGE_VIEWED` | Swaps | `BridgeView` reads from Redux
`abTestContext` |
| `PERPS_SCREEN_VIEWED` | Perps | `PerpsOrderView` reads from route
params |
#### New in this PR
| Event | Flow | Where added |
|-------|------|-------------|
| `Unified SwapBridge Submitted` | Swaps |
`BridgeStatusController.submitTx` / `submitIntent` |
| `Unified SwapBridge Completed` | Swaps | `BridgeStatusController`
history lookup |
| `Unified SwapBridge Failed` | Swaps | `BridgeStatusController` history
lookup |
| `Unified SwapBridge Polling Status Updated` | Swaps |
`BridgeStatusController` history lookup |
| `PERPS_TRADE_TRANSACTION` (status: `executed`) | Perps |
`TradingService.#trackOrderResult` |
| `PERPS_TRADE_TRANSACTION` (status: `failed`) | Perps |
`TradingService.#trackOrderResult` |
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: null
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
 Scenario: user [verb for user action]
 Given [describe expected initial app state]
 When user [verb for user action]
 Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Touches analytics event schemas and patches upstream bridge
controllers; risk is mainly around event payload compatibility and
making sure new optional fields don’t break consumers or alter queue
processing behavior.
> 
> **Overview**
> Threads optional **A/B test context** (`ab_tests`) into swap/bridge
and perps *completion* analytics so experiment attribution is available
beyond page-view events.
> 
> For swaps/bridge, `useSubmitBridgeTx` now reads `abTestContext` from
the Redux bridge slice and passes it through intent signing
(`handleIntentTransaction`) and
`BridgeStatusController.submitTx`/`submitIntent`; patched core
controllers persist `abTests` in tx history and automatically attach
`ab_tests` to unified swap/bridge events
(submitted/completed/failed/status updates) when present.
> 
> For perps, `PerpsOrderView` injects the token-details layout variant
into `OrderParams.trackingData.abTests`, `TradingService` emits it on
`PERPS_TRADE_TRANSACTION` events, and perps analytics typing/constants
are updated to allow/standardize the `ab_tests` payload. Separately, the
analytics queue now re-drains if new operations were enqueued during a
processing batch to avoid leaving events stuck.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
58d0789. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
runway-github bot added a commit to MetaMask/metamask-mobile that referenced this pull request Feb 25, 2026
#26354)
## **Description**
Core PR related: MetaMask/core#8007
The Token Details page is running an A/B test (`tokenDetailsV2AbTest`)
that compares a control layout vs. a treatment layout for action buttons
(Swap, buy, sell, long, short). To make conversion measurement easier,
we need to know whether users who **completed** a swap or perps trade
were in the control or treatment group.
Currently on `main`, only page-level view events carry the `ab_tests`
property. Completion events (swap confirmed, perps trade executed) do
not.
### What this PR does
**1. Swaps: Thread `ab_tests` through `BridgeStatusController` (via
patch)**
The `ab_tests` context is read from the Redux `bridge` slice in
`useSubmitBridgeTx` and passed through to
`BridgeStatusController.submitTx` / `submitIntent`.
**2. Perps: Thread `ab_tests` through `OrderParams.trackingData`**
The `ab_tests` context (already available in `PerpsOrderView` via
navigation params) is passed through the existing `trackingData`
mechanism to `TradingService.#trackOrderResult`, which includes it in
`PERPS_TRADE_TRANSACTION` events.
### Events carrying `ab_tests` — before vs. after
#### Already on `main` (no changes needed)
| Event | Flow | Where |
|-------|------|-------|
| `SWAP_PAGE_VIEWED` | Swaps | `BridgeView` reads from Redux
`abTestContext` |
| `PERPS_SCREEN_VIEWED` | Perps | `PerpsOrderView` reads from route
params |
#### New in this PR
| Event | Flow | Where added |
|-------|------|-------------|
| `Unified SwapBridge Submitted` | Swaps |
`BridgeStatusController.submitTx` / `submitIntent` |
| `Unified SwapBridge Completed` | Swaps | `BridgeStatusController`
history lookup |
| `Unified SwapBridge Failed` | Swaps | `BridgeStatusController` history
lookup |
| `Unified SwapBridge Polling Status Updated` | Swaps |
`BridgeStatusController` history lookup |
| `PERPS_TRADE_TRANSACTION` (status: `executed`) | Perps |
`TradingService.#trackOrderResult` |
| `PERPS_TRADE_TRANSACTION` (status: `failed`) | Perps |
`TradingService.#trackOrderResult` |
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: null
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
 Scenario: user [verb for user action]
 Given [describe expected initial app state]
 When user [verb for user action]
 Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Touches analytics event schemas and patches upstream bridge
controllers; risk is mainly around event payload compatibility and
making sure new optional fields don’t break consumers or alter queue
processing behavior.
> 
> **Overview**
> Threads optional **A/B test context** (`ab_tests`) into swap/bridge
and perps *completion* analytics so experiment attribution is available
beyond page-view events.
> 
> For swaps/bridge, `useSubmitBridgeTx` now reads `abTestContext` from
the Redux bridge slice and passes it through intent signing
(`handleIntentTransaction`) and
`BridgeStatusController.submitTx`/`submitIntent`; patched core
controllers persist `abTests` in tx history and automatically attach
`ab_tests` to unified swap/bridge events
(submitted/completed/failed/status updates) when present.
> 
> For perps, `PerpsOrderView` injects the token-details layout variant
into `OrderParams.trackingData.abTests`, `TradingService` emits it on
`PERPS_TRADE_TRANSACTION` events, and perps analytics typing/constants
are updated to allow/standardize the `ab_tests` payload. Separately, the
analytics queue now re-drains if new operations were enqueued during a
processing batch to avoid leaving events stuck.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
58d0789. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
runway-github bot added a commit to MetaMask/metamask-mobile that referenced this pull request Feb 25, 2026
#26354)
## **Description**
Core PR related: MetaMask/core#8007
The Token Details page is running an A/B test (`tokenDetailsV2AbTest`)
that compares a control layout vs. a treatment layout for action buttons
(Swap, buy, sell, long, short). To make conversion measurement easier,
we need to know whether users who **completed** a swap or perps trade
were in the control or treatment group.
Currently on `main`, only page-level view events carry the `ab_tests`
property. Completion events (swap confirmed, perps trade executed) do
not.
### What this PR does
**1. Swaps: Thread `ab_tests` through `BridgeStatusController` (via
patch)**
The `ab_tests` context is read from the Redux `bridge` slice in
`useSubmitBridgeTx` and passed through to
`BridgeStatusController.submitTx` / `submitIntent`.
**2. Perps: Thread `ab_tests` through `OrderParams.trackingData`**
The `ab_tests` context (already available in `PerpsOrderView` via
navigation params) is passed through the existing `trackingData`
mechanism to `TradingService.#trackOrderResult`, which includes it in
`PERPS_TRADE_TRANSACTION` events.
### Events carrying `ab_tests` — before vs. after
#### Already on `main` (no changes needed)
| Event | Flow | Where |
|-------|------|-------|
| `SWAP_PAGE_VIEWED` | Swaps | `BridgeView` reads from Redux
`abTestContext` |
| `PERPS_SCREEN_VIEWED` | Perps | `PerpsOrderView` reads from route
params |
#### New in this PR
| Event | Flow | Where added |
|-------|------|-------------|
| `Unified SwapBridge Submitted` | Swaps |
`BridgeStatusController.submitTx` / `submitIntent` |
| `Unified SwapBridge Completed` | Swaps | `BridgeStatusController`
history lookup |
| `Unified SwapBridge Failed` | Swaps | `BridgeStatusController` history
lookup |
| `Unified SwapBridge Polling Status Updated` | Swaps |
`BridgeStatusController` history lookup |
| `PERPS_TRADE_TRANSACTION` (status: `executed`) | Perps |
`TradingService.#trackOrderResult` |
| `PERPS_TRADE_TRANSACTION` (status: `failed`) | Perps |
`TradingService.#trackOrderResult` |
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: null
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
 Scenario: user [verb for user action]
 Given [describe expected initial app state]
 When user [verb for user action]
 Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Touches analytics event schemas and patches upstream bridge
controllers; risk is mainly around event payload compatibility and
making sure new optional fields don’t break consumers or alter queue
processing behavior.
> 
> **Overview**
> Threads optional **A/B test context** (`ab_tests`) into swap/bridge
and perps *completion* analytics so experiment attribution is available
beyond page-view events.
> 
> For swaps/bridge, `useSubmitBridgeTx` now reads `abTestContext` from
the Redux bridge slice and passes it through intent signing
(`handleIntentTransaction`) and
`BridgeStatusController.submitTx`/`submitIntent`; patched core
controllers persist `abTests` in tx history and automatically attach
`ab_tests` to unified swap/bridge events
(submitted/completed/failed/status updates) when present.
> 
> For perps, `PerpsOrderView` injects the token-details layout variant
into `OrderParams.trackingData.abTests`, `TradingService` emits it on
`PERPS_TRADE_TRANSACTION` events, and perps analytics typing/constants
are updated to allow/standardize the `ab_tests` payload. Separately, the
analytics queue now re-drains if new operations were enqueued during a
processing batch to avoid leaving events stuck.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
58d0789. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
runway-github bot added a commit to MetaMask/metamask-mobile that referenced this pull request Feb 25, 2026
#26354)
## **Description**
Core PR related: MetaMask/core#8007
The Token Details page is running an A/B test (`tokenDetailsV2AbTest`)
that compares a control layout vs. a treatment layout for action buttons
(Swap, buy, sell, long, short). To make conversion measurement easier,
we need to know whether users who **completed** a swap or perps trade
were in the control or treatment group.
Currently on `main`, only page-level view events carry the `ab_tests`
property. Completion events (swap confirmed, perps trade executed) do
not.
### What this PR does
**1. Swaps: Thread `ab_tests` through `BridgeStatusController` (via
patch)**
The `ab_tests` context is read from the Redux `bridge` slice in
`useSubmitBridgeTx` and passed through to
`BridgeStatusController.submitTx` / `submitIntent`.
**2. Perps: Thread `ab_tests` through `OrderParams.trackingData`**
The `ab_tests` context (already available in `PerpsOrderView` via
navigation params) is passed through the existing `trackingData`
mechanism to `TradingService.#trackOrderResult`, which includes it in
`PERPS_TRADE_TRANSACTION` events.
### Events carrying `ab_tests` — before vs. after
#### Already on `main` (no changes needed)
| Event | Flow | Where |
|-------|------|-------|
| `SWAP_PAGE_VIEWED` | Swaps | `BridgeView` reads from Redux
`abTestContext` |
| `PERPS_SCREEN_VIEWED` | Perps | `PerpsOrderView` reads from route
params |
#### New in this PR
| Event | Flow | Where added |
|-------|------|-------------|
| `Unified SwapBridge Submitted` | Swaps |
`BridgeStatusController.submitTx` / `submitIntent` |
| `Unified SwapBridge Completed` | Swaps | `BridgeStatusController`
history lookup |
| `Unified SwapBridge Failed` | Swaps | `BridgeStatusController` history
lookup |
| `Unified SwapBridge Polling Status Updated` | Swaps |
`BridgeStatusController` history lookup |
| `PERPS_TRADE_TRANSACTION` (status: `executed`) | Perps |
`TradingService.#trackOrderResult` |
| `PERPS_TRADE_TRANSACTION` (status: `failed`) | Perps |
`TradingService.#trackOrderResult` |
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: null
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
 Scenario: user [verb for user action]
 Given [describe expected initial app state]
 When user [verb for user action]
 Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Touches analytics event schemas and patches upstream bridge
controllers; risk is mainly around event payload compatibility and
making sure new optional fields don’t break consumers or alter queue
processing behavior.
> 
> **Overview**
> Threads optional **A/B test context** (`ab_tests`) into swap/bridge
and perps *completion* analytics so experiment attribution is available
beyond page-view events.
> 
> For swaps/bridge, `useSubmitBridgeTx` now reads `abTestContext` from
the Redux bridge slice and passes it through intent signing
(`handleIntentTransaction`) and
`BridgeStatusController.submitTx`/`submitIntent`; patched core
controllers persist `abTests` in tx history and automatically attach
`ab_tests` to unified swap/bridge events
(submitted/completed/failed/status updates) when present.
> 
> For perps, `PerpsOrderView` injects the token-details layout variant
into `OrderParams.trackingData.abTests`, `TradingService` emits it on
`PERPS_TRADE_TRANSACTION` events, and perps analytics typing/constants
are updated to allow/standardize the `ab_tests` payload. Separately, the
analytics queue now re-drains if new operations were enqueued during a
processing batch to avoid leaving events stuck.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
58d0789. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
runway-github bot added a commit to MetaMask/metamask-mobile that referenced this pull request Feb 25, 2026
#26354)
## **Description**
Core PR related: MetaMask/core#8007
The Token Details page is running an A/B test (`tokenDetailsV2AbTest`)
that compares a control layout vs. a treatment layout for action buttons
(Swap, buy, sell, long, short). To make conversion measurement easier,
we need to know whether users who **completed** a swap or perps trade
were in the control or treatment group.
Currently on `main`, only page-level view events carry the `ab_tests`
property. Completion events (swap confirmed, perps trade executed) do
not.
### What this PR does
**1. Swaps: Thread `ab_tests` through `BridgeStatusController` (via
patch)**
The `ab_tests` context is read from the Redux `bridge` slice in
`useSubmitBridgeTx` and passed through to
`BridgeStatusController.submitTx` / `submitIntent`.
**2. Perps: Thread `ab_tests` through `OrderParams.trackingData`**
The `ab_tests` context (already available in `PerpsOrderView` via
navigation params) is passed through the existing `trackingData`
mechanism to `TradingService.#trackOrderResult`, which includes it in
`PERPS_TRADE_TRANSACTION` events.
### Events carrying `ab_tests` — before vs. after
#### Already on `main` (no changes needed)
| Event | Flow | Where |
|-------|------|-------|
| `SWAP_PAGE_VIEWED` | Swaps | `BridgeView` reads from Redux
`abTestContext` |
| `PERPS_SCREEN_VIEWED` | Perps | `PerpsOrderView` reads from route
params |
#### New in this PR
| Event | Flow | Where added |
|-------|------|-------------|
| `Unified SwapBridge Submitted` | Swaps |
`BridgeStatusController.submitTx` / `submitIntent` |
| `Unified SwapBridge Completed` | Swaps | `BridgeStatusController`
history lookup |
| `Unified SwapBridge Failed` | Swaps | `BridgeStatusController` history
lookup |
| `Unified SwapBridge Polling Status Updated` | Swaps |
`BridgeStatusController` history lookup |
| `PERPS_TRADE_TRANSACTION` (status: `executed`) | Perps |
`TradingService.#trackOrderResult` |
| `PERPS_TRADE_TRANSACTION` (status: `failed`) | Perps |
`TradingService.#trackOrderResult` |
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: null
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
 Scenario: user [verb for user action]
 Given [describe expected initial app state]
 When user [verb for user action]
 Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Touches analytics event schemas and patches upstream bridge
controllers; risk is mainly around event payload compatibility and
making sure new optional fields don’t break consumers or alter queue
processing behavior.
> 
> **Overview**
> Threads optional **A/B test context** (`ab_tests`) into swap/bridge
and perps *completion* analytics so experiment attribution is available
beyond page-view events.
> 
> For swaps/bridge, `useSubmitBridgeTx` now reads `abTestContext` from
the Redux bridge slice and passes it through intent signing
(`handleIntentTransaction`) and
`BridgeStatusController.submitTx`/`submitIntent`; patched core
controllers persist `abTests` in tx history and automatically attach
`ab_tests` to unified swap/bridge events
(submitted/completed/failed/status updates) when present.
> 
> For perps, `PerpsOrderView` injects the token-details layout variant
into `OrderParams.trackingData.abTests`, `TradingService` emits it on
`PERPS_TRADE_TRANSACTION` events, and perps analytics typing/constants
are updated to allow/standardize the `ab_tests` payload. Separately, the
analytics queue now re-drains if new operations were enqueued during a
processing batch to avoid leaving events stuck.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
58d0789. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@cursor cursor[bot] cursor[bot] left review comments

@bfullam bfullam bfullam approved these changes

@Prithpal-Sooriya Prithpal-Sooriya Prithpal-Sooriya approved these changes

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /