Skip to content

[pull] main from MetaMask:main#800

Merged
pull[bot] merged 22 commits into
Reality2byte:mainfrom
MetaMask:main
Jun 1, 2026
Merged

[pull] main from MetaMask:main#800
pull[bot] merged 22 commits into
Reality2byte:mainfrom
MetaMask:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Jun 1, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

sahar-fehri and others added 22 commits June 1, 2026 17:33
<!--
Please submit this PR as a draft initially.

Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.

In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->

## **Description**

Pass the resolved ambient price color state (`isPricePositive` and
`useAmbientColor`) from the Token Details page through to the Market
Insights and Security Trust sub-screens so the Swap/Buy footer buttons
consistently match the token details theme color (green when price is
up, orange when price is down).
Previously, navigating to Market Insights or the Security Trust page
would always render the footer buttons in the default green, ignoring
the ambient color A/B test treatment active on the parent screen.


## **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: Fixed Market Insights and Security Trust page footer
buttons not reflecting the ambient price color from the Token Details
page

## **Related issues**

Fixes:
[ASSETS-3307](https://consensyssoftware.atlassian.net/browse/ASSETS-3307)

## **Manual testing steps**

```gherkin
Feature: Ambient color consistency across Token Details sub-screens
  Scenario: Footer buttons match token details color on Market Insights
    Given the user is on the Token Details page for a token with a negative price change
    And the ambient price color A/B test is active
    And the footer buttons are orange
    When user taps the Market Insights entry card
    Then the Swap/Buy buttons on the Market Insights page should also be orange
  Scenario: Footer buttons match token details color on Security Trust
    Given the user is on the Token Details page for a token with a negative price change
    And the ambient price color A/B test is active
    And the footer buttons are orange
    When user taps the Security Trust entry card
    Then the Swap/Buy buttons on the Security Trust page should also be orange
  Scenario: Positive price direction shows green on sub-screens
    Given the user is on the Token Details page for a token with a positive price change
    And the ambient price color A/B test is active
    And the footer buttons are green
    When user navigates to Market Insights or Security Trust
    Then the Swap/Buy buttons should remain green
  Scenario: Control group unaffected
    Given the user is in the control group for the ambient price color A/B test
    When user navigates to Market Insights or Security Trust
    Then the Swap/Buy buttons should display the default green color

```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->


https://github.com/user-attachments/assets/3aff0900-edeb-4900-b2d0-4cc4f22f2610


## **Pre-merge author checklist**

<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.

Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->

- [ ] 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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->

- [ ] 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]
> **Low Risk**
> UI-only navigation prop plumbing for an existing A/B test; no auth,
payments, or data-layer changes.
> 
> **Overview**
> **Token Details** now forwards chart price direction
(`isPricePositive`) and the ambient price-color A/B flag
(`useAmbientColor`) into **Market Insights** and **Security & Trust**
navigation params and sticky footers.
> 
> From `AssetOverviewContent`, opening Market Insights includes those
fields on the route; the Security entry card passes them into
`Routes.SECURITY_TRUST`. **MarketInsightsView** and
**SecurityTrustScreen** read the params and pass them to
`TokenDetailsStickyFooter`, so Swap/Buy styling stays aligned with Token
Details (green vs orange) instead of defaulting to green on push.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
87ce159. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->



[ASSETS-3307]:
https://consensyssoftware.atlassian.net/browse/ASSETS-3307?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
<!--
Please submit this PR as a draft initially.

Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.

In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->

## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **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**
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-06-01 at 13 27 16"
src="https://github.com/user-attachments/assets/8c4aca53-104a-4c20-bd69-136130d90afd"
/>

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.

Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->

- [x] 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).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] 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.

#### Performance checks (if applicable)

- [x] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [x] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [x] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->

- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] 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]
> **Low Risk**
> Single Tailwind class on VIP splash title styling; cosmetic layout
only with no logic or data impact.
> 
> **Overview**
> Adds **6px top padding** to the VIP splash screen gradient title
styles in `VipSplashScreen` so the masked `MMPoly-Regular` headline
aligns correctly with the layout (visual fix only; no behavior or copy
changes).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
208dcdc. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…ack (#30830)

<!--
Please submit this PR as a draft initially.

Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.

In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->

## **Description**
## Summary
- Migrate `NavigationUnitTest` from `@react-navigation/stack` to
`@react-navigation/native-stack`.
- This component is a navigation API regression harness (it verifies
`useNavigationState` + `findRouteNameFromNavigatorState` still resolve
the active route correctly). It is not imported anywhere in the app and
has no active tests since the snapshot tests were removed in #29441.
- No runtime behavior change today; this aligns the harness with the
native stack navigator used elsewhere in the app.


## **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**

<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.

Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->

- [x] 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).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] 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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] 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]
> **Low Risk**
> Two-line import/API swap in an unused test-only view with no
production or test runner impact.
> 
> **Overview**
> Updates the **NavigationUnitTest** regression harness to use
`@react-navigation/native-stack` instead of `@react-navigation/stack`
(`createNativeStackNavigator` / `createStackNavigator`).
> 
> The harness still checks that `useNavigationState` and
`findRouteNameFromNavigatorState` resolve the active route name; it is
not wired into production navigation and has no active snapshot tests.
The change aligns this isolated test view with the native stack pattern
used in the rest of the app.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
8c0c485. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…te-and-add-labels`" (#30881)

Reverts #30875.

The fallback is no longer necessary, as the original issue has been
resolved and the Patroll token will eventually be removed.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> CI-only change that removes a secrets fallback; labeling jobs may fail
if token exchange regresses, with no app or security surface impact.
> 
> **Overview**
> Reverts the temporary **Patroll** (`secrets.LABEL_TOKEN`) fallback in
the **Check template and add labels** workflow.
> 
> The **Get access token** step no longer uses `continue-on-error:
true`, so a failed token exchange fails the job instead of continuing.
**`LABEL_TOKEN`** is set only from `steps.get-token.outputs.token` (the
`|| secrets.LABEL_TOKEN` fallback is removed).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
a85d70c. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
….80.0 (#30379)

<!-- CURSOR_AGENT_PR_BODY_BEGIN -->
## **Description**

Adds `Token Details Action Clicked` analytics event instrumentation for
the Token Details Page (TDP) secondary action buttons, enabling product
to track how users interact with actions beyond the primary CTA.

Segment Schema: Consensys/segment-schema#577

**What changed:**

1. **New event**: `Token Details Action Clicked` registered in
`MetaMetrics.events.ts`
2. **New enum**: `TokenDetailsAction` with values: `send`, `receive`,
`more_opened`, `remove_token`, `view_on_explorer`, `copy_token_address`
3. **New tracking hook**: `useTokenDetailsActionTracking` — accepts
token params, balance, and severity; returns a stable callback that
fires the event
4. **Instrumented components**:
- `TokenDetailsActions` — fires on Send, Receive, and More (menu open)
button presses
- `MoreTokenActionsMenu` — fires on Remove Token and View on Block
Explorer
   - `TokenDetailsList` → Copy Token Address button


**Event properties:**

| Property | Type | Description |
|---|---|---|
| `action` | enum | `send`, `receive`, `more_opened`, `remove_token`,
`view_on_explorer`, `copy_token_address` |
| `token_symbol` | string | e.g. ETH |
| `token_address` | string | Token contract address |
| `chain_id` | string | Chain ID |
| `has_balance` | boolean | Whether user holds the token |
| `severity` | string | Security classification: Verified, Benign,
Warning, Spam, Malicious |
| `source` | string | Mirrors `Token Details Opened` source enum |

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/ASSETS-3212

## **Manual testing steps**

```gherkin
Feature: Token Details Action Clicked analytics

  Scenario: user taps Send on Token Details Page
    Given user is viewing a token with balance on Token Details Page

    When user taps the Send button
    Then "Token Details Action Clicked" event fires with action="send"

  Scenario: user taps Receive on Token Details Page
    Given user is viewing a token on Token Details Page

    When user taps the Receive button
    Then "Token Details Action Clicked" event fires with action="receive"

  Scenario: user taps More menu on Token Details Page
    Given user is viewing a token on Token Details Page

    When user taps the More (⋯) button
    Then "Token Details Action Clicked" event fires with action="more_opened"

  Scenario: user taps View on Block Explorer in More menu
    Given user has opened the More menu on Token Details Page

    When user taps View on Block Explorer
    Then "Token Details Action Clicked" event fires with action="view_on_explorer"

  Scenario: user taps Remove Token in More menu
    Given user has opened the More menu for a non-native token

    When user taps Remove Token
    Then "Token Details Action Clicked" event fires with action="remove_token"

  Scenario: user copies token contract address
    Given user is viewing token details section with contract address

    When user taps the copy address button
    Then "Token Details Action Clicked" event fires with action="copy_token_address"
