Skip to content

release: 7.69.0#27086

Merged
chloeYue merged 281 commits intostablefrom
release/7.69.0
Mar 13, 2026
Merged

release: 7.69.0#27086
chloeYue merged 281 commits intostablefrom
release/7.69.0

Conversation

@metamaskbot
Copy link
Collaborator

@metamaskbot metamaskbot commented Mar 5, 2026

🚀 v7.69.0 Testing & Release Quality Process

Hi Team,
As part of our new MetaMask Release Quality Process, here’s a quick overview of the key processes, testing strategies, and milestones to ensure a smooth and high-quality deployment.


📋 Key Processes

Testing Strategy

  • Developer Teams:
    Conduct regression and exploratory testing for your functional areas, including automated and manual tests for critical workflows.
  • QA Team:
    Focus on exploratory testing across the wallet, prioritize high-impact areas, and triage any Sentry errors found during testing.
  • Customer Success Team:
    Validate new functionalities and provide feedback to support release monitoring.

GitHub Signoff

  • Each team must sign off on the Release Candidate (RC) via GitHub by the end of the validation timeline (Tuesday EOD PT).
  • Ensure all tests outlined in the Testing Plan are executed, and any identified issues are addressed.

Issue Resolution

  • Resolve all Release Blockers (Sev0 and Sev1) by Tuesday EOD PT.
  • For unresolved blockers, PRs may be reverted, or feature flags disabled to maintain release quality and timelines.

Cherry-Picking Criteria

  • Only critical fixes meeting outlined criteria will be cherry-picked.
  • Developers must ensure these fixes are thoroughly reviewed, tested, and merged by Tuesday EOD PT.

🗓️ Timeline and Milestones

  1. Today (Friday): Begin Release Candidate validation.
  2. Tuesday EOD PT: Finalize RC with all fixes and cherry-picks.
  3. Wednesday: Buffer day for final checks.
  4. Thursday: Submit release to app stores and begin rollout to 1% of users.
  5. Monday: Scale deployment to 10%.
  6. Tuesday: Full rollout to 100%.

✅ Signoff Checklist

Each team is responsible for signing off via GitHub. Use the checkbox below to track signoff completion:

Team sign-off checklist

  • Accounts Framework
  • Assets
  • Bots Team
  • Card
  • Confirmations
  • Core Platform
  • Design System
  • Earn
  • EVM Datalake
  • Extension Platform
  • Mobile Platform
  • Mobile UX
  • Networks
  • Onboarding
  • Perps
  • Predict
  • Ramp
  • Rewards
  • Social & AI
  • Swaps and Bridge
  • Wallet Integrations

This process is a major step forward in ensuring release stability and quality. Let’s stay aligned and make this release a success! 🚀

Feel free to reach out if you have questions or need clarification.

Many thanks in advance

Reference

oilnam and others added 30 commits February 27, 2026 18:27
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

This PR removes the "Reset notifications" button which is not needed
anymore, and it's currently broken anyway.
Translation strings are also removed.

<img width="394" height="742" alt="image"
src="https://github.com/user-attachments/assets/4b29f6e0-8b84-4896-9757-4393d96d0b0b"
/>


## **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 "Reset notifications" button from notifications
list

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

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

## **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**
> Primarily removes dead/broken UI and navigation wiring; main risk is
missing a remaining reference to the removed route/string, but changes
are otherwise non-functional.
> 
> **Overview**
> Removes the broken **“Reset notifications”** entry from notification
settings by deleting the `ResetNotificationsButton`, the
`ResetNotificationsModal` bottom sheet, and their associated
tests/snapshots.
> 
> Cleans up navigation by removing `Routes.SHEET.RESET_NOTIFICATIONS`
and its route typing, and deletes related i18n strings across supported
languages; also stabilizes `useNotifications` hook tests by properly
mocking `usePushNotificationsToggle` and clearing mocks between tests.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3be27b9. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Phase 3 analytics migration (Batch 3-10): migrate Onboarding/Account
Import's ImportNewSecretRecoveryPhrase, ExperienceEnhancerModal, and
Pna25BottomSheet from useMetrics/MetaMetrics to the new analytics
system.

**Reason**: Deprecate MetaMetrics in favour of the shared analytics
utility and AnalyticsController.

**Changes**: ImportNewSecretRecoveryPhrase, ExperienceEnhancerModal, and
Pna25BottomSheet now use `useAnalytics` and `AnalyticsEventBuilder` from
`app/components/hooks/useAnalytics` and `app/util/analytics`; test mocks
updated to mock useAnalytics instead of useMetrics.
ImportFromSecretRecoveryPhrase already used useAnalytics — no migration
needed.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-302 (Batch
3-10)

## **Manual testing steps**

```gherkin
Feature: Onboarding/Account Import analytics

  Scenario: user triggers an onboarding/account import flow event
    Given app is open and user is in an onboarding/account import flow

    When user performs an action that triggers analytics (e.g. import SRP completed, marketing consent modal accept/cancel, PNA25 notice viewed/closed)
    Then the event is tracked on Mixpanel
```

## **Screenshots/Recordings**

N/A – analytics migration, no UI change.

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Replaces the legacy `useMetrics` analytics hook with `useAnalytics` in
onboarding/consent flows, which could change or break event
emission/consent traits if the new builder/hook behavior differs. No
functional UI changes, but tracking correctness is compliance- and
telemetry-sensitive.
> 
> **Overview**
> Migrates analytics instrumentation in **ExperienceEnhancerModal**,
**ImportNewSecretRecoveryPhrase**, and **Pna25BottomSheet** from legacy
`useMetrics` to `useAnalytics`, updating event/builder usage (e.g., SRP
import completion and PNA25 notice events) while keeping existing
`MetaMetricsEvents` names.
> 
> Updates Jest tests to mock `useAnalytics` and (for SRP import) swap
`MetricsEventBuilder` references to `AnalyticsEventBuilder`, ensuring
tracking assertions still validate emitted events/properties.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
09f4586. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Phase 3 analytics migration (Batch 3-11): migrate Hardware Wallet's
`LedgerSelectAccount` component from `useMetrics` to the new analytics
system.

**Reason**: Deprecate MetaMetrics in favour of the shared analytics
utility and AnalyticsController.

**Changes**: `LedgerSelectAccount/index.tsx` now uses `useAnalytics`
from `app/components/hooks/useAnalytics/useAnalytics` instead of
`useMetrics`; test mocks updated to mock `useAnalytics` instead of
`useMetrics`.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-302 (Batch
3-11)

## **Manual testing steps**

```gherkin
Feature: Hardware Wallet analytics

  Scenario: user triggers a hardware wallet flow event
    Given app is open and user is in a hardware wallet flow

    When user performs an action that triggers analytics (e.g. open account selector, unlock account, forget device)
    Then the event is tracked on Mixpanel
```

## **Screenshots/Recordings**

N/A – analytics migration, no UI change.

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

## **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**
> Swaps the analytics hook used by `LedgerSelectAccount` and updates its
unit test mock; behavior should be equivalent but could affect event
emission if the new hook differs in runtime wiring.
> 
> **Overview**
> Migrates hardware wallet `LedgerSelectAccount` analytics from the
deprecated `useMetrics` hook to the new `useAnalytics` hook while
keeping the same `trackEvent`/`createEventBuilder` call sites.
> 
> Updates `LedgerSelectAccount` tests to mock `useAnalytics` instead of
`useMetrics` so existing analytics-related assertions continue to run
against the new hook.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d71565b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Phase 3 analytics migration (Batch 3-14): migrate Legal/Onboarding's
terms-of-use utilities from `MetaMetrics.getInstance()` to the new
analytics system.

**Reason**: Deprecate MetaMetrics in favour of the shared analytics
utility and AnalyticsController.

**Changes**: `termsOfUse.ts` now uses `analytics.trackEvent()` and
`AnalyticsEventBuilder` from `app/util/analytics`; test mocks updated to
mock the analytics utility instead of `MetaMetrics.getInstance()`.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-302 (Batch
3-14)

## **Manual testing steps**

```gherkin
Feature: Legal/Onboarding analytics

  Scenario: user triggers a terms of use flow event
    Given app is open and user has not yet accepted terms of use

    When user performs an action that triggers analytics (e.g. terms of use shown, terms accepted)
    Then the event is tracked on Mixpanel
```

## **Screenshots/Recordings**

N/A – analytics migration, no UI change.

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

