Skip to content

[pull] main from MetaMask:main#739

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

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

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented May 7, 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 : )

alucardzom and others added 22 commits May 7, 2026 12:42
…r Android build (#29777)

## **Description**

INFRA-3595 Phase 3 — adds Namespace Cache Volumes integration to the
Android build and setup workflows, and fixes the GRADLE_USER_HOME path
mismatch that blocked Android builds on Namespace runners.

**Changes:**

1. **`build-android-e2e.yml`**: Make `GRADLE_USER_HOME` conditional on
`runner_provider` (`/home/runner/_work/.gradle` on Namespace vs
`/home/admin/_work/.gradle` on Cirrus). Add `nscloud-cache-action`
covering yarn, .metamask, node_modules, .yarn/cache, and Gradle
caches/wrapper. Gate all 4 `cirruslabs/cache` steps on `runner_provider
!= 'namespace'`. On Namespace, always run full build (no APK fingerprint
cache since cirruslabs/cache is skipped).

2. **`setup-node-modules.yml`**: Add `nscloud-cache-action` before
dependency install. Make `setup-node` `cache:` conditional (disabled on
Namespace). Gate `.metamask` `actions/cache` on current path.

**Both cache paths coexist for rollback safety.** When `runner_provider:
current` (default on all triggers), all ternaries collapse to prior
values — cirruslabs/cache runs, nscloud-cache-action is skipped.
Behavior is byte-identical to the base branch.

Builds on Phase 1 (PR #29716) and Phase 0 (PR #29557).

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: INFRA-3595 (parent epic INFRA-3511)
Refs: INFRA-3592 (Phase 0, PR #29557), INFRA-3593 (Phase 1, PR #29716)

## **Manual testing steps**

```gherkin
Feature: Android build on Namespace runners

  Scenario: dispatch with namespace provider — Android build succeeds
    Given the branch phase3-namespace-android
    When user runs `gh workflow run ci.yml --ref phase3-namespace-android -f runner_provider=namespace`
    Then Build Android E2E APKs succeeds on namespace-profile-metamask-android-build
    And GRADLE_USER_HOME resolves to /home/runner/_work/.gradle
    And nscloud-cache-action caches Gradle deps and yarn/node_modules
    And cirruslabs/cache steps are skipped

  Scenario: dispatch with current provider — byte-identical to base
    Given the branch phase3-namespace-android
    When user runs `gh workflow run ci.yml --ref phase3-namespace-android -f runner_provider=current`
    Then Build Android E2E APKs succeeds on Cirrus ubuntu-runner-amd64
    And GRADLE_USER_HOME resolves to /home/admin/_work/.gradle
    And cirruslabs/cache steps run as before
    And nscloud-cache-action steps are skipped

  Scenario: implicit current via PR/push trigger
    Given a push or pull_request event (no workflow_dispatch)
    Then inputs.runner_provider is undefined/empty
    And all ternaries collapse to existing behavior
```

## **Screenshots/Recordings**

### **Before**

N/A

### **After**

N/A — CI infrastructure PR, no UI surface.

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

N/A — workflow YAML only, no app code.

## **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]
> **Medium Risk**
> Moderate risk because it changes runner selection and caching behavior
across core CI/build/E2E workflows, which can impact build determinism
and job reliability. Default behavior remains `current`, but the new
`namespace` path introduces new cache tooling and environment
differences (e.g., Gradle home).
> 
> **Overview**
> Adds an opt-in `runner_provider` switch across CI, build, and E2E
workflows to route jobs to Namespace runner profiles (new labels added
to `actionlint.yaml`) instead of the existing GitHub/Cirrus runners.
> 
> When `runner_provider=namespace`, enables
`namespacelabs/nscloud-cache-action` for Yarn/`node_modules`/`.metamask`
(and Gradle caches for Android), disables existing
`actions/cache`/`cirruslabs/cache` steps where incompatible, and adjusts
Android `GRADLE_USER_HOME` to the Namespace filesystem layout. Manual
dispatch workflows (e.g., `ci.yml`, `build.yml`, Expo dev build, and E2E
regression runs) now expose `runner_provider` as an input and forward it
through reusable workflows.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
207bf39. 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: Jose Luque <jose.luque@consensys.net>
Co-authored-by: José Manuel <6741785+jluque0101@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description**

Add sort direction indicators to trending token filter buttons to
improve UX by making the current sort order immediately visible.

## **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: Adds sort icons on filter bar in trending list

## **Related issues**

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

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



https://github.com/user-attachments/assets/2b7ac0c1-fe27-4ec8-bcd3-2bcd459ce306



## **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**
> Low risk UI enhancement that only adds derived state and icon
rendering for the sort button; minimal chance of regressions outside the
Trending filter bar layout.
> 
> **Overview**
> Adds a sort-direction indicator to the Trending token list
price-change filter.
> 
> `FilterButton`/`FilterBar` now accept an optional
`iconName`/`priceChangeIconName` and render that icon before the label.
`useTokenListFilters` exposes a new `priceChangeSortDirectionIcon`
(up/down) derived from `priceChangeSortDirection`, `TokenListPageLayout`
wires it into the `FilterBar`, and tests cover the new icon mapping.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
0c6e926. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
#29122)

…Homepage section

- PredictMarketRowItem, PredictMarketCard, PredictPositionRow,
PredictActivity: Pressable → TouchableOpacity
- PredictMarketDetails (and sub-components): fix view nesting for iOS
XCUITest element lookup
- PredictDetailsChart, TimeframeSelector: align accessibility props
- PredictionsSection (Homepage): remove redundant Box wrappers, –1
native node

<!--
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**
> Primarily refactors layout/styling and view nesting to improve iOS
accessibility/XCUITest element lookup, with minor navigation and
rendering-guard tweaks; functional risk is low but UI regressions are
possible.
> 
> **Overview**
> Improves Predict and Homepage Predictions *iOS accessibility/test
reliability* by simplifying view hierarchies and reducing unnecessary
wrapper nodes (e.g., switching several layouts to direct
`TouchableOpacity` styling, removing extra `Box`/`View` nesting, and
returning `null` instead of empty containers).
> 
> Adjusts Predict Market Details header/actions composition (padding
moved into components; actions now self-wrap with bottom border/padding)
and fixes a wallet back-navigation target. Adds a new Predict E2E
selector prefix (`TRENDING_MARKET_CARD`) and extends
`PredictionsSection` tests to ensure the header and unrealized PnL row
aren’t duplicated/shown when the trending carousel renders above
positions.
> 
> Bumps build/version numbers in `bitrise.yml` and the iOS Xcode project
(`CURRENT_PROJECT_VERSION` to `4823`).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
6aa6fca. 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: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: metamaskbot <metamaskbot@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**

The `useStocksFeed` hook was passing `chainIds: ['eip155:1']` to
`useRwaTokens` when no search query was active, restricting the API
fetch to Ethereum mainnet only. The `RWATokensFullView` (full-screen
Stocks view) fetches from all RWA-supported chains (Ethereum + BNB
Chain) by default.

This mismatch caused the two views to operate on different datasets,
leading to inconsistent sort order: tokens available on BNB Chain (e.g.
Cipher Mining Ondo Tokenized) appeared at the top of the full-screen
view due to a higher 24h price change, but were completely absent from
the section widget, making a lower-ranked Ethereum token incorrectly
appear first there.

The fix removes the `chainIds` override from `useStocksFeed` so it
fetches the same combined dataset as the full-screen view. A client-side
filter is then applied to return only Ethereum mainnet tokens to the
section, preserving the intended display scope while correctly
reflecting the global sort order.

<!--
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: align data fetch on stocks

## **Related issues**

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

## **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]
> **Medium Risk**
> Moderate UI/data behavior change: alters what assets appear in
Trending sections by shifting RWA chain filtering client-side and
optionally hiding risky tokens, which could affect ordering/visibility
but not security-critical flows.
> 
> **Overview**
> Aligns the Trending *Stocks* section with the full RWA dataset by
removing the `chainIds` constraint from the `useRwaTokens` request and
instead filtering to Ethereum mainnet locally (by `assetId` CAIP prefix)
to avoid cache divergence and inconsistent sorting.
> 
> Adds an optional `hideRiskyTokens` flag to `useTokensFeed` to filter
out tokens marked `Warning`, `Spam`, or `Malicious` (keeping `Verified`,
`Benign`, and unscanned), enables it for the *Crypto movers* pills in
`NowTab`, and extends unit tests to cover the new filtering behavior.
> 
> Updates English strings so the RWA perps section/pill labels display
"Perps" instead of "Markets"/"Stocks & commodities".
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
ed1be03. 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?
-->

The new `AssetsController` is being introduced to replace most
controllers from `@metamask/assets-controllers`. This is one of many PRs
that replace direct access to legacy state with selectors that, using a
feature flag, handle the transition between the legacy state and the new
state when the flag is turned on.

## **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: https://consensyssoftware.atlassian.net/browse/ASSETS-2827

## **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).
- [ ] 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**
> Moderate risk because it changes how card token balances and fiat
values are sourced (from `Engine.context` to Redux selectors), which
could affect displayed balances/pricing if selector wiring or
feature-flagged state differs across networks.
> 
> **Overview**
> Updates `useAssetBalances` to stop reading rates/market data directly
from `Engine.context` and instead use feature-flag-aware selectors from
`selectors/assets/assets-migration` (including `allTokens`, currency
rates, token market data, and multichain conversion rates).
> 
> Adjusts `useAssetBalances.test.ts` to mock these values via
`useSelector` state (not controller state mutation), including a new
default selector state and a Solana conversion-rate test that injects
`MultichainAssetsRatesController` into the mocked Redux state.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
177704b. 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?
-->

The new `AssetsController` is being introduced to replace most
controllers from `@metamask/assets-controllers`. This is one of many PRs
that replace direct access to legacy state with selectors that, using a
feature flag, handle the transition between the legacy state and the new
state when the flag is turned on.

## **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: https://consensyssoftware.atlassian.net/browse/ASSETS-2827

## **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).
- [ ] 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**
> Updates how native balances are looked up for
`gas_insufficient_native_asset`, which could change metrics output if
address casing/normalization differs across callers. Scoped to
analytics/metrics code with test adjustments, but affects
transaction-finalized event properties.
> 
> **Overview**
> Updates gas metrics to read account balances via the
`selectAccountsByChainId` selector instead of directly accessing
`AccountTrackerController` state, aligning with the ongoing assets-state
migration.
> 
> `getNativeBalance` now resolves the sender address with
`safeToChecksumAddress` and looks up balances by checksummed key
(removing the previous `.toLowerCase()` access). Tests were updated to
use a realistic checksummed address and store balances under that exact
key.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
f71e6c6. 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**
The Transaction Finalized event may not be fired immediately so there is
a race condition between the E2E check and the timing for the event to
be fired. This PR adds a retry mechanism to want a maximum of 5s before
actually throwing the error when the event is not fired at all.

<!--
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:
https://consensys.slack.com/archives/C02U025CVU4/p1778143821257179

## **Manual testing steps**
N/A

## **Screenshots/Recordings**

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

### **Before**
N/A
<!-- [screenshots/recordings] -->

### **After**
N/A
<!-- [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**
> Low risk: test-only change that adds polling before failing when the
analytics event arrives late; no production logic is affected.
> 
> **Overview**
> Reduces flakiness in the send confirmation smoke test by **polling for
the `Transaction Finalized` MetaMetrics event** (up to 5 attempts with a
1s delay) before failing the transaction-hash validation.
> 
> Also updates the helper to import and use the `EventPayload` type for
the retried lookup.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
d151e36. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
… tests folder (#29826)

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

> Migrates test utilities away from the legacy `wdio` folder by deleting
`wdio/helpers/Accounts.js` and introducing a typed replacement
`tests/utils/Accounts.ts`, then updating affected flows/tests to import
from the new location.
> 
> Cleans up test framework remnants by removing
`tests/framework/utils/Flows.js` and updating page objects/selectors to
use app-owned test IDs (e.g., adds/uses
`SecurityPrivacyViewSelectorsIDs.DELETE_WALLET_BUTTON` and switches
Change Password confirm input to
`ChoosePasswordSelectorsIDs.CONFIRM_PASSWORD_INPUT_ID`). Also updates
swaps `QuoteView` to source `getAssetTestId` from the new selectors
module.
> 

## **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**
> Test-only refactors that change helper locations and test IDs; risk is
limited to CI test failures if selectors/IDs drift from the app UI.
> 
> **Overview**
> Migrates test utilities away from the legacy `wdio` folder by deleting
`wdio/helpers/Accounts.js`, adding a typed replacement
`tests/utils/Accounts.ts`, and updating flows/regression tests to import
it from the new location.
> 
> Removes the unused legacy `tests/framework/utils/Flows.js` helper
module.
> 
> Aligns Detox page objects with app-owned test IDs/selectors: adds
`SecurityPrivacyViewSelectorsIDs.DELETE_WALLET_BUTTON`, updates
`SecurityAndPrivacyView` to use it, switches Change Password confirm
input to `ChoosePasswordSelectorsIDs.CONFIRM_PASSWORD_INPUT_ID`, and
updates swaps `QuoteView` to import `getAssetTestId` from the new
`WalletView` selectors module.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
027d2eb. 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**
Removed sites arrows from sites tab

<!--
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: removed sites arrows from sites tab
 
## **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**
> Low risk UI-only change that removes a decorative icon; behavior and
navigation logic are unchanged.
> 
> **Overview**
> Removes the `Arrow2UpRight` icon from site rows (`SiteRowItem`) and
trending/recents tiles (`SiteTileRowItem`), simplifying the UI without
changing click handling or navigation.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
68cf003. 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**
> Low risk because changes are limited to performance test specs, but
enabling `SUBMIT_SWAP` will execute real swap confirmations and activity
assertions, which may increase test flakiness and runtime.
> 
> **Overview**
> Adds an optional “submit swap” path to the performance swap login
specs so they can go beyond quote timing and *actually confirm the swap*
when `SUBMIT_SWAP=true`.
> 
> When enabled, the tests dismiss the keypad, tap `Confirm swap`, and
validate the resulting activity via `checkSwapActivity` for both the
ETH→USDC and cross-chain ETH→SOL flows.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
60810d3. 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**

Adds a new Nightly System Tests GitHub Actions workflow
(run-system-tests.yml) that runs on a daily cron or manually, optionally
accepting pre-built BrowserStack app URLs.

The workflow builds two RC variants (clean + with pre-imported SRP),
uploads resulting APK/IPA artifacts to BrowserStack, runs Android/iOS
login and onboarding test suites via BrowserStack Local, publishes test
report artifacts, and fails the run if any platform flow fails.

## **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]
> **Medium Risk**
> Adds a new scheduled GitHub Actions workflow that builds and uploads
signed RC artifacts and runs device tests on BrowserStack, which may
affect CI load and secret usage if misconfigured.
> 
> **Overview**
> Adds a new `Nightly System Tests` GitHub Actions workflow
(`.github/workflows/run-system-tests.yml`) that runs on a daily cron or
manually, builds *clean* and *with-SRP* RC variants, uploads APK/IPA
artifacts to BrowserStack, and executes Android/iOS login + onboarding
system test suites via BrowserStack Local with report artifacts and a
failing summary gate.
> 
> Extends `builds.yml` with a new `main-rc-with-srp` build variant (RC
config plus injected `ADDITIONAL_SRP_1` and `PREDEFINED_PASSWORD`) to
support login-focused system tests, and updates `.github/CODEOWNERS` to
assign QA ownership for the new workflow.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
809f391. 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**
Fix Ondo tokens case inconsistency
<!--
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-05-07 at 11 01 09"
src="https://github.com/user-attachments/assets/3016810d-9f72-480d-b42e-bd9dbbc0690b"
/>
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-05-07 at 11 01 26"
src="https://github.com/user-attachments/assets/eebe2198-edb5-473d-a1f8-c2a5add08d6f"
/>
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-05-07 at 11 01 31"
src="https://github.com/user-attachments/assets/c7a99f25-62b6-40da-82f2-b7302a7acbb2"
/>

<!-- [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]
> **Medium Risk**
> Low-scope UI formatting change, but the new `tokenLabel` calls
`toUpperCase()` unconditionally which could throw if `tokenSymbol` is
missing/null at runtime.
> 
> **Overview**
> Normalizes token symbols shown in `OndoActivityRow` details by
uppercasing `tokenSymbol`, fixing mixed-case display (and updates the
related unit test expectation from `AAPLon` to `AAPLON`).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
f30dc80. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Adds `Home Viewed` Segment event tracking for the hub page discovery
tabs UI. Fires `interaction_type: tab_viewed` on initial mount
(Portfolio) and on every subsequent tab switch, using a stable ref-based
callback so analytics reads are never stale without causing extra
re-renders.

- New useTabViewedEvent hook encapsulates the event builder, guards
against `visitId === 0` (session not yet initialized), and exposes a
stable `trackTabViewed(name)` callback.
- `active_ab_tests` for `HOME_VIEWED` is injected automatically by the
existing analytics registry
`HUB_PAGE_DISCOVERY_TABS_AB_TEST_ANALYTICS_MAPPING`, no extra wiring
needed here.
- Full unit test coverage for both the hook and the tab switching
behavior in `HomepageDiscoveryTabs`.

## **Changelog**

CHANGELOG entry:null

## **Related issues**

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

## **Manual testing steps**

```gherkin
Feature: Hub page discovery tab analytics

  Scenario: user views the Portfolio tab on app open
    Given the hub page discovery tabs UI is enabled
    When the homepage mounts
    Then a Home Viewed event fires with name: portfolio and interaction_type: tab_viewed

  Scenario: user switches between tabs
    Given the homepage is open on the Portfolio tab
    When user taps the Perpetuals tab
    Then a Home Viewed event fires with name: perpetuals
    When user taps the Predictions tab
    Then a Home Viewed event fires with name: predictions
    When user taps the Portfolio tab
    Then a Home Viewed event fires with name: portfolio

  Scenario: user taps the already-active tab
    Given the homepage is open on any tab
    When user taps the same tab again
    Then no additional Home Viewed event fires
```

## **Screenshots/Recordings**


https://github.com/user-attachments/assets/6c34276a-1939-4b00-b200-93905de8c429

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

<!--
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**
> Low risk: adds Segment/MetaMetrics event tracking on homepage
discovery tab mount/switch with unit tests; no auth, funds, or
persistence logic changed.
> 
> **Overview**
> Adds `useTabViewedEvent` to emit `MetaMetricsEvents.HOME_VIEWED` with
`interaction_type: 'tab_viewed'` and tab name, including `entry_point`,
`app_session_id`, and `visit_number` from homepage scroll context.
> 
> Updates `HomepageDiscoveryTabs` to fire the event on initial mount
(Portfolio) and on each distinct tab switch, and extends tests to assert
the tracking is called correctly (including *not* re-firing when
re-pressing the active tab).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
53f3626. 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>
<!--
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**

3 polish fixes for the What's Happening detail view:

Dots in sync with swipe, the active dot now flips the moment the next
card crosses 50% during the drag, instead of lagging until the snap
animation settles.
Sources bottom sheet is now full-width.
Navigation to specific card index is working again.

<img height="790" alt="Simulator Screenshot - iPhone 17 Pro - 2026-05-07
at 10 46 08"
src="https://github.com/user-attachments/assets/d371241d-2a53-4221-b841-ed69220b3b54"
/>

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

- [ ] 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]
> **Medium Risk**
> Adjusts carousel scroll handling and analytics triggers, and changes
how the sources bottom sheet is presented; regressions could affect
navigation to an initial card, page indicator accuracy, or event
tracking.
> 
> **Overview**
> Improves the What’s Happening detail carousel by updating the page
indicator *live during drag* via `onScroll`, while only firing
`WHATS_HAPPENING_VIEWED` analytics on `onMomentumScrollEnd` after snap
settling.
> 
> Fixes initial-card navigation by scrolling to `initialIndex` on
`onContentSizeChange` once the content is wide enough, guarded to run
only once.
> 
> Moves the sources bottom sheet out of `WhatsHappeningExpandedCard`
into `WhatsHappeningDetailView` (card now emits `onSourcesPress` with
`articles`), enabling a full-width sheet anchored at the screen root;
tests were updated/added to cover these behaviors.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
c126348. 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?
-->

### Problem statement:

- Some networks like Monad require a [Reserve
Balance](https://docs.monad.xyz/developer-essentials/reserve-balance) to
be kept at all times in a given account.
- This constraint is usually not explicitly reflected in UX in most
wallets, but the limit is real and a tx may fail if user accounts go
below that minimum reserve. For example it is of `10 MON` for Monad.
- MetaMask Swap will always run a pre-flight simulation while fetching,
triggering an error message when trying to swap `MON` in a swap that
would put it's reserve below the `10 MON` threshold.

### Proposed solution

- Keep showing quotes to the user when it this situation (same as the
"not enough balance" situation) -> Lift this balance constraint during
pre-flight simulation by setting the `insufficientBal` parameter to
`true`.
- Display a specific Banner Alert for this specific issue, explaining
the constraint of the user.
- (nice to have) Add a `Use max available` CTA in the Alert Banner that
will prefill automatically `balance - minimumReserve` as source amount.
This solution ticks three boxes:
1. Preserves the "max" button original behavior without polluting it
with per-chain logic.
2. Avoids terrible UX where clicking on "max" would not select "max".
3. Allows the user to be informed about the constraint, and be aware of
the consequences.

## **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: Swap/Bridge to warn user if native balance will go
below a minimum threshold.

## **Related issues**

Fixes:
https://consensyssoftware.atlassian.net/browse/NEB-1113?atlOrigin=eyJpIjoiYmRkZGU5ZjE0MTRhNDM4OTgyNWZjOGJlMDU1YTliZDMiLCJwIjoiaiJ9

## **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="300" alt="Screenshot_2026-05-05-11-54-55-377_io metamask"
src="https://github.com/user-attachments/assets/cfb0e87b-a7a7-46a4-a5ed-862721090fd8"
/>

<!-- [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]
> **Medium Risk**
> Medium risk: changes swap/bridge quote-request parameters and submit
gating, which can affect quote fetching and transaction eligibility on
gas-sponsored networks (especially for native-token swaps). Logic is new
but scoped and covered by unit tests and copy additions.
> 
> **Overview**
> Adds detection for *native-token minimum reserve* constraints on
gas-sponsored EVM networks (e.g., Monad), via a new
`useInsufficientNativeReserveError` hook that computes a required
reserve and max swappable amount.
> 
> When triggered, the Bridge view shows a dedicated warning banner with
a **“Use max allowed”** CTA that pre-fills the allowable amount,
disables the confirm button (labeling it as insufficient funds), and
includes the condition in quote analytics warnings. Quote requests now
set `insufficientBal=true` when this reserve constraint is hit so quotes
can still be fetched/displayed, and tests/i18n strings are added to
cover the new behavior.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
1d06ecd. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Open orders (limit, TP, SL) on compact order rows displayed
trigger/limit prices with fixed 2 decimals. Changed
`PRICE_RANGES_MINIMAL_VIEW` to `PRICE_RANGES_UNIVERSAL` in
`PerpsCompactOrderRow` so prices use market-appropriate decimals (e.g.,
0 for BTC, 2 for mid-range, up to 6 for micro-cap tokens), matching how
market prices and expanded order cards already display.

## **Changelog**

CHANGELOG entry: Fixed open order trigger/limit prices showing only 2
decimals instead of market-appropriate precision

## **Related issues**

Fixes:
[TAT-3094](https://consensyssoftware.atlassian.net/browse/TAT-3094)

## **Manual testing steps**

```gherkin
Feature: Open order decimal precision

  Scenario: Compact order row shows market-appropriate decimals for BTC
    Given the Trading account has open BTC TP/SL orders with trigger prices > $10,000

    When user navigates to BTC market details and views compact order rows
    Then trigger prices display with 0 decimals (matching market price format)
```

## **Screenshots/Recordings**

Compact order row price formatting changed from
PRICE_RANGES_MINIMAL_VIEW (fixed 2 decimals) to PRICE_RANGES_UNIVERSAL
(market-appropriate decimals).

<table>
<tr><td colspan="2"><strong>BTC market details with order data (market
price shows 0 decimals)</strong></td></tr>
<tr>
<td align="center" width="50%"><em>Before</em><br/><img
src="https://raw.githubusercontent.com/abretonc7s/mm-mobile-farm-artifacts/main/fixes/29799/before-evidence-ac1-market-details.png"
alt="before" width="400" /></td>
<td align="center" width="50%"><em>After</em><br/><img
src="https://raw.githubusercontent.com/abretonc7s/mm-mobile-farm-artifacts/main/fixes/29799/after-ac1-market-details.png"
alt="after" width="400" /></td>
</tr>
</table>

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

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

## **Validation Recipe**

<details>
<summary>recipe.json</summary>

```json
{
  "pr": "29799",
  "title": "Open order prices use market-appropriate decimals",
  "jira": "TAT-3094",
  "acceptance_criteria": [
    "AC1: Compact order rows display trigger/limit price with market-appropriate decimals instead of fixed 2 decimals",
    "AC2: Expanded order card detail view continues to display trigger/limit price correctly (no regression)"
  ],
  "validate": {
    "static": ["yarn lint:tsc"],
    "workflow": {
      "pre_conditions": ["wallet.unlocked", "perps.feature_enabled"],
      "entry": "setup-nav-market",
      "nodes": {
        "setup-nav-market": {
          "action": "call",
          "ref": "perps/market-discovery",
          "params": { "symbol": "BTC" },
          "next": "ac1-eval-orders-exist"
        },
        "ac1-eval-orders-exist": {
          "action": "eval_async",
          "expression": "Engine.context.PerpsController.getOpenOrders().then(function(orders) { var btcOrders = orders.filter(function(o) { return o.symbol === 'BTC' && o.status === 'open'; }); var results = btcOrders.map(function(o) { var tp = parseFloat(o.triggerPrice || o.price || '0'); return { orderId: o.orderId, triggerPrice: tp, type: o.detailedOrderType }; }); return JSON.stringify({ count: btcOrders.length, orders: results }); })",
          "assert": { "operator": "gt", "field": "count", "value": 0 },
          "next": "ac1-assert-btc-price-range"
        },
        "ac1-assert-btc-price-range": {
          "action": "eval_async",
          "expression": "Engine.context.PerpsController.getOpenOrders().then(function(orders) { var btcOrders = orders.filter(function(o) { return o.symbol === 'BTC' && o.status === 'open'; }); var o = btcOrders[0]; var price = parseFloat(o.triggerPrice || o.price || '0'); var isHighPrice = price > 10000; return JSON.stringify({ price: price, isHighPrice: isHighPrice, expectedMaxDecimals: isHighPrice ? 0 : 2, detailedType: o.detailedOrderType }); })",
          "assert": { "operator": "eq", "field": "isHighPrice", "value": true },
          "next": "ac1-screenshot-market"
        },
        "ac1-screenshot-market": {
          "action": "screenshot",
          "filename": "evidence-ac1-market-details.png",
          "note": "AC1: BTC market details screen showing order data available",
          "next": "ac2-eval-expanded-uses-universal"
        },
        "ac2-eval-expanded-uses-universal": {
          "action": "eval_async",
          "expression": "Engine.context.PerpsController.getOpenOrders().then(function(orders) { var btcOrders = orders.filter(function(o) { return o.symbol === 'BTC' && o.status === 'open'; }); var results = btcOrders.map(function(o) { var price = parseFloat(o.triggerPrice || o.price || '0'); return { orderId: o.orderId, price: price, type: o.detailedOrderType, priceShouldHaveZeroDecimals: price > 10000 }; }); return JSON.stringify({ count: results.length, orders: results }); })",
          "assert": { "operator": "gt", "field": "count", "value": 0 },
          "next": "done"
        },
        "done": { "action": "end", "status": "pass" }
      }
    }
  }
}
```

</details>

## **Recipe Workflow**

<details>
<summary>workflow.mmd</summary>

```mermaid
graph TD
    setup-nav-market["setup-nav-market<br/>call perps/market-discovery"] --> ac1-eval-orders-exist
    ac1-eval-orders-exist["ac1-eval-orders-exist<br/>eval_async: BTC orders exist"] --> ac1-assert-btc-price-range
    ac1-assert-btc-price-range["ac1-assert-btc-price-range<br/>eval_async: price > 10000"] --> ac1-screenshot-market
    ac1-screenshot-market["ac1-screenshot-market<br/>screenshot"] --> ac2-eval-expanded-uses-universal
    ac2-eval-expanded-uses-universal["ac2-eval-expanded-uses-universal<br/>eval_async: order data valid"] --> done
    done["done<br/>end: pass"]
```

</details>

[TAT-3094]:
https://consensyssoftware.atlassian.net/browse/TAT-3094?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk UI-only change that alters decimal formatting for prices in
`PerpsCompactOrderRow` and updates unit tests accordingly.
> 
> **Overview**
> **Compact perps open-order rows now format trigger/limit prices with
market-appropriate precision.** `PerpsCompactOrderRow` switches
`formatPerpsFiat` from `PRICE_RANGES_MINIMAL_VIEW` to
`PRICE_RANGES_UNIVERSAL`, aligning compact rows with other perps price
displays.
> 
> Tests update the `formatUtils` mock and add an assertion that
`formatPerpsFiat` is called with `{ ranges: PRICE_RANGES_UNIVERSAL }`.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
887f158. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Two new CI workflows have been added for uploading localized messages
from releaase branches, and downloading translations onto releaase
branches.

Today we only use `main` as the source for localized messages, and all
translations go through `main` first, then get cherry-picked onto the
current RC. This process risks the translations getting out-of-sync with
the sources on the current release (since they're derived from the
localized message sources on `main`), which could cause severe
localization errors. This process is also time-consuming for the
delivery team.

These updated workflows bypass that problem completely. Translations
will always be in-sync on release branches, and we will have no
conflicts.

In the future this will run on a schedule, but it's just configured for
manual workflow dispatch for now, so that we can test it further.

## **Changelog**

CHANGELOG entry: N/A

## **Related issues**

This is adapted from an older experiment:
#8565

## **Manual testing steps**

This can't easily be tested (we'd have to setup a fork of the repo, and
a new crowdin project, and new secrets, etc.). Instead it's configured
to be run manually on targeted branches, so that we can test this after
merge with minimal disruption.

## **Screenshots/Recordings**

N/A

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

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Introduces new GitHub Actions that can create/commit translation PRs
across release branches using a PAT, so misconfiguration could affect
release branch contents and CI triggering (though currently
`dryrun_action: true` limits impact).
> 
> **Overview**
> Adds two manually-triggered Crowdin GitHub Actions workflows for
release candidates.
> 
> `crowdin-rc-upload-sources.yml` uploads localization source strings
from the current branch to the matching Crowdin branch.
> 
> `crowdin-rc-download-translations.yml` downloads *approved*
translations and opens per-branch localization PRs; when run on `main`
it first discovers open `release/x.y.z` PR branches targeting `stable`
and runs across them via a matrix, otherwise it runs only for the
current branch. Both workflows use `METAMASKBOT_CROWDIN_TOKEN` and are
currently configured in `dryrun_action` mode.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
ced3104. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

This PR replaces the temporary `HeaderCompactStandard` component with
`HeaderStandard` from `@metamask/design-system-react-native` across
Perps surfaces.

**Reason:** Standardize Perps headers on the MetaMask design system and
reduce dependence on `component-library/components-temp` for common
header patterns.

**What changed:** `HeaderStandard` is now used for the Perps markets
list, withdrawal flow, transaction detail screens (funding, order,
position—including the “not found” states), and the default header
inside `PerpsBottomSheetTooltip` when no custom header is supplied.
Existing props such as `includesTopInset`, `onBack`, `onClose`, `title`,
`backButtonProps`, and `testID` are preserved so behavior should match
the previous implementation.

**Tests:** `PerpsMarketListHeader.test.tsx` was updated to spread
`jest.requireActual('@metamask/design-system-react-native')` into the
design-system mock and to remove the dedicated `HeaderCompactStandard`
mock, so tests exercise the real `HeaderStandard` behavior from the
design system package.

## **Changelog**

CHANGELOG entry: null 

## **Related issues**

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

## **Manual testing steps**

```gherkin
Feature: Perps headers use design system HeaderStandard

  Scenario: Markets list header
    Given the user opens Perps and navigates to the markets list
    When they view the header and use back or any trailing actions (e.g. watchlist) as before
    Then layout and navigation match prior behavior

  Scenario: Transaction detail screens
    Given the user opens a Perps funding, order, or position transaction from history
    When they view the header title and tap back
    Then they return to the previous screen and titles match expectations

  Scenario: Missing transaction
    Given a transaction id resolves to no data
    When the user lands on the not-found state
    Then a minimal header with back is shown and back navigates away

  Scenario: Withdraw screen
    Given the user opens Perps withdraw
    When they view the withdrawal title and use the back control
    Then behavior matches the previous screen

  Scenario: Bottom sheet tooltip
    Given a Perps tooltip bottom sheet that uses the default (non-custom) header
    When the user views the title and closes the sheet
    Then the sheet dismisses as before
```

## **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**
> Low risk refactor that swaps a temporary header component for the
design-system `HeaderStandard`; main risk is minor UI/layout or testID
regressions across Perps screens.
> 
> **Overview**
> Standardizes Perps UI headers by replacing the temporary
`HeaderCompactStandard` with MMDS `HeaderStandard` across the markets
list, withdraw flow, transaction detail screens (including “not found”
states), the default header in `PerpsBottomSheetTooltip`, and the shared
`ListHeaderWithSearch`.
> 
> Updates the `PerpsMarketListHeader` test setup to rely on the real
design-system exports (spreading
`jest.requireActual('@metamask/design-system-react-native')`) and
removes the dedicated `HeaderCompactStandard` mock so tests exercise
`HeaderStandard` behavior.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
5e55753. 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 Rewards screens and
related sheets, and updates unit tests to match.

**Reason:** Align Rewards with the MetaMask design system and reduce use
of `component-library/components-temp` for standard headers.

## **Changelog**

CHANGELOG entry: null 

## **Related issues**

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

<!-- Add issue link(s) if applicable. -->

## **Manual testing steps**

```gherkin
Feature: Rewards headers use design system HeaderStandard

  Scenario: Benefits and campaigns
    Given the user opens Rewards benefits (list or single benefit), campaigns list, or campaign mechanics
    When they use the header back control and read titles
    Then navigation and copy match prior behavior

  Scenario: Ondo and Season One campaign flows
    Given the user opens Ondo campaign details, portfolio, or Season One campaign details
    When they navigate back from the header
    Then behavior matches the previous implementation

  Scenario: Rewards settings and auxiliary sheets
    Given the user opens Rewards settings, referral, MUSD calculator, end-of-season claim, linked off-device accounts, opt-in modal, or environment toggle surfaces touched by this PR
    When they dismiss or navigate via the header
    Then sheets and screens behave as before
```

## **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**
> Low risk refactor limited to UI header component swaps and
corresponding test updates; main risk is minor visual/layout or `testID`
regressions affecting navigation/back-button automation.
> 
> **Overview**
> Rewards screens and sheets now use **MMDS `HeaderStandard`** instead
of the legacy `HeaderCompactStandard` component, including benefits,
campaigns, referral, settings, calculators, and multiple bottom
sheets/modals.
> 
> Unit tests were updated to remove `HeaderCompactStandard` mocks, align
back/close button `testID`s (e.g., campaign mechanics/details), and add
missing Safe Area hook stubs (notably `useSafeAreaInsets`) so
`HeaderStandard` can render cleanly in Jest.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
d6a8c44. 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` on Trending UI.

**Reason:** Align Trending with the MetaMask design system and avoid
`component-library/components-temp` for standard headers.

## **Changelog**

CHANGELOG entry: null 

## **Related issues**

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

## **Manual testing steps**

```gherkin
Feature: Trending uses design system HeaderStandard

  Scenario: Trending list header
    Given the user opens Trending tokens
    When they view the header title and use back or search as before
    Then navigation and search behavior match prior behavior

  Scenario: Network, sort, and time bottom sheets
    Given the user opens the network selector, price-change sort, or time-range sheet from Trending
    When they view each sheet title and tap close
    Then each sheet dismisses and labels match prior copy
```

## **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**
> Low risk UI refactor that swaps header components; main risk is minor
regressions in header/back/close/testID wiring across Trending screens
and related tests.
> 
> **Overview**
> Updates Trending UI to use the design-system `HeaderStandard` instead
of the temporary `HeaderCompactStandard`, covering the main Trending
list header and the network/price-change/time bottom-sheet headers.
> 
> Adjusts a Rewards `OndoCampaignRwaSelectorView` test to press the new
back-button testID emitted by the updated header implementation.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
030a1cd. 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 the temporary `HeaderCompactStandard` component with
`HeaderStandard` from `@metamask/design-system-react-native` on Predict
screens and sheets.

**Reason:** Align Predict UI with the MetaMask design system and rely
less on `component-library/components-temp` for standard headers.

**What changed:**  
- **Predict feed:** Main Predict feed header now uses `HeaderStandard`
with `includesTopInset`, back handling, and the existing title string.
Unused design-system imports (`Icon`, `IconColor`, `IconSize`) were
removed from this file after the swap.
- **Activity detail:** Activity detail screen header uses
`HeaderStandard` with the same title fallback logic
(`activityDetails?.headerTitle` vs. the default activity-details
string).
- **Unavailable bottom sheet:** The “Predict unavailable” sheet header
uses `HeaderStandard` with `testID`, title, and close behavior
unchanged.

Behavior is intended to match the previous headers (navigation, titles,
safe area).

## **Changelog**

CHANGELOG entry: null 

## **Related issues**

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

## **Manual testing steps**

```gherkin
Feature: Predict headers use design system HeaderStandard

  Scenario: Predict feed header
    Given the user opens Predict from the wallet (Predict feed)
    When they view the header title and tap back
    Then navigation matches prior behavior and the title shows the expected Predict label

  Scenario: Activity detail header
    Given the user opens a Predict activity from history or the feed
    When they view activity details
    Then the header title reflects activity-specific copy when present or the default activity-details string
    When they use the back control
    Then they return to the previous screen as before

  Scenario: Predict unavailable sheet
    Given Predict is unavailable and the bottom sheet is shown
    When the user views the header and closes the sheet
    Then the sheet dismisses as before
```

## **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**
> Low risk UI refactor that swaps a temporary header component for the
design-system `HeaderStandard`; primary risk is minor layout/safe-area
or button behavior differences across screens/sheets.
> 
> **Overview**
> Updates Predict UI to use the design-system `HeaderStandard` in place
of the temporary `HeaderCompactStandard` on the feed screen, activity
detail screen, and the “Predict unavailable” bottom sheet.
> 
> Keeps existing titles and back/close wiring (including testIDs and
`includesTopInset`) while removing now-unused icon-related imports in
`PredictFeed`.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
391f93a. 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>
<!--
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**

The PR sets gasIncluded to true on Solana quote requests while
preserving the fact that the MAX button is not available when SOL is the
source token.

<!--
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] -->

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

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

<!--
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).
- [ ] 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**
> Changes quote parameter selection for Solana source tokens, which can
affect pricing/transaction flow for Solana swaps/bridges. Logic is small
and covered by tests, but impacts a core bridging path.
> 
> **Overview**
> For Solana source tokens, `selectGasIncludedQuoteParams` now always
returns `gasIncluded: true` and forces `gasIncluded7702: false`,
regardless of swap/bridge flags or STX/7702 support.
> 
> The bridge MAX-button rendering logic (`useShouldRenderMaxOption`) now
explicitly hides MAX for *Solana native assets* even if gas-included
quoting is enabled, and tests were updated/added to cover these
Solana-specific behaviors.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
d75e3e3. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@pull pull Bot locked and limited conversation to collaborators May 7, 2026
@pull pull Bot added the ⤵️ pull label May 7, 2026
@pull pull Bot merged commit d4722b8 into Reality2byte:main May 7, 2026
3 of 15 checks passed
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.