```

## **Screenshots/Recordings**

https://www.loom.com/share/73dce87dc6bc47b48a0d40588213c4e1

## **Pre-merge author checklist**

- [x] 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).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] 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.
<!-- CURSOR_AGENT_PR_BODY_END -->

<div><a
href="https://cursor.com/agents/bc-ba3c87c5-525c-4c40-9869-9f3a17eacea8"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>&nbsp;<a
href="https://cursor.com/background-agent?bcId=bc-ba3c87c5-525c-4c40-9869-9f3a17eacea8"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img
alt="Open in Cursor" width="131" height="28"
src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;</div>
<!--
Please submit this PR as a draft initially.

Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.

In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->

## **Description**
This PR migrates the Send flow's stack navigator
(`app/components/Views/confirmations/components/send/send.tsx`) from the
JS-based `createStackNavigator` to `@react-navigation/native-stack`.

**Why** 
The JS stack adds overhead and produces less native-feeling transitions
than the native stack used elsewhere in the migration effort. This
migration has been done in other feature teams such as card, ramp,
predict...etc

**What changed:**
1. **Native stack migration** — `createStackNavigator` →
`createNativeStackNavigator`, and `cardStyle` → `contentStyle` for the
screen background.
2. **In-body headers** — With native-stack, a custom React header
rendered by the navigator visibly lingers during the push/pop animation.
To fix this, each Send screen (`Amount`, `Recipient`, `Asset`) now
renders its own `HeaderCompactStandard` in-body (via `useSendNavbar`)
with `headerShown: false`, so the header transitions natively with the
screen content.
3. **Shared `Asset` component** — `Asset` is reused by `pay-with-modal`
(which supplies its own header), so it gained a `hideHeader` prop. The
`useSendNavbar` call is isolated in a child component
(`AssetSendHeader`) that only mounts inside the Send flow, so
`pay-with-modal` doesn't pull in `useSendNavbar`'s dependency chain.
4. **Back/Cancel fix** — Moving `useSendNavbar` from the parent `Send`
route into the nested screens meant its navigation-state lookup no
longer saw the main stack, which swapped the behavior (Back → home,
Cancel → previous screen). `useSendNavbar` now reads the parent
navigator's state, and `handleCancelPress` exits via the parent
navigator, restoring correct Back (previous step) and Close (exit flow)
behavior.

Android build:
https://github.com/MetaMask/metamask-mobile/actions/runs/26662374868
## **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: Send flow navigation (native stack)
  
Scenario: Header transitions cleanly between Send screens
    Given the user is in the Send flow
    When the user navigates from Asset to Amount to Recipient
    Then the header transitions natively with the screen
    And no previous header lingers during the animation
  
Scenario: Back button steps back within the Send flow
    Given the user is on a Send screen
    When the user taps the back button
    Then the user returns to the previous step (or exits Send correctly from the first screen)
  
Scenario: Close button exits the Send flow
    Given the user is on a Send screen
    When the user taps the close button
    Then the entire Send flow is dismissed
  
Scenario: Pay-with modal still works
    Given the user opens the "Other assets" picker from a Pay with confirmation
    Then the modal renders its own header (no duplicate Send header)
    And token selection works as before
```

## **Screenshots/Recordings**
happy path
|before|after|
|---|---|
|<img width="370" height="808" alt="send happy path before"
src="https://github.com/user-attachments/assets/41bbed29-e124-42b4-a2a6-ee2df9148726"
/>|<img width="370" height="808" alt="send happy path after"
src="https://github.com/user-attachments/assets/4953ced0-1543-41ab-a20b-3300ee491a88"
/>|

cancel path
|before|after|
|---|---|
|<img width="370" height="808" alt="send cancel before"
src="https://github.com/user-attachments/assets/3af10caf-f67f-45f1-9fb3-c006cf144c25"
/>|<img width="370" height="808" alt="send cancel after"
src="https://github.com/user-attachments/assets/d9deddff-9c8d-489d-a244-6be62444394a"
/>|

Token Selector 
|before|after|
|---|---|
|<img width="370" height="808" alt="pay with token before"
src="https://github.com/user-attachments/assets/ec6bbf54-7c82-4b48-a39e-df7c679fd60c"
/>|<img width="370" height="808" alt="token selector after"
src="https://github.com/user-attachments/assets/3a020e0f-eac5-470a-aa23-39b195c648d7"
/>|

Android

https://github.com/user-attachments/assets/ba847f25-c94e-4d39-8cda-796f07757c20


## **Pre-merge author checklist**

<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.

Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->

- [x] 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).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] 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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] 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 core Send navigation and exit paths; incorrect parent-stack
handling could mis-route users on back/close, though scope is limited to
the Send stack and shared Asset picker.
> 
> **Overview**
> The Send flow’s nested navigator is switched from **JS stack** to
**native stack**, with `headerShown: false` and **in-body**
`HeaderCompactStandard` on Amount, Recipient, and Asset (via
`useSendNavbar`) so headers animate with screen content instead of
lingering during transitions.
> 
> **Asset** gains `hideHeader` and an `AssetSendHeader` child so
**pay-with-modal** can keep its own header without duplicating Send
chrome or mounting the full navbar hook chain. **Back/close** behavior
is corrected: `useSendNavbar` reads the **parent** stack for back
navigation, and **close** calls `getParent().goBack()` to leave the
whole Send flow. Tests are updated with navbar mocks and
parent-navigation expectations.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
4f3d780. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…rest questionnaire (#30876)

## **Description**

This PR updates the onboarding interest questionnaire option cards to
use `TouchableOpacity` instead of `Pressable`.

Reason for change:
- The option cards no longer need a pressed-state style callback for
their interaction feedback.

Improvement/solution:
- Replaced the option card touch target with `TouchableOpacity` in
`OnboardingInterestQuestionnaire.tsx`.
- Simplified the `style` prop from a callback form to a static
`tw.style(...)` expression.
- Removed the `pressed` opacity condition while preserving
selection-based border and background styling.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: N/A

## **Manual testing steps**

```gherkin
Feature: onboarding interest selection card interaction

  Scenario: user selects and deselects an interest option
    Given the onboarding interest questionnaire is visible

    When user taps an unselected interest option card
    Then the card appears selected

    When user taps the same selected interest option card
    Then the card appears unselected
```

## **Screenshots/Recordings**

<!-- No visual change expected beyond removal of pressed-state opacity.
-->

### **Before**

<!-- [screenshots/recordings] -->


https://github.com/user-attachments/assets/7eac6d7a-4953-4505-99e4-6fb6bb9a7181



### **After**

<!-- [screenshots/recordings] -->


https://github.com/user-attachments/assets/3de229bf-4c5b-47cc-b15e-d0e4eb9c819a



## **Pre-merge author checklist**

- [x] 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).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] 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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **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]
> **Low Risk**
> Single-screen UI touch component swap with no changes to selection
logic, analytics, or navigation.
> 
> **Overview**
> Onboarding interest questionnaire **option cards** now use
**`TouchableOpacity`** instead of **`Pressable`**, with a static
`tw.style(...)` instead of a pressed-state style callback.
> 
> **Removed** the custom **pressed opacity** (`opacity-70`); **selected
vs unselected** border and background styling is unchanged. Toggle
behavior, test IDs, and checkbox accessibility are the same.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
214fe40. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
<!--
Please submit this PR as a draft initially.

Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.