## **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 the event tracking implementation for
terms-of-use shown/accepted; behavior should be equivalent but could
impact whether/when these two events are emitted if the new analytics
queueing differs from `MetaMetrics.getInstance()`.
> 
> **Overview**
> Migrates terms-of-use analytics emission from
`MetaMetrics.getInstance().trackEvent`/`MetricsEventBuilder` to the
shared `analytics.trackEvent` helper with `AnalyticsEventBuilder` for
the `USER_TERMS_SHOWN` and `USER_TERMS_ACCEPTED` events.
> 
> Updates `termsOfUse` unit tests to mock `app/util/analytics/analytics`
and assert calls to `analytics.trackEvent` instead of mocking
`MetaMetrics`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f7c5c93. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Phase 3 analytics migration (Batch 3-15): migrate the ResetPassword view
from `MetaMetrics.getInstance()` / `MetricsEventBuilder` to the new
`analytics` utility and `AnalyticsEventBuilder`.

**Reason**: Deprecate MetaMetrics in favour of the shared analytics
utility and AnalyticsController.

**Changes**: `ResetPassword/index.js` now uses `analytics.trackEvent()`
and `AnalyticsEventBuilder` from `app/util/analytics`; test mocks
updated to mock the analytics utility instead of MetaMetrics.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-302 (Batch
3-15)

## **Manual testing steps**

```gherkin
Feature: Settings analytics

  Scenario: user triggers a password change event
    Given app is open and user is in Settings > Change Password flow

    When user performs an action that triggers analytics (e.g. password change confirmation)
    Then the event is tracked on Mixpanel
```

## **Screenshots/Recordings**

N/A – analytics migration, no UI change.

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

## **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 analytics plumbing in the password reset
flow; main risk is mis-tracking or missing the `PASSWORD_CHANGED` event
due to the API swap.
> 
> **Overview**
> Migrates `ResetPassword` analytics from legacy
`MetaMetrics.getInstance()`/`MetricsEventBuilder` to the shared
`analytics` utility with `AnalyticsEventBuilder`, keeping the
`PASSWORD_CHANGED` event and its biometry-related properties.
> 
> Updates the `ResetPassword` tests to mock `util/analytics/analytics`
instead of `MetaMetrics`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
22501d0. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Phase 3 analytics migration (Batch 3-16): migrate selectors
(`legalNotices`, `bridgeController`) from `MetaMetrics.getInstance()` to
the new analytics system.

**Reason**: Deprecate MetaMetrics in favour of the shared analytics
utility and AnalyticsController.

**Changes**: `legalNotices/index.ts` and `bridgeController/index.ts` now
use `analytics.isEnabled()` from `app/util/analytics/analytics` instead
of `MetaMetrics.getInstance().isEnabled()`; test mocks updated to mock
the analytics utility instead of MetaMetrics.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-302 (Batch
3-16)

## **Manual testing steps**

```gherkin
Feature: Selectors analytics

  Scenario: user triggers a selector-dependent flow event
    Given app is open and user is in a flow that relies on legalNotices or bridgeController selectors

    When user performs an action that triggers analytics (e.g. PNA25 notice display, bridge quote request)
    Then the event is tracked on Mixpanel
```

## **Screenshots/Recordings**

N/A – analytics migration, no UI change.

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