In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->

## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **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] -->
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-06-01 at 14 30 25"
src="https://github.com/user-attachments/assets/5e91466e-2f70-471d-8b96-bd1c7d3b4df1"
/>
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-06-01 at 14 31 03"
src="https://github.com/user-attachments/assets/856c872a-30de-4ce4-8341-a93366de15f0"
/>

## **Pre-merge author checklist**

<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.

Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->

- [x] 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).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] 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.

#### Performance checks (if applicable)

- [x] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [x] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [x] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->

- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] 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]
> **Low Risk**
> Small UI/theming change on the rewards leaderboard with a focused
test; no auth, data, or payment logic.
> 
> **Overview**
> The **HyperTracker** wordmark on the perps trading campaign
leaderboard no longer stays hard-coded white. The SVG wordmark path now
uses **`currentColor`**, and **`PerpsTradingCampaignLeaderboard`**
passes **`colors.text.default`** from **`useTheme`** into
**`HyperTrackerLogo`** so the logo matches the active theme (e.g.
readable in light mode).
> 
> A unit test wraps the leaderboard in **`ThemeContext`** and asserts
the logo receives the theme text color.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
909d29e. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.

Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.

In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->

## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **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:

## **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**

<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.

Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->

- [ ] 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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->

- [ ] 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]
> **Low Risk**
> CI-only flag change for nightly iOS TestFlight; no app runtime or auth
logic affected.
> 
> **Overview**
> Nightly **iOS** `exp` and `rc` jobs now pass **`distribute_external:
true`** into `build-and-upload-to-testflight.yml`, so scheduled builds
are distributed to external TestFlight testers (still using the
**MetaMask BETA & Release Candidates** group) instead of relying on the
workflow default of internal-only upload.
> 
> Android nightly jobs are unchanged.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
c2648c5. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…URE_BLACK_PREVIEW (#30661)

## **Description**

Part of the pure-black dark mode migration (TMCU-798). When
`MM_PURE_BLACK_PREVIEW=true`, `background.default` resolves to
`#000000`, causing elevated surfaces bound to that token to collapse
into the screen background (black-on-black). This PR addresses two
design-system components plus their downstream consumers:

- `ListItemSelect` selected-row background → uses
`getElevatedSurfaceColor` shim (`background.alternative` under
pure-black dark, unchanged otherwise).
- Deprecated `Input` (and its SRP-input fork) → same shim. Bridge
`TokenInputArea` and `InputStepper` previously relied on `Input`'s
`background.default` to match the screen background and render
"invisible"; both now explicitly opt out via `backgroundColor:
importedColors.transparent` so the swap amount inputs stay flat.
- `EditMultichainAccountName` was using a raw RN `TextInput` with no
`backgroundColor`, so the field rendered as an outline-only border
against pure black. Migrated to `TextField` from
`@metamask/design-system-react-native`, which paints `background.muted`
(translucent overlay → elevated under pure black).

Net effect: elevated surfaces render correctly under pure-black, no
regressions on the Bridge/Swap amount entry, and
`EditMultichainAccountName` is now off a deprecated RN-native input.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TMCU-798

## **Manual testing steps**

```gherkin
Feature: Elevated surfaces remain visible under MM_PURE_BLACK_PREVIEW

  Scenario: ListItemSelect selected row is visibly elevated
    Given MM_PURE_BLACK_PREVIEW=true and the app is in dark mode

    When the user opens the Tokens sort bottom sheet
    Then the currently-selected sort option renders an elevated row (background.section)

  Scenario: Deprecated Input renders elevated where no parent provides elevation
    Given the same flag and theme

    When the user navigates to a screen using the deprecated Input directly (e.g. SRP input)
    Then the input fill is visibly elevated, not pure black

  Scenario: Bridge/Swap amount inputs stay flat
    Given the same flag and theme

    When the user opens the Swap screen
    Then the source and destination amount fields render flat against the screen background (no elevated rectangle around the "0")

  Scenario: EditMultichainAccountName field is visible
    Given the same flag and theme

    When the user opens Account details → Edit account name
    Then the "Account name" field renders with a visible elevated fill (DS TextField muted background)
```

## **Screenshots/Recordings**

### ListItemSelect (Shows sort but the change is the same for all
consumers

| Before | After |
|--------|-------|
|
![Before](https://github.com/user-attachments/assets/c4321a74-a64f-4271-9fd4-15b3c079d544)
|
![After](https://github.com/user-attachments/assets/166d8c53-59af-42b9-8d1f-1d7fa8924628)
|

### Input (Nothing Changes)


https://github.com/user-attachments/assets/6a2a4eb9-dddd-4476-bb84-a00009337e2a

### Migrate input from react native to design system component for edit
wallet name

| Before | After |
|--------|-------|
|
![Before](https://github.com/user-attachments/assets/3fbcbfec-30a2-4985-9152-14c34c3ae669)
|
![After](https://github.com/user-attachments/assets/8fc6b08e-86a4-44a5-895c-3894ec14813b)
|


### **Before**

`~`

### **After**

`~`

## **Pre-merge author checklist**

- [x] 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).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] 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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] 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]
> **Low Risk**
> Theme and presentation-only changes behind a preview flag; no auth,
persistence, or payment logic.
> 
> **Overview**
> Under **`MM_PURE_BLACK_PREVIEW`**, elevated UI no longer disappears on
a pure-black screen: deprecated **`Input`** and **`ListItemSelect`** now
use **`getElevatedSurfaceColor`** instead of **`background.default`**,
so fills stay visible in dark mode while other themes stay the same.
> 
> **Bridge/Swap** amount fields still look flat: **`TokenInputArea`**
and **`InputStepper`** pass **`backgroundColor: transparent`** on the
nested **`Input`** styles so the new elevated default does not draw a
box around the amount.
> 
> **Edit multichain account name** drops the raw RN **`TextInput`**
(border-only on black) for design-system **`TextField`**, with error
state and keyboard props moved into **`inputProps`**.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
e4c092d. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Wires Batch Sell final review submission using the preview Bridge
Controller and Bridge Status Controller builds.

This PR adds the required preview package configuration, allows
`BridgeStatusController` to call `BridgeController:getState`, and
introduces a Batch Sell-specific submit hook that calls
`BridgeStatusController.submitBatchSell`. The submit path passes the
list of executable recommended quote responses, matching the controller
contract for Batch Sell.

It also updates the final review modal to:

- submit via the new `useSubmitBatchSellTx` hook
- block `Sell all` until `isBatchSellTradeAvailable` is true
- use `isBatchSellTradeAvailable` directly instead of returning a
duplicate `networkFeeIsLoading` field
- toggle the existing submitting state and navigate to the Transactions
view after submit

## **Changelog**

CHANGELOG entry: Added Batch Sell submit support

## **Related issues**

Fixes:
[SWAPS-4441](https://consensyssoftware.atlassian.net/browse/SWAPS-4441)

## **Manual testing steps**

```gherkin
Feature: Batch Sell submit

  Scenario: user submits a Batch Sell transaction
    Given Batch Sell quotes have loaded on the final review screen
    And Batch Sell trades are available
    And the user has sufficient funds for gas

    When the user taps Sell all
    Then the app submits the list of recommended Batch Sell quote responses
    And the button enters the submitting state
    And the app navigates to the Transactions view after submission
```

```gherkin
Feature: Batch Sell unavailable trade state

  Scenario: Batch Sell trades are not ready
    Given the final review screen is open
    And isBatchSellTradeAvailable is false

    Then the network fee row shows its loading skeleton
    And the Sell all button is disabled
```

```gherkin
Feature: Batch Sell expired quote refresh

  Scenario: user refreshes an expired Batch Sell quote
    Given the final review screen is open
    And the quote has expired after max refresh

    When the user taps Get new quote
    Then BridgeController quote state is reset
    And fresh Batch Sell quote requests are made
```

## **Screenshots/Recordings**

### **Before**

n/a

### **After**



https://github.com/user-attachments/assets/c6d9fddc-7c51-4abc-890f-6de3b98d6105


## **Pre-merge author checklist**

- [x] 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).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] 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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **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.

## **Automated testing performed**

- `yarn jest
app/components/UI/Bridge/hooks/useSubmitBatchSellTx/useSubmitBatchSellTx.test.tsx
app/components/UI/Bridge/components/BatchSellFinalReviewModal/BatchSellFinalReviewModal.test.tsx`
- `yarn jest app/util/bridge/hooks/useSubmitBridgeTx.test.tsx
app/components/UI/Bridge/hooks/useSubmitBatchSellTx/useSubmitBatchSellTx.test.tsx
app/components/UI/Bridge/hooks/useBatchSellQuoteData/useBatchSellQuoteData.test.ts
app/components/UI/Bridge/components/BatchSellFinalReviewModal/BatchSellFinalReviewModal.test.tsx
app/components/UI/Bridge/Views/BatchSellReview/BatchSellReview.test.tsx`
- `yarn eslint` on touched Batch Sell submit/final review files
- `yarn lint:tsc`
- `git diff --check`


[SWAPS-4441]:
https://consensyssoftware.atlassian.net/browse/SWAPS-4441?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **High Risk**
> Introduces real on-chain batch submission through Bridge Status
Controller and changes when users can confirm trades; incorrect gating
or submit payloads could block or mis-route user transactions.
> 
> **Overview**
> This PR **wires end-to-end Batch Sell submission** and tightens
quote/trade readiness in the UI.
> 
> **Final review:** **Sell all** now calls a new `useSubmitBatchSellTx`
hook that forwards **recommended quote responses** to
`BridgeStatusController.submitBatchSell` (wallet, STX, destination
security). The modal toggles **submitting** state, blocks the CTA while
trades are loading or unavailable, treats **gasless** fee coverage
failures as insufficient funds, and **always navigates to Transactions**
after submit (success or error). Quote data drops `networkFeeIsLoading`
in favor of **`isBatchSellTradeAvailable` / `isBatchSellTradesLoading`**
and exposes **`recommendedQuotes`** for submit.
> 
> **Review screen:** The primary button stays **disabled while quotes
are still fetching** (even with partial row data), shows **“Searching
for best quotes”** during fetch, and keeps **Get new quote** when
expired.
> 
> **Platform:** Bumps **`@metamask/bridge-controller`** and
**`@metamask/bridge-status-controller`**, delegates
**`BridgeController:getState`** to `BridgeStatusController`, adds **BSC
USDT** and **Linea MUSD** stablecoin metadata, plus tests and copy.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
4e4859d. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…rted tokens (#30824)

<!--
Please submit this PR as a draft initially.

Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.

In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->

## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

Expands "Earn on your crypto" section of Money Home to include all
supported MM Pay tokens.

#### Changes
- Added `useMoneyDepositTokens` as single source of truth for Money
deposit payment tokens
- Remotely configurable blocklist, minimum balance, "no fee" tokens, and
sorting modes
- Wired up "Add" buttons to the Money account deposit screen 

## **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`
3. 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: Expanded "Earn on your crypto" in Money to show all MM
Pay-supported deposit tokens and start deposit with the selected token.

## **Related issues**

- Fixes:
[MUSD-830](https://consensyssoftware.atlassian.net/browse/MUSD-830)

## **Manual testing steps**

```gherkin
Feature: Money potential earnings uses MM Pay deposit tokens

  Scenario: user sees expanded eligible token list in potential earnings
    Given user opens Money Home with multiple MM Pay-supported tokens that pass filters
    When the potential earnings section renders
    Then the token rows are shown from the Money deposit token set

  Scenario: user starts deposit from token row
    Given user is on Money Home or Potential Earnings view
    When user taps a token row
    Then Money deposit flow opens with that token pre-selected

  Scenario: user starts deposit from primary CTA
    Given user is on Potential Earnings view with at least one eligible token
    When user taps "Convert"
    Then Money deposit flow opens with the first eligible token pre-selected
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->
- Token list displayed mUSD conversion eligible tokens only
- "Add" button redirected to the mUSD conversion screen
### **After**

<!-- [screenshots/recordings] -->


https://github.com/user-attachments/assets/be14f704-7829-4367-8b76-cd4b396e6a4b

## **Pre-merge author checklist**

<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.

Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->

- [x] 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).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] 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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->

- [ ] 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.

<!-- Generated with the help of the pr-description AI skill -->


[MUSD-830]:
https://consensyssoftware.atlassian.net/browse/MUSD-830?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes which tokens users can fund Money from and switches the
primary action from mUSD conversion to deposit initiation; mitigated by
feature flags, blocklists, and extensive unit tests but still
user-facing payment flow logic.
> 
> **Overview**
> **Earn on your crypto** on Money Home and Potential Earnings now uses
**MM Pay–eligible deposit tokens** instead of the narrower mUSD
conversion token list.
> 
> A new **`useMoneyDepositTokens`** hook centralizes which wallet tokens
appear: MM Pay blocklist, Money-specific blocklist, minimum fiat balance
(remote/env), optional **no-fee** token lists, and sort modes
(`fiatBalanceDesc` vs **no-fee first**). **Add/Convert** actions call
**`initiateDeposit`** with a **preferred payment token** rather than
**`initiateCustomConversion`**.
> 
> **No fee** badges on token rows come from configurable
**`isNoFeeToken`** (replacing hardcoded stablecoin symbols). New remote
flags and `.js.env` fallbacks back the blocklist, no-fee map, min
balance, and sort mode.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
9b092ab. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Showcase of the transitions between views 👇 


https://github.com/user-attachments/assets/67300465-117f-4168-9e66-67e9a996fe37


QuickBuy screens previously swapped instantly. This PR animates the
screen change inside `QuickBuyRoot` with a direction-aware slide + fade:

- **Forward** (going deeper, e.g. `amount -> payWith`, `quoteDetails ->
selectQuote`): the new screen slides in from the right and fades in
while the old screen slides out to the left and fades out.
- **Back** (going shallower): the motion is mirrored.

Direction is derived from a per-screen depth map (`SCREEN_DEPTH`) and
stored in a reanimated shared value that the `entering`/`exiting`
worklets read lazily, so both the entering (new) and exiting (old) views
use the direction computed at navigation time rather than a stale value.
The initial screen does not animate when the sheet first opens, and the
content container keeps its locked height so the bottom sheet does not
jump during transitions.

Motion reuses the existing `AnimationDuration.Fast` (150ms) token from
`@metamask/design-tokens`. The navigation `setActiveScreen` is now a
thin `(screen) => void` wrapper that computes direction before updating
state, so all existing call sites are unchanged.

## **Changelog**

CHANGELOG entry: Animates transitions between views in the Quick Buy
bottom sheet

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: QuickBuy screen transitions

  Scenario: user navigates forward through QuickBuy screens
    Given the QuickBuy bottom sheet is open on the amount screen
    When the user taps an action that opens a deeper screen (e.g. Pay with, or the rate to view quote details)
    Then the new screen slides in from the right and fades in while the previous screen slides out to the left

  Scenario: user navigates back
    Given the user is on a deeper QuickBuy screen
    When the user taps back
    Then the previous screen slides in from the left and fades in while the current screen slides out to the right

  Scenario: sheet opens without an awkward enter animation
    Given QuickBuy is triggered from the Buy button
    When the bottom sheet opens
    Then the amount screen appears without a slide/fade enter animation
```

## **Screenshots/Recordings**

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] 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).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] 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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **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.