## **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 only swaps the opt-in check from
`MetaMetrics.getInstance().isEnabled()` to `analytics.isEnabled()` in a
couple of selectors and updates unit test mocks accordingly.
> 
> **Overview**
> Migrates selector logic in `bridgeController` and `legalNotices` off
deprecated `MetaMetrics.getInstance()` and onto the shared `analytics`
helper.
> 
> `participateInMetaMetrics` (bridge app state) and the PNA25 notice
gating check now call `analytics.isEnabled()`, and the `legalNotices`
selector tests were updated to mock the new analytics utility instead of
`MetaMetrics`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
97d418a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…nd bridge transactions (#26701)

## **Description**

The "View on block explorer" button on the Bridge/Swap Transaction
Details screen was broken for both swaps and bridge transactions —
pressing it did nothing.

Root causes:

- Swap transactions: `navigation.navigate(Routes.BROWSER.VIEW, ...)` was
called directly, but `BROWSER.VIEW` is a nested screen inside the
`BROWSER.HOME` tab navigator. React Navigation silently ignores
navigation calls to nested screens made from outside their parent.
Additionally, navigating to a tab navigator replaces the current stack,
so the back button would return to the home screen instead of
activities.

- Bridge transactions:
`navigation.navigate(Routes.BRIDGE.MODALS.TRANSACTION_DETAILS_BLOCK_EXPLORER,
...)` was called directly, but this screen is nested inside
`BridgeModalStack` (registered as `Routes.BRIDGE.MODALS.ROOT`). Same
silent failure.

Fix:

- Swap path now uses `Routes.WEBVIEW.MAIN` → `Routes.WEBVIEW.SIMPLE`,
which pushes a `WebView` on top of the current stack (back button
returns to Transaction Details correctly)
- Bridge path now navigates to `Routes.BRIDGE.MODALS.ROOT` with screen:
`TRANSACTION_DETAILS_BLOCK_EXPLORER` as a nested param
- Tightened the condition from a bare else to else if (isBridge) to
prevent a swap with an unresolved explorer URL from accidentally opening
the bridge modal

## **Changelog**

CHANGELOG entry: Fixed "View on block explorer" button not working on
Bridge/Swap Transaction Details screen

## **Related issues**

Fixes: #26628

## **Manual testing steps**

```gherkin
Feature: View on block explorer from Transaction Details

  Scenario: user views a completed swap on block explorer
    Given user has a completed swap transaction (same-chain)
    When user taps the transaction in Activity to open Transaction Details
    And user taps "View on block explorer"
    Then a WebView opens showing the block explorer for that transaction
    And tapping back returns the user to Transaction Details

  Scenario: user views a completed bridge on block explorer
    Given user has a completed bridge transaction (cross-chain)
    When user taps the transaction in Activity to open Transaction Details
    And user taps "View on block explorer"
    Then a bottom sheet appears with source and destination chain explorer options
    When user taps one of the explorer options
    Then a WebView opens showing that chain's block explorer for the transaction
```

## **Screenshots/Recordings**

`~`

### **Before**


https://github.com/user-attachments/assets/9030e42a-32a5-4661-bc00-d4953ae17850

### **After**


https://github.com/user-attachments/assets/26da74e6-353b-4df9-9be2-7f45f00105fe

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes React Navigation targets for the “View on block explorer” flow
and bridge explorer modal buttons, which is user-facing and could
regress routing/back-stack behavior if route params or navigator
structure differ across entry points.
> 
> **Overview**
> Fixes the broken “View on block explorer” actions in Bridge/Swap
transaction details by updating navigation to valid parent/nested
routes.
> 
> Swaps now open the in-app `WEBVIEW` (`Routes.WEBVIEW.MAIN` →
`Routes.WEBVIEW.SIMPLE`) instead of `Routes.BROWSER.VIEW`, while bridges
now navigate via `Routes.BRIDGE.MODALS.ROOT` to show the
explorer-selection bottom sheet; the fallback logic is tightened to only
open the modal for actual bridge transactions.
> 
> Updates/expands unit tests to mock navigation and assert the new
webview/modal navigation behavior, including pressing source/destination
explorer buttons in `BlockExplorersModal`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
77221e0. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…works in transaction details (#26659)

## **Description**

`getBlockExplorerForChain()` in `TransactionDetails` only resolved block
explorer URLs for hardcoded built-in networks (Mainnet, Linea, Sepolia)
and user-added custom RPC networks. Popular networks (Arbitrum, Polygon,
BNB Chain, etc.) are neither — they aren't stored in
`networkConfigurations` — so the method fell through to
`NO_RPC_BLOCK_EXPLORER`, hiding the "View on X" link entirely.

The fix adds a `PopularList` lookup as a fallback, matching the pattern
already used correctly in useBlockExplorer.ts.

## **Changelog**

CHANGELOG entry: Fixed a bug where transactions on popular networks
(Arbitrum, Polygon, BNB Chain, etc.) were missing the block explorer
link in transaction details

## **Related issues**

Fixes: #26419

## **Manual testing steps**

```gherkin
Feature: Block explorer link in transaction details

  Scenario: user views a transaction from a Popular network
    Given the user has transactions on Arbitrum, Polygon, or BNB Chain
    And the activity feed is filtered by "Popular networks"

    When user taps a confirmed transaction from one of those networks
    Then a "View on Arbiscan" / "View on Polygonscan" / "View on Bscscan" link appears
    And tapping it opens the correct block explorer tx URL in the webview

  Scenario: user views a transaction on Ethereum Mainnet
    Given the user has transactions on Ethereum Mainnet
    When user taps a confirmed transaction
    Then a "View on Etherscan" link still appears (regression check)
```

## **Screenshots/Recordings**

`~`

### **Before**


https://github.com/user-attachments/assets/0b15c664-e62e-4811-94f6-e12687454025

### **After**


https://github.com/user-attachments/assets/8c71420a-f95a-4ebe-ba4c-dedd7cfebc0e

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

## **Pre-merge reviewer checklist**

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


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk UI fix that only changes how the transaction details screen
resolves a block explorer URL, with added test coverage to prevent
regressions.
> 
> **Overview**
> Fixes missing **“View on …”** links in `TransactionDetails` for
*popular networks* that aren’t present in `networkConfigurations` by
falling back to `PopularList` to resolve `rpcPrefs.blockExplorerUrl`.
> 
> Adds unit tests ensuring the correct explorer link text/URL is
produced for Arbitrum, Polygon, and BNB Chain, alongside existing
mainnet/custom-network coverage.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0e7e142. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Extract various logic into separate pure functions and hooks. 

<!--
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: https://consensyssoftware.atlassian.net/browse/SWAPS-4188

## **Manual testing steps**

```gherkin
This PR introduce no change to business logic. Ensure that no regressions got introduced. 
```

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

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Mostly refactoring with broad surface-area touch in Bridge quoting/fee
display and validation filtering; moderate risk of UI regressions around
fee formatting and when quote sections render/clear on expiry.
> 
> **Overview**
> **Refactors Bridge quote presentation logic into reusable
utilities/hooks.** Network-fee formatting is extracted to
`formatNetworkFee` + `useFormattedNetworkFee`, and gas-sponsorship logic
is moved into `useIsNetworkGasSponsored` +
`useShouldRenderGasSponsoredBanner`, with gasless detection centralized
in `isGaslessQuote`.
> 
> **Hardens quote-driven UI and data selection.** `BridgeView` now
avoids rendering the bottom action section when there’s no `activeQuote`
(fixing an expiry/redirect edge case), and `useBridgeQuoteData` adds
`validQuotes` by filtering sorted quotes to those matching the selected
destination token and non-expired state.
> 
> **Consolidates fiat formatting.** The existing `useFiatFormatter` hook
is simplified to delegate to a new shared `util/formatFiat` helper, with
extensive new unit tests added across the new hooks/utilities.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
9096d32. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…ity (#26676)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Part "4.5" of the hardware wallet connection & error management
overhaul. This does not introduce user facing changes.

Will close:
- https://consensyssoftware.atlassian.net/browse/MUL-1495

Final implementation will look like this ([Figma
designs](https://www.figma.com/design/1F3yNWYLOVPFpTPeJugH20/SWAP?node-id=11110-19571&t=tPMZNNiwCgbDfegd-0)):
<img width="1404" height="631" alt="image"
src="https://github.com/user-attachments/assets/68850711-f53b-4060-8b47-6faceb67f82f"
/>

Reference feature branch:
#25519

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

no manual testing steps

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

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Refactors core hardware-wallet connection flow and transport
monitoring into new hooks, which could subtly change state transitions
(scanning/connecting/error/ready) or cleanup behavior. No new security
surface, but regressions could impact device connectivity and error
handling.
> 
> **Overview**
> Refactors `HardwareWalletProvider` by extracting adapter lifecycle,
transport monitoring, device discovery, and connection/retry/close logic
into new hooks (`useAdapterLifecycle`, `useTransportMonitoring`,
`useDeviceDiscovery`, `useDeviceConnectionFlow`) and wiring the provider
to these hook APIs.
> 
> Simplifies the connecting UI contract by removing adapter-provided
`connectionTips`: `getConnectionTips()` is removed from
`HardwareWalletAdapter` (and Ledger/NonHardware adapters),
`HardwareWalletBottomSheet` no longer accepts `connectionTips`, and
`ConnectingContent` now derives tips via
`getConnectionTipsForWalletType()` in `helpers.ts`. Also makes
bottom-sheet `onClose` required and updates tests accordingly.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b84edf3. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Add comprehensive analytics events to the Unified Buy v2 flow, covering
every user interaction across Token Selection and Amount Input screens.
Flow identity uses **`ramp_type` only** (e.g. `'UNIFIED BUY 2'`); for a
single dimension in Segment and Data Council.

**Reason for change:** Measure UB2 funnel conversion and drop-offs;
compare UB2 vs UB1.
**Improvement:** 18 new events + enhanced existing events; screen viewed
once per visit; Change provider only in Payment Selection modal.

### Changes
- **18 new events:** Ramps Screen Viewed, Back Button Clicked, Network
Filter Clicked, Token Searched, Settings Clicked, Setting Option
Clicked, Payment Method Selector Clicked, Quick Amount Clicked, Change
Provider Button Clicked, Provider Selected, Continue Button Clicked
(KPI), Terms Consent Clicked, External Link Clicked, Close Button
Clicked, Quote Error, Quote Error Tooltip Clicked, Unsupported Token
Tooltip Clicked, Toast Button Clicked.
- **Existing enhanced:** `RAMPS_TOKEN_SELECTED` and
`RAMPS_BUTTON_CLICKED` accept `ramp_type: 'UNIFIED BUY 2'`.
- **Screens:** TokenSelection, BuildQuote, PaymentSelectionModal (Change
provider only).

### Related PRs
- Segment schema: Consensys/segment-schema#471

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TRAM-3028

## **Manual testing steps**

```gherkin
Feature: Unified Buy v2 analytics events

  Scenario: user completes token selection and amount input in UB2 flow
    Given Unified Buy v2 is enabled (MM_RAMPS_UNIFIED_BUY_V2_ENABLED=true) and user is on Buy from home

    When user opens Token Selection then searches token, filters by network, selects token, opens Amount Input, taps quick amount, opens payment selector, taps Change provider in Payment Selection modal, taps Settings, then taps Continue

    Then Segment debugger shows Ramps Screen Viewed (once per visit per screen), Ramps Token Searched, Ramps Network Filter Clicked, Ramps Token Selected with ramp_type UNIFIED BUY 2, Ramps Quick Amount Clicked, Ramps Payment Method Selector Clicked, Ramps Change Provider Button Clicked, Ramps Settings Clicked, Ramps Continue Button Clicked with no feature_flag_unified_buy_v2 in payloads
```

## **Screenshots/Recordings**

<div>
<a href="https://www.loom.com/share/ac98af2b79cc41c1a37336329fd06cb5">
      <p>Ramps Unified Buy V2 Analytics Walkthrough - Watch Video</p>
    </a>
<a href="https://www.loom.com/share/ac98af2b79cc41c1a37336329fd06cb5">
<img style="max-width:300px;"
src="https://cdn.loom.com/sessions/thumbnails/ac98af2b79cc41c1a37336329fd06cb5-564c55257a094c01-full-play.gif#t=0.1">
    </a>
  </div>


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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Adds/changes analytics instrumentation across multiple ramp screens
and entry points, which is moderately risky due to potential schema
regressions or event-volume changes (but no funds/auth logic is
altered).
> 
> **Overview**
> Adds **Unified Buy v2 (UB2)** analytics instrumentation across the
ramps flow, introducing a new `ramp_type` value (`UNIFIED_BUY_2`) and a
set of new MetaMetrics events (screen views, back/close, settings, quick
amounts, provider/payment selection, external links, quote errors,
tooltips, etc.).
> 
> Updates existing ramps events to match the new schema (notably
renaming the `RAMPS_BUTTON_CLICKED` property from `text` to
`button_text`) and wires UB2-aware `ramp_type` selection into multiple
entry points (e.g., `BalanceEmptyState`, `FundActionMenu`,
`AccountsMenu`, Card add-funds deposit).
> 
> Extends navigation header helpers to support an optional `onBackPress`
callback so screens can track back navigation, and adjusts unit/smoke
tests and snapshots accordingly.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
2fb77db. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=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 the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
- Fix geolocation mock to return plain text (us-ca) instead of a JSON
object, matching the real API's response format. The app reads this with
response.text(), so a JSON object gets stringified and can produce
malformed URLs when used in path segments.
- Support string responses in the mock server layer — both
MockServerE2E.ts and mockHelpers.ts now return string responses as raw
text instead of JSON-serializing them.
- Add catch-all mock for the legacy /regions/{region}/tokens endpoint to
DEFAULT_RAMPS_API_MOCKS, preventing unmocked live API calls.
- On mUSD convert disables the synchronization only after tapping the
CTA to make sure it is displayed before on a first time user.


This PR addresses a gigantic mocking error on default mocks,
specifically speaking the onramp geolocation. This issue was causing
random flakiness due to a bad formatted url coming from a mock.
Example:
`https://on-ramp-cache.uat-api.cx.metamask.io/regions/%7B%22id%22:%22/regions/us-ca%22,%22name%22:%22california%22,%22emoji%22:%22%F0%9F%87%BA%F0%9F%87%B8%22,%22detected%22:true%7D/tokens?action=deposit&sdk=2.1.5`
(see [run
reference](https://github.com/MetaMask/metamask-mobile/actions/runs/22429213914/job/64944977184))

The reason for this is that the request for
`https://on-ramp.<ENV>-api.cx.metamask.io/geolocation` was returning
```typescript
{
    id: region.id,
    name: region.name,
    emoji: region.emoji,
    detected: true,
}
```
when in reality the geolocation endpoint returns plaintext containing
the country code for the user's location. This PR adds the ability to
the mock server to accept plain text instead of json as a response and
fixes the mocking.

It then caused perps tests to fail due to region not available since the
[fallback country (US) is currently being
blacklisted](https://github.com/MetaMask/metamask-mobile/blob/main/builds.yml#L40)
and this was the country used in the onramps default geolocation mock.


## CI changes
`ref` was removed from the shard runner checkout as this was causing
inconsistencies with the way every single workflow uses checkout. Builds
do **not** contain a ref which results in building apps with a merge
commit instead of the branch commit while tests would run with a
different ref resulting in failed tests for changes that were already
fixed on main.

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

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

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



<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Moderate risk: changes test infrastructure by installing a
lifecycle-wide `unhandledRejection` filter and altering mock server
shutdown behavior, which could mask unexpected promise rejections if the
filter is too broad. Functional app code is untouched; impact is limited
to E2E reliability and mocking fidelity.
> 
> **Overview**
> Fixes onramp geolocation mocking to return *plain text* region codes
(matching the real API) and updates the mocking layer (`MockServerE2E`,
`setupMockRequest`) to return raw string bodies without
JSON-serializing; adds a catch-all mock for legacy
`/regions/{region}/tokens` to prevent live calls.
> 
> Hardens E2E infra by adding `MockServerE2E.startDraining()` (return
503 during cleanup) and installing a lifecycle-wide filter that
suppresses mockttp `Error('Aborted')` unhandled rejections, with cleanup
integrated into `withFixtures`.
> 
> Stabilizes flaky Detox flows: waits for elements to stop moving before
taps (wallet token rows, confirm button), relaxes a swap analytics
assertion to *min length*, adjusts unified-buy analytics region
assertions to expect a string, adds perps geolocation mocking
(non-blocked region), and tweaks/simplifies a few smoke tests (mUSD sync
timing, SOL send assertions).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
27fc622. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…nterface (#26703)

## **Description**

Consolidates scattered feature flag resolution in PredictController into
a single `resolveFeatureFlags()` method and injects flags into
PolymarketProvider via a constructor callback.

**Problem**: Feature flags (liveSportsLeagues, feeCollection,
marketHighlights) were resolved independently in 3 separate
PredictController methods (`getMarkets`, `getMarket`, `previewOrder`),
each calling `RemoteFeatureFlagController:getState` and unwrapping flags
ad-hoc. These flags were then passed as method parameters to
PolymarketProvider.

**Solution**:
- New `PredictFeatureFlags` type consolidating all predict feature flags
- New `resolveFeatureFlags()` private method on PredictController —
single resolution point
- PolymarketProvider now takes a `getFeatureFlags` callback in
constructor and reads flags internally
- Cleaned `PredictProvider` interface — removed per-method flag
parameters (`liveSportsLeagues`, `feeCollection`)
- Removed `liveSportsLeagues` from `GetMarketsParams` (internal concern,
not caller-facing)

This is a **pure refactor** — zero behavior changes. Foundation for
upcoming Permit2 fee authorization support.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/PRED-715

## **Manual testing steps**

```gherkin
Feature: Predict feature flag resolution refactor

  Scenario: user places prediction market orders as before
    Given user has Predict feature enabled and is in a supported region

    When user browses markets, views market details, and previews/places orders
    Then all functionality works identically to before (no behavior changes)
```

## **Screenshots/Recordings**

N/A — pure refactor, no UI changes.

### **Before**

N/A

### **After**

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.

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches Predict market fetching and order preview paths by changing
how feature flags are resolved and threaded into the Polymarket
provider. Risk is mainly around mismatched defaults or missing flag
injection impacting live sports overlays, highlights ordering, or fee
collection in previews.
> 
> **Overview**
> **Refactors Predict feature-flag plumbing** by introducing
`PredictFeatureFlags` and a single
`PredictController.resolveFeatureFlags()` that reads remote flags (live
sports leagues, market highlights, fee collection) and supplies them to
`PolymarketProvider` via a `getFeatureFlags` constructor callback.
> 
> `PolymarketProvider` now consumes flags internally (no longer accepts
`liveSportsLeagues`/`feeCollection` as method params), and the
`PredictProvider`/`GetMarketsParams` types are simplified accordingly.
Tests are updated to match the new provider constructor + method
signatures and to assert fee collection defaults are applied during
`previewOrder` and highlight fetching.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
fdb4a95. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
#26696)

## **Description**

This PR adds `@deprecated` JSDoc comments with README links to 20
component library files that have replacements in the MetaMask Design
System (MMDS).

The deprecation messages provide clear migration paths for developers
by:
1. Indicating which MMDS component to use as a replacement
2. Warning that the API may have changed
3. Linking directly to the component's README in the MMDS repository

This work improves developer experience by making it easier to migrate
from legacy component library components to the standardized MMDS
components.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

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

## **Manual testing steps**

```gherkin
Feature: JSDoc deprecation comments

  Scenario: developer views deprecated component
    Given a developer opens a component library file
    
    When developer hovers over a deprecated component import
    Then the IDE should display the @deprecated JSDoc comment with migration guidance
    And the comment should include a link to the MMDS component README
```

## **Screenshots/Recordings**

N/A - Documentation-only changes

### **Before**

Components had either no deprecation messages or minimal ones without
full context.

### **After**

All 20 components now have consistent deprecation messages following
this pattern:

```javascript
/**
 * @deprecated Please update your code to use `ComponentName` from `@metamask/design-system-react-native`.
 * The API may have changed — compare props before migrating.
 * @see {@link https://github.com/MetaMask/metamask-design-system/blob/main/packages/design-system-react-native/src/components/ComponentName/README.md}
 */
```

**Components updated:**
- Avatar components: AvatarAccount, AvatarBase, AvatarFavicon,
AvatarGroup, AvatarIcon, AvatarNetwork, AvatarToken
- Badge components: BadgeBase, BadgeNetwork, BadgeNotifications,
BadgeWrapper
- Button components: Button, ButtonIcon, ButtonLink, ButtonPrimary,
ButtonSecondary
- Form components: Checkbox, TextField
- Other components: Card, Icon, Text

## **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 (N/A - documentation only)
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **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 documentation-only change: adds/standardizes `@deprecated`
JSDoc blocks and external README links without altering component
runtime behavior. Main risk is minor lint/formatting or tooling
differences in how IDEs surface these comments.
> 
> **Overview**
> Adds consistent `@deprecated` JSDoc annotations across legacy
component-library UI components (avatars, badges, buttons, checkbox,
text field, icon, text), pointing developers to the equivalent
`@metamask/design-system-react-native` replacements.
> 
> Each deprecation notice now includes a migration caution about
potential API differences and a direct link to the relevant MMDS README
for the replacement component.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
167e357. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Update the Xcode stack from osx-xcode-16.3.x to osx-xcode-26.2.x to
enable building with iOS SDK 26. This prepares for the April 2026 App
Store requirement that apps must be built with Xcode 26 or later.

This PR updates the ruby version to 3.2.9 according to the [Bitrise
stack
availability](https://bitrise.io/stacks/stack_reports/osx-xcode-26.2.x/).
It also updates the Ruby Version source for the `ci/docker` step.

It also requires an update to the .github-tools repo here:
https://github.com/MetaMask/github-tools/pull/220/commits

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

AI agent: Be specific about what you changed and why. Include context
about the fix/feature, not generic descriptions.
-->

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

AI agent: Use format `CHANGELOG entry: [fix/feat/chore]: [User-facing
description in past tense]`.
Examples: `fix: resolved token name display issue`, `feat: added dark
mode toggle`, `chore: updated dependencies`.
For non-user-facing changes, use `CHANGELOG entry: null`.
-->

CHANGELOG entry: null

## **Related issues**

<!--
AI agent: Replace with `Fixes: #[ISSUE_NUMBER]` using the actual issue
number you're implementing.
-->

Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-329

## **Manual testing steps**

<!--
AI agent: Write specific, contextual Gherkin steps based on what you
actually implemented.
Do NOT use generic placeholders like "my feature name". Be concrete
about the feature, scenario, and 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**
Successful Bitrise:
https://app.bitrise.io/build/d8ffdf86-23f8-4476-afef-1b4dda76a554
Successful CI (note there a some flaky flask tests):
https://github.com/MetaMask/metamask-mobile/actions/runs/22237789978?pr=25136
Successful build.yml:
https://github.com/MetaMask/metamask-mobile/actions/runs/22241562536

## **Pre-merge author checklist**

<!--
AI agent: Check ALL boxes in this section (mark all as [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).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

<!--
AI agent: Leave ALL boxes unchecked ([ ]) - these are for reviewers to
check, not the author.
-->

- [ ] 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 because it changes core CI/build infrastructure (Bitrise
Xcode stack, Ruby toolchain, and shared `setup-e2e-env` action), which
can break iOS/Android build and E2E workflows if the new environment has
compatibility issues.
> 
> **Overview**
> Updates CI and Bitrise build environments to support iOS SDK 26 by
moving Bitrise stacks to `osx-xcode-26.2.x` and aligning the Ruby
toolchain to `3.2.9` (including `.ruby-version`, `ios/Gemfile`,
`Gemfile.lock`, and GitHub Actions `ruby/setup-ruby`).
> 
> Refreshes GitHub Actions workflows to use `MetaMask/github-tools`
`setup-e2e-env@v1.7` across build and E2E pipelines, and updates the
Docker CI image’s ruby-build pin used to install the newer Ruby.
> 
> Bumps iOS/Bitrise build numbers from `3607` to `3821` (including
`bitrise.yml` envs and `CURRENT_PROJECT_VERSION` in the Xcode project).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
01116b4. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: tommasini <46944231+tommasini@users.noreply.github.com>
Co-authored-by: tommasini <tommasini15@gmail.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 the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

This PR adds **HeaderStandardAnimated**, a scroll-driven animated header
component to `app/component-library/components-temp/`. The header shows
a full title section (e.g. with `TitleStandard`) when at the top of the
scroll, and animates to a compact center title when the user scrolls
past that section.

**Reason for change:** Screens with a large title block (e.g. Perps
market detail) need a header that stays visible and collapses to a
compact title as the user scrolls. This component provides that pattern
with Reanimated-driven animation tied to scroll position.

**What changed:**

1. **HeaderStandardAnimated**
(`app/component-library/components-temp/HeaderStandardAnimated/`)
- New component that extends the header pattern from
`HeaderCompactStandard` and requires `scrollY` and `titleSectionHeight`
shared values to drive the center-title animation.
- Renders a `HeaderBase` with optional back/close buttons, title,
subtitle, or custom children. The center content is wrapped in an
`Animated.View` whose opacity and translateY are derived from scroll
(compact title appears when `scrollY >= titleSectionHeight`).
- Props: `scrollY`, `titleSectionHeight` (required), plus
title/subtitle/children, `onBack`/`backButtonProps`,
`onClose`/`closeButtonProps`,
`startButtonIconProps`/`endButtonIconProps`, `testID`, `twClassName`,
and other `HeaderBase` props.

2. **useHeaderStandardAnimated**
- New hook that returns `scrollY`, `titleSectionHeightSv`,
`setTitleSectionHeight`, and `onScroll` for use with
`HeaderStandardAnimated` and a `ScrollView`. Consumers call
`setTitleSectionHeight` from the title section’s `onLayout` and pass
`onScroll` to the `ScrollView`.

3. **Stories**
- `HeaderStandardAnimated.stories.tsx`: Default (title + back) and
WithSubtitle, both with scrollable content and the hook wiring.

4. **Unit tests**
- `HeaderStandardAnimated.test.tsx`: Rendering (title, subtitle,
children, testIDs via child prop objects), back/close button behavior
and callbacks, and `startButtonIconProps` priority. Uses mocked
Reanimated and safe area; shared values use a full
`SharedValue<number>`-shaped mock.
- `useHeaderStandardAnimated.test.ts`: Return shape, initial values, and
that `setTitleSectionHeight` and `onScroll` update the shared values.

5. **Storybook**
- `HeaderStandardAnimated` stories registered in
`.storybook/storybook.requires.js`.

## **Changelog**

This PR is not end-user-facing; it adds a new internal header component
for scroll-driven screens.

CHANGELOG entry: null

## **Related issues**

Fixes:
https://consensyssoftware.atlassian.net/browse/DSYS-287?atlOrigin=eyJpIjoiZThjYTU4Y2UyODcwNDJlMWJjMWQ0ZTQ1YmI0NjVhMGUiLCJwIjoiaiJ9

## **Manual testing steps**

```gherkin
Feature: HeaderStandardAnimated component

  Scenario: Default header with scroll shows compact title when scrolled
    Given the app is open with Storybook or a screen using HeaderStandardAnimated
    When the user views the header with a scrollable list below a title section
    Then the full title section is visible at the top
    When the user scrolls down past the title section
    Then a compact center title appears in the header and the transition is animated

  Scenario: Back and close buttons work
    Given a HeaderStandardAnimated with onBack and onClose
    When the user taps the back button
    Then onBack is invoked
    When the user taps the close button
    Then onClose is invoked
```

## **Screenshots/Recordings**

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

### **Before**

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

N/A – new component.

### **After**

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


https://github.com/user-attachments/assets/85c5f28c-86f4-4efb-89bf-26223de637f3

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

## **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 because this is additive and isolated to the component
library (`components-temp`) plus Storybook registration, with unit tests
covering basic rendering and button-callback behavior.
> 
> **Overview**
> Adds `HeaderStandardAnimated`, a new `components-temp` header wrapper
around `HeaderCompactStandard` that animates the centered title/subtitle
in based on `scrollY` and a measured `titleSectionHeight` shared value.
> 
> Introduces `useHeaderStandardAnimated` to provide the required
Reanimated `SharedValue`s and `onScroll` handler, along with Storybook
stories demonstrating the scroll behavior and unit tests validating
rendering and back/close/start-button callback precedence.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
e06f5c5. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Updates the `/create-bug` Claude Code skill command to include a full
root cause analysis workflow (Step 6) with three phases:
- **6a**: Investigate root cause — trace through the code to identify
exact files, lines, and logic
- **6b**: Identify regression PRs — check git history against previous
releases
- **6c**: Scope analysis — search for same pattern across codebase, file
separate bugs for other affected features

Also updates the comment format to include all required sections.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:

[MMQA-1523](https://consensyssoftware.atlassian.net/browse/MMQA-1523)

## **Manual testing steps**

```gherkin
Feature: Create Bug Skill Root Cause Analysis

  Scenario: user runs /create-bug and opts into root cause investigation
    Given user has Claude Code open in the metamask-mobile repo

    When user runs /create-bug and files a bug report
    And user opts into root cause investigation
    Then Claude performs root cause investigation (6a)
    And Claude identifies regression PRs by comparing release branches (6b)
    And Claude performs scope analysis to find same pattern elsewhere (6c)
    And Claude posts a comment with summary, regression PRs, error flow, scope of impact, key files, suggested fix, and related bug links
```

## **Screenshots/Recordings**

### **Before**

N/A

### **After**

Run `/create-bug` in Claude Code terminal and opt into root cause
investigation to see the full 3-phase workflow.

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

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

[MMQA-1523]:
https://consensyssoftware.atlassian.net/browse/MMQA-1523?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## **Description**

Phase 3 analytics migration (Batch 3-17): migrate Sample Feature's
components and hooks from `useMetrics`/`MetricsEventBuilder` to the new
`useAnalytics`/`AnalyticsEventBuilder` analytics system.

**Reason**: Deprecate MetaMetrics in favour of the shared analytics
utility and AnalyticsController.

**Changes**: `SamplePetNamesForm`, `SampleCounterPane`, and
`SampleFeatureDevSettingsEntryPoint` now use `useAnalytics()` from
`app/components/hooks/useAnalytics/useAnalytics` and
`createEventBuilder` from the hook instead of `useMetrics()` and
`MetricsEventBuilder`; test mocks updated to mock the `useAnalytics`
hook with a chainable builder instead of `useMetrics`.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-302 (Batch
3-17)

## **Manual testing steps**

```gherkin
Feature: Sample Feature analytics

  Scenario: user triggers a Sample Feature flow event
    Given app is open and user is in a Sample Feature flow

    When user performs an action that triggers analytics (e.g. increment counter, add pet name, navigate to sample feature)
    Then the event is tracked on Mixpanel
```

## **Screenshots/Recordings**

N/A – analytics migration, no UI change.

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

## **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: this is a refactor of analytics event building/tracking in a
non-production sample feature, with corresponding unit test updates.
Main risk is mis-tracked or missing events due to the new
builder/mocking semantics.
> 
> **Overview**
> Updates SampleFeature event tracking to use `useAnalytics()` and its
`createEventBuilder` instead of `useMetrics()`/`MetricsEventBuilder` in
`SampleCounterPane`, `SamplePetNamesForm`, and the dev-settings entry
point.
> 
> Adjusts analytics event definitions (`analytics/events.ts`) and
rewrites unit tests to mock/verify the new `useAnalytics` hook and
builder chaining, plus updates SampleFeature docs/e2e docs to refer to
**Analytics** (not MetaMetrics).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
2dce2e4. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**


Updates the Provider Selection modal UI with improved quote-driven
sorting, provider tags, skeleton loading states, and a redesigned
payment method banner.

### Payment Method Banner
- Replaced the plain "Quotes displayed for {paymentMethod}" text with a
full-width banner component featuring a circular payment method icon on
the left and the descriptive text left-aligned beside it, matching the
latest design spec.

### Quote-Based Provider Sorting
- Providers with quotes are now sorted by the API's `QuoteSortOrder`
reliability ranking (via `quotes.sorted`), placing the most reliable
provider at the top.
- Providers without quotes are pushed to the bottom of the list, sorted
alphabetically, with an "Other options" text separator between the two
groups.

### Skeleton Loading State
- When quotes are loading, the provider list is replaced with a skeleton
placeholder (5 rows) instead of showing unsorted providers with
individual loading spinners. Once quotes resolve, providers render in
their sorted order.

### Provider Tags
- Each provider can display one tag below its name: **Previously used**,
**Most reliable**, or **Best rate**.
- Tags use the quote's `metadata.tags` (`isMostReliable`, `isBestRate`)
from the API response, and `getOrdersProviders` from Redux to identify
previously used providers from completed order history.
- Precedence when a provider qualifies for multiple tags: Previously
used > Most reliable > Best rate.

### Conditional Back Button
- The header back arrow is now only shown when the Payment Selection
modal is in the navigation stack (i.e., the user navigated from payment
selection to provider selection). When the provider modal is opened
directly (e.g., from error recovery or token-not-available flows), the
back button is hidden since there's nothing to go back to.

## Changed Files
- `ProviderSelection.tsx` — Banner, skeleton, sorting, tags, conditional
back button
- `ProviderSelectionModal.tsx` — Passes `ordersProviders` from Redux,
`showBackButton` from navigation state
- `ProviderSelection.test.tsx` — Updated test for skeleton loading
behavior
- `en.json` — Added i18n strings: `other_options`, `previously_used`,
`best_rate`, `most_reliable`


<!--
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: Updates ramp provider selection modal UI

## **Related issues**

Fixes:

https://consensyssoftware.atlassian.net/browse/TRAM-3307
https://consensyssoftware.atlassian.net/browse/TRAM-3187

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

![new-provider-modal](https://github.com/user-attachments/assets/4efe134f-80ba-4c65-9967-662f23479eec)


<img width="353" height="355" alt="Screenshot 2026-02-28 at 5 30 22 AM"
src="https://github.com/user-attachments/assets/5b089b35-d302-4c82-8ef5-994e697bac4a"
/>
<img width="360" height="754" alt="Screenshot 2026-02-28 at 5 30 01 AM"
src="https://github.com/user-attachments/assets/cc720ccf-02d6-4681-ac88-303b59775d51"
/>
<img width="353" height="747" alt="Screenshot 2026-02-28 at 5 29 14 AM"
src="https://github.com/user-attachments/assets/04cbedf4-d233-4576-8bd8-c79c6ce0115d"
/>
<img width="341" height="742" alt="Screenshot 2026-02-28 at 5 29 00 AM"
src="https://github.com/user-attachments/assets/ec1e2031-0c01-4c59-85ad-e9fdccaddabc"
/>



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

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [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.

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes provider ordering/visibility and quote presentation logic in
the provider selection flow (sorting, skeleton states, tags, and
back-button behavior), which could affect user selection and navigation
in edge cases. No security- or data-sensitive logic is introduced.
> 
> **Overview**
> Updates `ProviderSelection` to be *quote-driven*: providers with
successful quotes are sorted by the API reliability order and shown
above an **“Other options”** separator, while providers without quotes
are pushed below and alphabetized.
> 
> Replaces the prior “show providers while loading” behavior with a
dedicated skeleton list, updates the payment-method header to a banner
with an icon, and adds per-provider tags (**Previously used**, **Most
reliable**, **Best rate**) derived from order history and quote
metadata.
> 
> `ProviderSelectionModal` now conditionally shows the back button only
when the payment selection modal exists in the navigation stack and
passes `ordersProviders` from Redux; tests/snapshots and i18n strings
were updated accordingly.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
790f8c3. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Phase 3 analytics migration (Batch 3-13): migrate Network Management's
components and hooks from `useMetrics` to the new analytics system
(`useAnalytics`).

**Reason**: Deprecate MetaMetrics in favour of the shared analytics
utility and AnalyticsController.

**Changes**: `ManageNetworks`, `NetworkMultiSelector`, `NetworkManager`,
and `MultiRpcModal` now use `useAnalytics` from
`app/components/hooks/useAnalytics/useAnalytics` and import
`MetaMetricsEvents` from `app/core/Analytics`; test mocks updated to
mock `useAnalytics` instead of `useMetrics`.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-302 (Batch
3-13)

## **Manual testing steps**

```gherkin
Feature: Network Management analytics

  Scenario: user triggers a network management flow event
    Given app is open and user is in a network management flow

    When user performs an action that triggers analytics (e.g. switch network, open network manager, accept multi-RPC modal)
    Then the event is tracked on Mixpanel
```

## **Screenshots/Recordings**

N/A – analytics migration, no UI change.

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

## **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 only swaps analytics plumbing; primary risk
is missing/misnamed events if the new `useAnalytics` hook or
`MetaMetricsEvents` import differs from the old `useMetrics` behavior.
> 
> **Overview**
> Switches Network Management UI surfaces (e.g., `ManageNetworks`,
`NetworkManager`, `NetworkMultiSelector`, and `MultiRpcModal`) from
`useMetrics` to the shared `useAnalytics` hook while keeping existing
event tracking calls (`trackEvent`/`createEventBuilder`).
> 
> Updates unit tests to mock `useAnalytics` instead of `useMetrics`, and
adjusts event constant imports/expectations to use `MetaMetricsEvents`
from `core/Analytics/MetaMetrics.events` where applicable.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3c6fb53. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
#26484)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

**Reason for the change:**
The `SwitchAccountTypeModal` component was using the `useRoute()` hook
internally to access route parameters. This approach has several
drawbacks:
- Tightly couples the component to the navigation context
- Makes type derivation less explicit (required unsafe type assertion:
`(route?.params as { address: Hex })?.address`)
- Reduces testability as tests needed to mock the `useRoute` hook
globally
- No graceful handling when address parameter is missing

**Improvement/Solution:**
- Refactored `SwitchAccountTypeModal` to receive `route` as a prop
instead of calling `useRoute()` internally
- Added proper TypeScript interfaces:
`SwitchAccountTypeModalRouteParams`, `SwitchAccountTypeModalParamList`,
and `SwitchAccountTypeModalProps`
- Added fallback UI with "No account selected" message when no address
is available from route params
- Added missing `key` prop to `AccountNetworkRow` component in the map
function (fixes React key warning)
- Significantly expanded test coverage:
- Organized tests into logical describe blocks (`rendering`, `route
params handling`, `navigation`, `hook integration`)
  - Added tests for empty network list, multiple networks, loading state
  - Added tests for address matching/non-matching scenarios
  - Added test for hook integration to verify correct address is passed

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: N/A (internal refactoring)

## **Manual testing steps**

```gherkin
Feature: Switch Account Type Modal (EIP-7702)

  Scenario: User opens switch account type modal with valid address
    Given the user has an account upgraded to a smart account on a supported network
    And the user is viewing account details

    When user taps on "Switch account type"
    Then user should see the Switch Account Type modal
    And user should see their account name
    And user should see the list of networks where the account is upgraded
    And each network row should show "Smart account" status

  Scenario: User switches back to regular account
    Given the user is viewing the Switch Account Type modal
    And the account is currently a smart account on Sepolia

    When user taps "Switch back" on the Sepolia row
    Then the account should be downgraded to a regular account on Sepolia

  Scenario: User navigates back from modal
    Given the user is viewing the Switch Account Type modal

    When user taps the back button
    Then the modal should close
    And user should return to the previous screen

  Scenario: Modal shows loading state while fetching network data
    Given the network data is still being fetched

    When user opens the Switch Account Type modal
    Then user should see a loading spinner
    And the network list should not be visible
```

## **Screenshots/Recordings**

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

### **Before**

N/A - No visual changes (except for new fallback state)

### **After**

N/A - No visual changes (except for new fallback state when no address
is available)

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

## **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.
…d assertions (#26710)

## **Description**

Updates `amount-keyboard.test.tsx` to use `mockTheme` design token
references instead of hardcoded hex values in test assertions,
unblocking the design tokens upgrade to v8.2.1 (#26639).

**What this PR does:**
- Replaces hardcoded color hex values (`#b7bbc8`, `#121314`, `#ca3542`)
with `mockTheme.colors.*` references in test assertions for
`getBackgroundColor` and the disabled Next button

**Why this is an improvement:**
- Makes tests resilient to design token value changes
- Ensures tests validate correct token usage rather than specific hex
values
- Aligns with design system best practices
- Follows the same pattern established in #26657

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Dependency of: #26639
Related: #26657

## **Manual testing steps**

```gherkin
Scenario: Verify updated tests pass
  Given the repository with design tokens v8.2.1
  When I run app/components/Views/confirmations/components/send/amount/amount-keyboard/amount-keyboard.test.tsx
  Then all 6 tests should pass
```

## **Screenshots/Recordings**

N/A - Test-only changes

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

## **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**
> Test-only updates that swap fixed hex assertions for `mockTheme` token
references, reducing brittleness during design token upgrades. No
production logic changes; risk limited to potential mismatches with
token names/structure.
> 
> **Overview**
> Updates `amount-keyboard.test.tsx` to stop asserting on hardcoded hex
colors for the disabled Next/Continue button and `getBackgroundColor`
output.
> 
> Assertions now reference `mockTheme.colors.text.*` and
`mockTheme.colors.error.*`, making the tests resilient to design token
value changes while still verifying the correct token is used.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
95e250e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Fixes mobile CI build failures caused by invalid action tag references
in workflow files.

Several workflows were using
`MetaMask/github-tools/.github/actions/setup-e2e-env@v1.7`, but `v1.7`
does not exist in `MetaMask/github-tools` (valid refs include `v1` and
`v1.7.0`).
This PR updates those references to `@v1` to restore build job setup
resolution.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: N/A

## **Manual testing steps**

```gherkin
Feature: CI workflow setup action reference

  Scenario: Build jobs resolve setup-e2e-env action
    Given workflow files reference setup-e2e-env@v1
    When CI runs Build Android E2E APKs and Build iOS E2E Apps jobs
    Then job setup resolves the action successfully
    And CI no longer fails with "unable to find version v1.7"

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: jvbriones <jvbriones@users.noreply.github.com>
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Adds a "View PIN" option to the Card Home manage card section, allowing
users to securely view their card PIN through a PCI-compliant
image-based display.

**Why**: Users need to retrieve their card PIN (e.g. for ATM use or
in-store transactions). The PIN is never transmitted as plain text — it
is rendered as an image via a time-limited, single-use secure token from
the `POST /v1/card/pin/token` endpoint, ensuring PCI compliance.

**What changed**:
- **New SDK method** (`CardSDK.generateCardPinToken`): Calls `POST
/v1/card/pin/token` with optional `customCss` for theming the PIN image.
Mirrors the existing `generateCardDetailsToken` pattern with proper
error handling.
- **React Query integration**: New `cardQueries.pin` key factory and
`pinTokenMutationFn` following the established React Query patterns from
the codebase.
- **`useCardPinToken` hook**: Wraps `useMutation` for PIN token
generation. Automatically applies dark/light theme-aware `customCss`
(background and text colors) so the PIN image matches the app
appearance.
- **`ViewPinBottomSheet` component**: Displays the PIN image in a bottom
sheet with a skeleton loader and `CardScreenshotDeterrent` enabled to
prevent screenshots of sensitive data.
- **`CardHome` integration**: New `ManageCardListItem` for "View PIN"
with biometric authentication gating (matching the "View Card Details"
flow). Falls back to password bottom sheet with a PIN-specific
description when biometrics are not configured. Visible for US users
(all card types) and international users with non-virtual cards.
- **Analytics**: Added `VIEW_PIN_BUTTON` action to `CardActions` enum,
tracked via `CARD_BUTTON_CLICKED` event.
- **Navigation**: Registered `CardViewPinModal` route and added the
`ViewPinBottomSheet` screen to `CardModalsRoutes`.
- **Tests**: Added tests across 5 files — SDK method tests, query layer
tests, hook tests, bottom sheet snapshot/render tests, and 11 new
CardHome integration tests covering visibility conditions, biometric
auth flow, password fallback, and loading guards.

## **Changelog**

CHANGELOG entry: Added "View PIN" option to the Card Home screen,
allowing users to securely view their card PIN via biometric or password
authentication.

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: View card PIN

  Scenario: View PIN button is visible for eligible users
    Given the user is authenticated with an active card
    And the user is a US user OR has a non-virtual (metal) card
    When the user navigates to the Card Home screen
    Then a "View PIN" option is displayed in the manage card section

  Scenario: View PIN button is hidden for international virtual card users
    Given the user is an international user with a virtual card
    When the user navigates to the Card Home screen
    Then the "View PIN" option is NOT displayed

  Scenario: View PIN with biometric authentication
    Given the user has biometric authentication configured
    When the user taps "View PIN"
    Then a biometric prompt is displayed
    And upon successful authentication, the card PIN is shown as an image in a bottom sheet
    And the PIN image matches the current theme (light/dark background)

  Scenario: View PIN with password fallback
    Given the user does NOT have biometric authentication configured
    When the user taps "View PIN"
    Then a password bottom sheet appears with the message "Enter your wallet password to view your card PIN."
    And upon entering the correct password, the card PIN is shown in a bottom sheet

  Scenario: View PIN biometric cancellation
    Given the user has biometric authentication configured
    When the user taps "View PIN" and cancels the biometric prompt
    Then no PIN is displayed and the user returns to Card Home

  Scenario: View PIN error handling
    Given the user taps "View PIN" and authentication succeeds
    When the PIN token request fails
    Then an error toast is shown with "Failed to load PIN. Please try again."

  Scenario: Screenshot prevention
    Given the card PIN bottom sheet is displayed
    When the user attempts to take a screenshot
    Then the screenshot deterrent is active and prevents capture of the PIN
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots or recordings of the View PIN flow
-->

### **Before**

<!-- Card Home without View PIN option -->

### **After**

<!-- Card Home with View PIN option + View PIN bottom sheet -->

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

## **Pre-merge reviewer checklist**

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


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Adds a new authenticated flow to fetch and display a sensitive card
PIN image via a new SDK endpoint and modal UI, with biometric/password
gating and error handling. Risk is mainly around auth/error-state
handling and the new network call/token lifecycle.
> 
> **Overview**
> Adds a new **“View PIN”** manage-card action on `CardHome`, shown only
for eligible users (authenticated, has a card, not loading; US users or
non-virtual cards), gated by `reauthenticate()` with a
password-bottom-sheet fallback when biometrics aren’t configured and
guarded against concurrent loads.
> 
> Introduces PIN-token generation plumbing:
`CardSDK.generateCardPinToken` calling `POST /v1/card/pin/token`, React
Query `cardQueries.pin` + `useCardPinToken` (theme-aware `customCss`),
plus a new `ViewPinBottomSheet` modal route
(`Routes.CARD.MODALS.VIEW_PIN`) that renders the PIN image with a
skeleton loader and `CardScreenshotDeterrent` enabled.
> 
> Updates analytics (`CardActions.VIEW_PIN_BUTTON`), test IDs, and
English strings, and adds comprehensive tests for the SDK/query/hook,
the new bottom sheet (snapshot/render), and CardHome
visibility/auth/error flows.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
514ae0c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
This PR aims to add the stocks section in the explore page. In order to
get this PR to the finish line, I have:
- Updated the core package
[here](MetaMask/core#8019) to fix an issue with
the `limit` param in the search endpoint request and support for a
higher limit when calling with the QueryString `Ondo`
- Asked the design team to add the corporate icon
[here](#26492)
- Raised the following issues in api-platform and got a fix
  - https://consensys.slack.com/archives/C03MLR70YSK/p1771489684959419
  - https://consensys.slack.com/archives/C03MLR70YSK/p1771850443811719
- Added Geo-blocking (hardcoded for now but it should live on the API at
some point)
- Modified order of sections in explore page following @chaoticgoodpanda
guidance
- Modified predictions section to not be a carousel

<!--
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: added stocks section to explore page

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/ASSETS-2635 &
https://consensyssoftware.atlassian.net/browse/ASSETS-2632

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

[Here](https://consensys.slack.com/archives/C07NF2K42LE/p1771849520486939)
is a full video explaining the e2e functionality.




https://github.com/user-attachments/assets/ac8c7c52-30c6-4913-9e69-7b8fe8e0db52





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

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

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


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Adds a new Explore section and full-screen view backed by a new search
hook with geo-restriction logic and new navigation routes, which could
affect what data users see and how filtering/refetch behaves. Refactors
Trending Tokens full view into shared layout/components, so regressions
could impact existing trending-token filtering UI and bottom sheets.
> 
> **Overview**
> Adds a new **Stocks** section to Explore, including a new
`RWATokensFullView` screen/route and `useRwaTokens` hook that queries
Ondo RWA assets (with production geo-blocking) and supports search,
network, and sort filters.
> 
> Refactors `TrendingTokensFullView` into the `UI/Trending` area and
introduces shared `TokenListPageLayout`, `FilterBar`, and
`useTokenListFilters` to unify header/search/filter behavior across
token list full views; updates the network bottom sheet to take an
explicit `networks` prop and adjusts token sorting to push missing
market data to the end. Explore/QuickActions/predictions presentation,
navigation, mocks, and smoke tests are updated to include the new Stocks
section and new predictions row rendering.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
2be0c5a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Bump bridge controller

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

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Updates a core bridging dependency; while the diff is lockfile-only,
the new `@metamask/bridge-controller` version could change bridge
quoting/execution behavior at runtime.
> 
> **Overview**
> Bumps `@metamask/bridge-controller` from `^67.3.0` to `^67.4.0` in
`package.json`.
> 
> Updates `yarn.lock` to resolve the new `67.4.0` package (including
updated resolution and checksum).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b400db1. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

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

- Redact sensitive data from SDKConnectV2 / MWP debug and error logs
- Add `redactUrl` utility to strip query/fragment params from deeplink
URLs before logging
- Reduce message payload logging to method + id metadata only

## **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:
[WAPI-1117](https://consensyssoftware.atlassian.net/browse/WAPI-1117)

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

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


[WAPI-1117]:
https://consensyssoftware.atlassian.net/browse/WAPI-1117?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: changes are limited to logging/error messages in
SDKConnectV2, with minimal behavioral impact aside from altered log
output and one test expectation.
> 
> **Overview**
> Prevents sensitive SDKConnectV2/MWP connection parameters from being
written to logs by introducing `redactUrl()` and using it when
throwing/logging deeplink handling errors.
> 
> Reduces verbosity of connection message logging by logging only
JSON-RPC `method` and `id` (instead of full payloads), and adjusts
connect-deeplink success logging to avoid dumping full `ConnectionInfo`.
Updates the `handleMwpDeeplink` non-string URL test to expect the new
redacted/invalid URL message.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
dd3a3d0. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…26773)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

The DeFi homepage section was returning null (hiding entirely) when the
API responded with an error (e.g. 501). This matched the behavior for
the empty-data case, but the acceptance criteria requires showing a
retry UI on API failure — consistent with how the Predictions and Tokens
sections handle errors.

**This PR:**

- Separates error and empty handling in DeFiSection: errors now render
the shared ErrorState component with a retry button, while empty data
(200 with 0 positions) still hides the section.

- Replaces the no-op refresh function with a real one that calls
DeFiPositionsController._executePoll(), so both the retry button and
pull-to-refresh actually re-fetch.

- Updates tests to assert the new error UI behavior and verify retry
triggers _executePoll.

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: Fixed DeFi homepage section to show retry UI when API
request fails instead of hiding the section

## **Related issues**

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

## **Manual testing steps**

```gherkin
Feature: DeFi section error handling on homepage

  Scenario: user sees retry UI when DeFi API fails
    Given the DeFi positions API returns a 501 error
    And the user navigates to the homepage

    When the homepage loads
    Then the DeFi section displays with a "Unable to load" message and a "Retry" button

  Scenario: user retries after API failure
    Given the DeFi section is showing the error/retry UI

    When user taps the "Retry" button
    Then the DeFi positions are re-fetched from the API

  Scenario: DeFi section hidden when no positions exist
    Given the DeFi positions API returns 200 with no positions

    When the homepage loads
    Then the DeFi section is not displayed
```

## **Screenshots/Recordings**

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

### **Before**

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

### **After**
<img width="377" height="613" alt="Screenshot 2026-03-02 at 13 21 18"
src="https://github.com/user-attachments/assets/55d6b7e4-2187-4824-87c9-fa1161439e70"
/>

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

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [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.

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes homepage DeFi rendering and refresh behavior to call
`DeFiPositionsController._executePoll()`, which could affect polling
frequency and error-handling paths. Uses a controller internal method,
so regressions are possible if controller APIs change.
> 
> **Overview**
> DeFi homepage section no longer disappears on API errors: when
`hasError` (and not loading) it now renders the shared `ErrorState` with
a Retry button while still hiding the section for the *empty data* case.
> 
> The section’s `refresh` handler (used by pull-to-refresh and Retry) is
wired to `Engine.context.DeFiPositionsController._executePoll()` to
actively re-fetch positions.
> 
> Tests were updated to validate the new error UI and to assert that
both Retry and the exposed `ref.refresh()` call `_executePoll()`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
296c330. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Fix recipient list display in send flow.

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

## **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**
<img width="396" height="847" alt="Screenshot 2026-03-02 at 5 04 59 PM"
src="https://github.com/user-attachments/assets/3b4e8f2d-448c-41a2-bf53-55f2ba2d967c"
/>

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

## **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-only change that swaps the row wrapper component and
tweaks padding/accessibility; main risk is minor touch/spacing
regressions in the recipient list.
> 
> **Overview**
> Fixes the recipient list row rendering in the send/confirmation flow
by replacing the design-system `ButtonBase` wrapper with React Native
`Pressable`.
> 
> Updates the row styling to include horizontal padding (`px-4`) and
explicitly sets `accessibilityRole="button"` while preserving the
existing pressed/selected background behavior.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
e5b33b4. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **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?
-->
- Skip trending tests to unblock pipeline
## **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**

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

## **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: this only disables a smoke test, reducing CI coverage but
not affecting production code paths.
> 
> **Overview**
> Disables the Trending Feed smoke test that navigates through each
section’s `View All` full views (and back to the feed) by marking the
spec as `it.skip`, to unblock the pipeline.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
5f8dd44. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@chloeYue chloeYue removed request for a team March 13, 2026 09:13
@chloeYue chloeYue added the skip-sonar-cloud Only used for bypassing sonar cloud when failures are not relevant to the changes. label Mar 13, 2026
@codecov-commenter
Copy link

Codecov Report

❌ Patch coverage is 90.82569% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.50%. Comparing base (444b662) to head (5078ae1).
⚠️ Report is 259 commits behind head on stable.

Files with missing lines Patch % Lines
...-library/components-temp/HeaderRoot/HeaderRoot.tsx 92.00% 1 Missing and 1 partial ⚠️
.../HeaderStandardAnimated/HeaderStandardAnimated.tsx 84.61% 0 Missing and 2 partials ⚠️
...eaderStandardAnimated/useHeaderStandardAnimated.ts 87.50% 1 Missing ⚠️
...ts/Form/TextField/foundation/Input/Input.styles.ts 80.00% 1 Missing ⚠️
app/components/Nav/App/App.tsx 50.00% 1 Missing ⚠️
...ponents/UI/BalanceEmptyState/BalanceEmptyState.tsx 66.66% 0 Missing and 1 partial ⚠️
...ridge/components/GaslessQuickPickOptions/index.tsx 92.85% 0 Missing and 1 partial ⚠️
...slessQuickPickOptions/useTrackInputAmountChange.ts 83.33% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           stable   #27086      +/-   ##
==========================================
+ Coverage   81.21%   81.50%   +0.28%     
==========================================
  Files        4462     4621     +159     
  Lines      116332   121060    +4728     
  Branches    25096    26604    +1508     
==========================================
+ Hits        94482    98671    +4189     
- Misses      15250    15451     +201     
- Partials     6600     6938     +338     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

chloeYue
chloeYue previously approved these changes Mar 13, 2026
@chloeYue
Copy link
Contributor

policy-bot: approve

@chloeYue chloeYue added the team-bots Bot team (for MetaMask Bot, Runway Bot, etc.) label Mar 13, 2026
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
Increase JS bundle 1 MB
<!--
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**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: workflow-only change that just relaxes the CI bundle-size
gate by 1 unit and doesn’t affect runtime code.
> 
> **Overview**
> **CI bundle-size gating has been relaxed slightly.** The
`js-bundle-size-check` step in `.github/workflows/ci.yml` now allows an
iOS `main.jsbundle` size threshold of `53` instead of `52` when running
`./scripts/js-bundle-stats.sh`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3c0f0a4. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@github-actions
Copy link
Contributor

🔍 Smart E2E Test Selection

⏭️ Smart E2E selection skipped - base branch is not main (base: stable)

All E2E tests pre-selected.

View GitHub Actions results

@sonarqubecloud
Copy link

@github-actions
Copy link
Contributor

⚠️ E2E Fixture Validation — Structural changes detected

Category Count
New keys 68
Missing keys 11
Type mismatches 0
Value mismatches 6 (informational)

The committed fixture schema is out of date. To update, comment:

@metamaskbot update-mobile-fixture

View full details | Download diff report

@chloeYue chloeYue merged commit e7ebdc1 into stable Mar 13, 2026
119 of 126 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators Mar 13, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.69.0 Issue or pull request that will be included in release 7.69.0 size-XL skip-sonar-cloud Only used for bypassing sonar cloud when failures are not relevant to the changes. team-bots Bot team (for MetaMask Bot, Runway Bot, etc.)

Projects

None yet

Development

Successfully merging this pull request may close these issues.