Made with [Cursor](https://cursor.com)


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> UI-only Quick Buy navigation and animation; trade/confirm logic is
unchanged aside from routing through navigateToScreen.
> 
> **Overview**
> Quick Buy bottom sheet screens no longer swap instantly:
**`QuickBuyRoot`** wraps the active screen in a keyed
**`Animated.View`** with Reanimated **enter/exit** slide + fade, using a
new **`transitions`** module (`SCREEN_DEPTH`, shared direction,
`makeScreenTransitions`) and **`AnimationDuration.Fast`**.
> 
> **Forward** vs **back** motion follows depth (deeper vs shallower);
same-depth moves (e.g. `payWith` ↔ `quoteDetails`) use forward-style
animation. Direction is set in **`navigateToScreen`** before state
updates and read lazily in worklets so entering and exiting views stay
in sync. The **first** screen when the sheet opens does **not**
enter-animate; locked container height behavior is unchanged.
> 
> Context **`setActiveScreen`** is typed as **`(screen) => void`**
(still only screen-name calls from existing sites). Unit tests cover
transition math and root navigation probes.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
6ba1ab5. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description**

Implements the `Token Details Closed` analytics event to track when and
how users leave the Token Details page. The event captures `exit_action`
(how they left) and `time_on_screen_ms` (how long they stayed).

### Event payload

```json
{
  "chain_id": "0x1",
  "token_symbol": "DAI",
  "token_address": "0x6b17...",
  "exit_action": "back_navigation | cta_clicked | app_backgrounded",
  "time_on_screen_ms": 12345
}
```
## **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: Added token details closed event

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/ASSETS-3292
Related: Consensys/segment-schema#589

## **Manual testing steps**

```gherkin
Feature: Token Details Closed event tracking

**Scenario: user navigates back from token details**
Given the user is viewing the Token Details page
When user presses the back button
Then a "Token Details Closed" event is emitted with exit_action "back_navigation" and a valid time_on_screen_ms

**Scenario: user taps Swap CTA**
Given the user is viewing the Token Details page
When user taps the Swap button
Then a "Token Details Closed" event is emitted with exit_action "cta_clicked" and a valid time_on_screen_ms

**Scenario: user taps Buy CTA**
Given the user is viewing the Token Details page
When user taps the Buy button
Then a "Token Details Closed" event is emitted with exit_action "cta_clicked" and a valid time_on_screen_ms

**Scenario: user taps Send CTA**
Given the user is viewing the Token Details page
When user taps the Send button
Then a "Token Details Closed" event is emitted with exit_action "cta_clicked" and a valid time_on_screen_ms

**Scenario: user taps Long/Short CTA**
Given the user is viewing the Token Details page
When user taps the Long or Short button
Then a "Token Details Closed" event is emitted with exit_action "cta_clicked" and a valid time_on_screen_ms

**Scenario: user backgrounds the app**
Given the user is viewing the Token Details page
When user backgrounds the app
Then a "Token Details Closed" event is emitted with exit_action "app_backgrounded" and a valid time_on_screen_ms

**Scenario: user returns from a CTA and then navigates back**
Given the user is viewing the Token Details page
And the user previously tapped Swap and returned
When user presses the back button
Then a "Token Details Closed" event is emitted with exit_action "back_navigation" and a fresh time_on_screen_ms (timer resets on focus)

**Scenario: user opens Receive bottom sheet (no event)**
Given the user is viewing the Token Details page
When user taps the Receive button
Then NO "Token Details Closed" event is emitted (bottom sheet overlays, does not leave page)

```

## **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**

<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.

Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->

- [ ] 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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->

- [ ] 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.


[ASSETS-3292]:
https://consensyssoftware.atlassian.net/browse/ASSETS-3292?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ




<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Analytics-only instrumentation in Token Details with tests; no auth,
payments, or transaction logic changes.
> 
> **Overview**
> Adds **`Token Details Closed`** MetaMetrics tracking when users leave
the Token Details screen, with **`exit_action`** (`back_navigation`,
`cta_clicked`, `app_backgrounded`) and **`time_on_screen_ms`**.
> 
> The route wrapper owns session state: **`beforeRemove`** for
back/stack pop, **`AppState`** only on **`background`** (not transient
**`inactive`**), and **`useFocusEffect`** cleanup when leaving via CTA
after **`cta_clicked`** is set. Returning from background resets the
timer and allows another close event. A **`firedRef`** guard prevents
duplicate emissions per session.
> 
> CTAs wire through **`onCtaClicked`** / **`onExitAction`** on Buy,
Send, sticky Swap/Buy, and Perps Long/Short. Sticky footer
**`onSwapPress`/`onBuyPress`** now run only when navigation actually
proceeds (after geo checks and security **Proceed**, not on blocked or
modal-only paths).
> 
> Tests cover AppState behavior and sticky footer callback timing.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
ef680ff. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

This change replaces `HeaderCompactStandard` (component-library) with
**`HeaderStandard`** from `@metamask/design-system-react-native` across
confirmation-related modals and sheets.

---

## **Changelog**

CHANGELOG entry: null 

---

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-698

---

## **Manual testing steps**

```gherkin
Feature: Confirmation modals use standard header

  Scenario: Account selector sheet shows standard header
    Given the user is on a transaction confirmation that supports switching accounts
    When the user opens the account selector from the confirmation UI
    Then the sheet shows a header with the expected title and a working close control

  Scenario: Pay with asset modal
    Given the user is on a confirmation that opens the pay-with token picker
    When the user opens the pay-with modal and closes it via the header
    Then the modal closes without errors and the confirmation flow remains usable

  Scenario: Gas-related modals
    Given the user can open network fee or gas fee token UI from the confirmation
    When the user opens the estimates modal or gas fee token modal and dismisses it
    Then the modal closes correctly and the underlying confirmation is unchanged

  Scenario: Tooltip and expandable detail modals
    Given a confirmation screen shows info that opens a tooltip or expandable modal
    When the user opens and closes those modals from the header
    Then content is readable and close behaves as before
```

---

## **Screenshots/Recordings**

### **Before**


### **After**


---

## **Pre-merge author checklist**

<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.

Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->

- [x] 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).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] 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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->

- [ ] 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]
> **Low Risk**
> UI-only header component migration with unchanged close handlers and
transaction logic; main regression risk is visual/layout or
accessibility on modal headers.
> 
> **Overview**
> Confirmation-related bottom sheets and modals now use
**`HeaderStandard`** from `@metamask/design-system-react-native` instead
of the temporary **`HeaderCompactStandard`** from the component library.
> 
> The swap is applied across account selection, pay-with, gas (estimates
and fee token), cancel/speedup, tooltip, and expandable flows. Existing
props (`title`, `onClose`, `closeButtonProps`) are preserved so dismiss
behavior and test IDs stay the same.
> 
> **AccountSelector** tests drop the dedicated header mock and instead
partially mock the design system (including `useTailwind`) while
spreading the real package so **`HeaderStandard`** can render in tests.
A style comment is updated to reference **`HeaderStandard`**.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
e5bb661. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description**

This PR replaces `HeaderCompactStandard` with `HeaderStandard` from
`@metamask/design-system-react-native` across several flows that
previously depended on `component-library/components-temp`.

**Reason:** Use the canonical design-system header and reduce reliance
on temporary header components.

## **Changelog**

CHANGELOG entry: null 

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-705

## **Manual testing steps**

```gherkin
Feature: Headers use design system HeaderStandard

  Scenario: Card region selector
    Given the user is in Card onboarding and opens the region selector sheet
    When they view the header and close the sheet
    Then the sheet dismisses as before

  Scenario: Network manager
    Given the user opens the networks manager bottom sheet from the wallet
    When they view the header title and tap close
    Then the sheet closes as before

  Scenario: OTA updates modal
    Given an OTA update prompt is shown
    When the user views the branded header and taps close
    Then the modal dismisses as before

  Scenario: Seed phrase info and select picker
    Given the user opens “What is a seed phrase?” from backup flow or a SelectComponent modal (e.g. settings flows using that picker)
    When they use the header close control
    Then behavior matches prior implementation

  Scenario: Pool staking learn-more and list header with search
    Given the user opens pool staking learn-more or a screen using ListHeaderWithSearch
    When they navigate back or use search as applicable
    Then navigation and layout match prior behavior
```

## **Screenshots/Recordings**

### **Before**


### **After**


## **Pre-merge author checklist**

- [x] 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).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] 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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **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]
> **Low Risk**
> Presentational header swap with preserved close/dismiss behavior; only
notable detail is OTA close testID for tests.
> 
> **Overview**
> This PR swaps the temporary **`HeaderCompactStandard`** component for
**`HeaderStandard`** from `@metamask/design-system-react-native` on
several bottom sheets and modals: card region selector, network manager,
OTA updates, seed phrase info, `SelectComponent` picker, and pool
staking learn-more.
> 
> Behavior stays the same (titles, close handlers, and dismiss flows).
The OTA modal keeps a **custom branded header** via `HeaderStandard`
children and wires **`closeButtonProps.testID`** so tests can still hit
close without a dedicated mock. **`OTAUpdatesModal.test.tsx`** drops the
old `HeaderCompactStandard` Jest mock in favor of the real design-system
header.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
e92392d. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
…30903)

<!--
Please submit this PR as a draft initially.

Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.

In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->

## **Description**

Updates Token list mUSD filtering to include check for Money hub
enablement. When Money hub is disabled mUSD is included in the Token
list.

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **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: update token list mUSD filtering to include check for
money hub enablement; when money hub is disabled mUSD is included in the
Token list.

## **Related issues**

Fixes: [MUSD-856: Can't see mUSD in the token list since Money Hub was
released](https://consensyssoftware.atlassian.net/browse/MUSD-856)

## **Manual testing steps**

```gherkin
Feature: mUSD cash section token filtering

  Scenario: user has Money Hub enabled with mUSD balance
    Given user has the Money Hub, mUSD conversion flow, and geo eligibility all enabled
    And user holds mUSD on a supported network

    When user views the homepage token list
    Then mUSD is hidden from the token list
    And mUSD is shown only in the Cash section

  Scenario: user has Money Hub disabled
    Given user has the Money Hub feature flag disabled

    When user views the homepage token list
    Then mUSD appears in the token list alongside other tokens
    And no Cash section filtering is applied
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

#### When Money Hub feature is disabled

<img width="494" height="1020" alt="image"
src="https://github.com/user-attachments/assets/204d2dd2-7bf7-4418-a6df-e825cd39ed29"
/>

<img width="494" height="1020" alt="image"
src="https://github.com/user-attachments/assets/38f11eba-51ca-41f1-8f19-c76c614c3394"
/>

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.

Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->

- [x] 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).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] 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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->

- [ ] 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]
> **Low Risk**
> UI-only feature-flag gating for token list filtering with matching
test updates; no auth, payments, or persistence changes.
> 
> **Overview**
> **mUSD** is no longer removed from homepage and wallet token lists
unless the **Money Hub** feature flag is on, in addition to the existing
mUSD conversion flow, geo eligibility, and (for the main `Tokens` list)
homepage sections checks.
> 
> The shared **Cash section** gate (`isCashSectionEnabled`) now requires
`selectMoneyHubEnabledFlag` in `Tokens`, `TokensSection`, and
`usePopularTokens`, so filtering and popular-token exclusions only run
when Cash/Money Hub is actually available. Tests and feature-flag setup
were updated to cover the three-way flag combination.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
e5c32e4. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Adds a `variant` prop to the shared `Pressable` primitive so a single
component covers the three touch-feedback models used in the app:

- `PressableVariant.Default` — dims caller subtree opacity to `0.7` on
press. Mirrors `TouchableOpacity` behaviour. Use for buttons, icon
affordances, inline tappable elements.
- `PressableVariant.Highlight` — composites `background.pressed` over
the caller's resting surface. Use for list rows / settings rows / sheet
rows.
- `PressableVariant.None` — applies no visual feedback. Use only when
the caller component already renders its own press-state styling
internally (e.g. a button that toggles its own background via
`useState(pressed)`). Without this, those callers get double feedback
after migration.

The default is `Default` (opacity) so the broader codebase migration
from `TouchableOpacity` becomes a mechanical sweep — every existing call
site keeps the visual model it already had. List-row primitives
explicitly opt into `Highlight`. Components with internal press-state
implementations opt into `None`.

Follows the MMDS const-enum pattern (`PressableVariant.X`), matching
`TextVariant`, `ButtonVariants`, etc.

Updated in this PR:
- `Pressable` and `PressableGH` primitives, including `forwardRef`
preservation and tests for the pure `pressedStyleFor` helper.
- `ListItemSelect`, `ListItemMultiSelect`, `ListItemMultiSelectButton`,
`ListItemMultiSelectWithMenuButton` — opted into
`PressableVariant.Highlight`.
- README, Storybook story, and `index.ts` exports updated.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TMCU-790

## **Manual testing steps**

```gherkin
Feature: Pressable variant feedback

  Scenario: default variant dims subtree on press
    Given a Pressable rendered without a variant prop
    When the user presses it
    Then the caller subtree opacity briefly drops to 0.7
    And no background overlay is applied

  Scenario: highlight variant composites background.pressed on press
    Given a Pressable rendered with variant={PressableVariant.Highlight}
    When the user presses it
    Then the background briefly shifts to colors.background.pressed
    And the subtree opacity is unchanged

  Scenario: DS list rows show backdrop highlight
    Given the app is open
    When the user taps a ListItemSelect / ListItemMultiSelect / multi-select row
    Then the row flashes background.pressed (no subtree dim)
    And feedback is visible in pure-black mode
```

## **Screenshots/Recordings**

### Pressable - default is dimming on press while highlight variant
behavior needs to be explicitly set


https://github.com/user-attachments/assets/e51aaf22-f868-4ecc-88fe-0de9a6f13162

 
### List Item - highlight variant behavior is explicitly set for
`ListItems` behavior is the same as `main`


https://github.com/user-attachments/assets/51e8621d-d0c4-404a-884c-a2aa188f6014


### **Before**

`~`

### **After**

`~`

## **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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->

- [ ] 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]
> **Low Risk**
> UI-only component-library press feedback; no auth, data, or payment
paths. Default variant changes global Pressable press appearance unless
callers opt into Highlight or None.
> 
> **Overview**
> Adds a **`variant`** prop to the shared **`Pressable`** /
**`PressableGH`** primitives so press feedback is explicit instead of
one global behavior. **`PressableVariant.Default`** (the default) dims
the subtree to **0.7** opacity on press, matching
**`TouchableOpacity`**-style feedback. **`PressableVariant.Highlight`**
applies **`background.pressed`** over the caller’s surface (the previous
always-on overlay model). **`PressableVariant.None`** skips built-in
feedback for callers that style press state themselves.
> 
> List-row components (**`ListItemSelect`**, **`ListItemMultiSelect`**,
and the multi-select button variants) now pass
**`PressableVariant.Highlight`** so row taps keep the backdrop highlight
pattern. Docs, Storybook (**Default** vs **Highlight**), tests for
**`pressedStyleFor`**, and **`PressableVariant`** exports are updated
accordingly.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
c8877b0. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

When Rive can't play the splash animation (corrupted file, stuck state
machine, unsupported renderer — typically low-end Android), `FoxLoader`
falls back to the static fox and forces app reveal via a timeout. Two
problems with the current behavior:

1. The timeout was 5s, which is longer than necessary on devices where
Rive will *never* play — users stare at the static fox for an avoidable
~2s.
2. The timeout fired `Logger.error`, which generates Sentry noise for
what is expected, recoverable behavior on unsupported hardware.

This PR reduces `ANIMATION_TIMEOUT_MS` from 5s → 3s and downgrades the
timeout log from `Logger.error` to `Logger.log`. The other two
`Logger.error` calls in the file (hideAsync rejection in the timeout
path; onError bail-out) are unchanged — those remain genuine failures
worth a Sentry signal.

No functional change to the fallback itself; the static fox path was
already working.

## **Changelog**


CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TMCU-717

## **Manual testing steps**

```gherkin
Feature: Splash fallback on Rive failure

  Scenario: Rive fails to play on launch
    Given a device where Rive cannot render (e.g. low-end Android, or a forced Rive onError in dev)
    When the user launches the app
    Then the static fox is shown
    And the app reveals within 3 seconds
    And no Sentry error is emitted for the timeout
```

## **Screenshots/Recordings**

`~`

### **Before**

`~`

### **After**

`~`

## **Pre-merge author checklist**

- [x] 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).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] 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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] 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]
> **Low Risk**
> Observability and timing tweak only; splash fallback behavior and
error logging for real hideAsync failures are unchanged.
> 
> **Overview**
> **FoxLoader** shortens the splash **animation timeout** from **5s to
3s** so devices where Rive never plays reveal the app sooner on the
existing static-fox fallback.
> 
> When that timeout fires and the animation never completed globally,
logging is **downgraded from `Logger.error` to `Logger.log`** so
expected unsupported-hardware cases stop creating Sentry noise;
**`hideAsync` failures** on the same path still use **`Logger.error`**.
> 
> Tests mock **`Logger.log`** and advance fake timers by **3s** to match
the new constant.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
3c756cd. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

App icons backgrounds are now pure black

## **Changelog**

CHANGELOG entry:null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TMCU-767

## **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**


https://github.com/user-attachments/assets/42e12a7d-b69a-4771-bc9e-a98e63b37b5b



https://github.com/user-attachments/assets/3a9857d1-d447-49b5-bb7b-6d5ce923f738

### **Before**



https://github.com/user-attachments/assets/a3177288-0041-42f6-ae10-7d42f97fd904


### **After**



https://github.com/user-attachments/assets/42e12a7d-b69a-4771-bc9e-a98e63b37b5b



https://github.com/user-attachments/assets/3a9857d1-d447-49b5-bb7b-6d5ce923f738



## **Pre-merge author checklist**

- [x] 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).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] 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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->

- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] 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]
> **Low Risk**
> Asset-only visual change to iOS/Android launcher icons; no auth,
networking, or runtime behavior impact.
> 
> **Overview**
> Updates **MetaMask home-screen / launcher icon assets** so their
backgrounds are **pure black (`#000000`)** instead of the previous
non-black treatment (e.g. dark gray or transparent), addressing
**TMCU-767**.
> 
> Expect changes in **native image resources**—typically iOS `AppIcon`
(and related) asset catalogs under `ios/MetaMask/Images.xcassets/` and
Android adaptive launcher layers (`ic_launcher_background` / mipmap
PNGs)—with **no application logic** changes. Visual-only: icons should
read consistently on the home screen and in app switchers after
reinstall or asset refresh.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
12e9f97. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
#30319)

<!--
Please submit this PR as a draft initially.

Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.

In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->

## **Description**

This PR adopts the breaking messenger contract introduced in
`@metamask/ramps-controller` for
[TRAM-3502](https://consensyssoftware.atlassian.net/browse/TRAM-3502),
which moves the Buy widget API call from unauthenticated to
authenticated using a bearer token sourced from
`AuthenticationController`.

**Why:** The Buy widget endpoint on the ramps API has been gated behind
authentication. Without sending an `Authorization: Bearer <token>`
header on `getBuyWidgetUrl`, mobile users will be unable to launch the
Transak buy flow.

**What changed in core (the dependency):**
- `RampsService.getBuyWidgetUrl` now fetches a bearer token via
`AuthenticationController:getBearerToken` and sends it as an
`Authorization` header.
- `RampsServiceMessenger`'s `AllowedActions` was widened from `never` to
include `AuthenticationController:getBearerToken` — i.e. consumers (this
app) **must** delegate that action into the ramps messenger or the call
will throw.
- See the core PR for the full contract change: `<link-to-core-PR>`.

**What this PR does in mobile:**
1. Bumps `@metamask/ramps-controller` to the new major version
(currently consuming the preview build
`@metamask-previews/ramps-controller@<preview-version>` while the core
PR is in review; will switch to `^14.0.0` once published).
2. Delegates `AuthenticationController:getBearerToken` into the
`RampsServiceMessenger` at the point where the messenger is constructed
in the engine/controller-init layer.
3. Surfaces the new failure modes (wallet locked / user signed out /
token fetch failure) to the Buy entry points so the user gets a usable
error rather than an unhandled rejection.

## **Changelog**

CHANGELOG entry: null

<!-- This PR has no end-user-visible UI change on the happy path. The
Buy flow behaves identically when the user is signed in; the only
user-visible difference is improved error handling on signed-out /
locked states, which is captured in the relevant feature changelog by
the entry-point change, not here. If release engineering prefers an
entry, suggested wording: "Improved Buy widget reliability by
authenticating requests to the ramps API." -->

## **Related issues**

Fixes:
[TRAM-3502](https://consensyssoftware.atlassian.net/browse/TRAM-3502)

Depends on (core): `<link-to-core-PR>` — must be merged and released to
NPM before this PR can leave draft.

## **Manual testing steps**

```gherkin
Feature: Buy widget authentication

  Scenario: Signed-in user opens the Buy widget
    Given the user is signed in and the wallet is unlocked
    And the user has selected a token that supports Transak
    When the user taps "Buy" and proceeds to the Transak provider
    Then the Buy widget URL loads successfully
    And the upstream request to the ramps API includes an "Authorization: Bearer <token>" header
    And Transak opens in the in-app browser as before

  Scenario: Wallet-locked user attempts to open the Buy widget
    Given the wallet is locked
    When the user taps "Buy" and proceeds to the Transak provider
    Then the user sees a clear error state (not a silent failure or crash)
    And no unauthenticated request is sent to the ramps API

  Scenario: Signed-out user attempts to open the Buy widget
    Given the user is signed out of profile sync / authentication
    When the user taps "Buy" and proceeds to the Transak provider
    Then the user sees a clear error state
    And no unauthenticated request is sent to the ramps API

  Scenario: Bearer token call fails transiently
    Given the AuthenticationController fails to mint a bearer token
    When the user taps "Buy" and proceeds to the Transak provider
    Then the failure is surfaced as a user-facing error
    And retrying after the underlying auth issue is resolved succeeds
```

**How to verify the Authorization header on-device:**
- Point a debugging proxy (Charles / mitmproxy) at the device.
- Trigger the Buy flow and inspect the request to
`https://on-ramp.api.cx.metamask.io/providers/<provider>/buy-widget`.
- Confirm an `Authorization: Bearer <jwt>` header is present.

## **Screenshots/Recordings**

### **Before**

<!-- Recording of Buy widget on current `main`: request to /buy-widget
has no Authorization header. -->

### **After**


https://github.com/user-attachments/assets/b45d9a6e-3534-46f1-b51f-1d42637c32d0

<!-- Recording of Buy widget on this branch: same UX, request now
includes Authorization: Bearer <token>. Plus recordings of the
locked-wallet and signed-out error states. -->

## **Pre-merge author checklist**

- [x] 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).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] 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.

#### Performance checks (if applicable)

- [x] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **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.


[TRAM-3502]:
https://consensyssoftware.atlassian.net/browse/TRAM-3502?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
[TRAM-3502]:
https://consensyssoftware.atlassian.net/browse/TRAM-3502?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Wires bearer-token access into the Buy/ramps path; mis-delegation
would break Transak buy, but changes are localized to messenger setup
and a dependency bump.
> 
> **Overview**
> Upgrades **`@metamask/ramps-controller`** to **^14.0.0** so the Buy
widget can call the ramps API with an authenticated bearer token
(required by the new controller contract).
> 
> When **`getRampsServiceMessenger`** builds the child messenger, it now
**delegates** `AuthenticationController:getBearerToken` from the root
messenger into `RampsServiceMessenger`, so `RampsService` can mint
tokens without the call failing at runtime. A unit test asserts that
delegated call returns the token from the registered handler.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
c7e989f. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Darius Costolas <10818970+meltingice1337@users.noreply.github.com>
Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
Co-authored-by: Amitabh Aggarwal <aggarwal.amitabh@gmail.com>
…l views (#30069)

## Summary

Unifies Segment funnel reporting by emitting a new MetaMetrics event
`ASSET_VIEWED` whenever any of these legacy events fire, with the **same
properties** plus:

- `trade_type`: `Predict` | `Perps` | `Swaps` (mapped from the legacy
event)
- `implementation_type`: `native` (mobile)

Legacy events are **unchanged**; `ASSET_VIEWED` is an additional
duplicate for downstream analytics.

## **Changelog**

CHANGELOG entry: refactor: update analytic events

## Implementation

| Legacy event | Trigger |
|--------------|---------|
| Predict Feed Viewed | `PredictAnalytics` (`feedViewed` /
`trackFeedViewed`) |
| Perp Screen Viewed | `usePerpsEventTracking` `track()`;
`PerpsOpenOrderCard` geo path (`useAnalytics`) |
| Unified SwapBridge Page Viewed | `useTrackSwapPageViewed` |

Shared merge helper:
`app/core/Analytics/trade-transaction-funnel/assetViewedAnalytics.ts`
(exported via `app/core/Analytics/index.ts`).

Swap-related AB test mappings include `ASSET_VIEWED` so
`enrichWithABTests` applies the same assignments as `Unified SwapBridge
Page Viewed`.

## Testing

```bash
yarn jest app/core/Analytics/trade-transaction-funnel/assetViewedAnalytics.test.ts \
  app/components/UI/Perps/hooks/usePerpsEventTracking.test.ts \
  app/components/UI/Predict/controllers/PredictAnalytics.test.ts \
  app/components/UI/Bridge/hooks/useTrackSwapPageViewed/index.test.ts \
  app/util/analytics/enrichWithABTests.test.ts
```


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Analytics-only duplication of existing events with guarded AB
enrichment and one Perps screen-type exclusion; no auth, payments, or
transaction logic changes.
> 
> **Overview**
> Introduces a unified Segment **`Asset Viewed`** event that fires **in
addition to** existing Predict, Perps, and Swaps screen-view events,
carrying the same payload plus `trade_type` (`Predict` | `Perps` |
`Swaps`) and `implementation_type: native` via
**`mergeAssetViewedProperties`**.
> 
> **Swaps:** `useTrackSwapPageViewed` now emits `ASSET_VIEWED` next to
`Unified SwapBridge Page Viewed`. Swap numpad and token-selector AB
mappings include `ASSET_VIEWED` with **`eventPropertyRequirements`** so
`enrichWithABTests` only attaches swap experiments when `trade_type` is
`Swaps`.
> 
> **Perps:** `usePerpsEventTracking` mirrors `Perp Screen Viewed` with
`ASSET_VIEWED`, except **`cancel_all_orders`** screens (avoids
mis-mapping `open_position`). Geo-block cancel flow in
**`PerpsOpenOrderCard`** also emits `ASSET_VIEWED`.
> 
> **Predict:** `PredictAnalytics` emits `ASSET_VIEWED` for **feed
viewed** and **market details opened**. Explore
**`trackExploreSectionSeeAll`** adds Predict funnel `ASSET_VIEWED` for
**`predictions_trending`** only.
> 
> Helper normalizes open-position fields to **`open_positions_count`**
on Asset Viewed. Tests and integration expectations updated accordingly.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
3e5bc2f. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Prithpal Sooriya <prithpal.sooriya@gmail.com>
Co-authored-by: Prithpal Sooriya <prithpal.sooriya@consensys.net>
@pull pull Bot locked and limited conversation to collaborators Jun 1, 2026
@pull pull Bot added the ⤵️ pull label Jun 1, 2026
@pull pull Bot merged commit a33a1ed into Reality2byte:main Jun 1, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.