Skip to content

[pull] main from MetaMask:main#505

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

[pull] main from MetaMask:main#505
pull[bot] merged 67 commits into
Reality2byte:mainfrom
MetaMask:main

Conversation

@pull

@pull pull Bot commented Feb 7, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


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

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

runway-github Bot and others added 30 commits January 30, 2026 12:49
…nd list padding fix cp-7.64.0 (#25422)

- fix(perps): watchlist and explore header and list padding fix
cp-7.64.0 (#25407)

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

- Fix header font weight to match Figma design specs (500 Medium instead
of 700
Bold)
- Implement dynamic header padding based on context (balance visibility,
watchlist
presence)
- Remove redundant horizontal padding from Watchlist component
(inherited from
parent)
- Increase explore market row vertical padding from 6px to 16px
- Add horizontal margin to "See All Perps" button
Changes
Font Weight:
- Changed Watchlist and Explore headers from TextVariant.HeadingMD to
TextVariant.BodyLGMedium
Dynamic Header Padding:
- Watchlist header: 16px/4px (no balance) or 24px/4px (with balance)
- Explore header: 16px/4px (no balance), 24px/4px (with balance), or
20px/8px (below
watchlist)
Padding Cleanup:
- Removed duplicate paddingHorizontal: 16 from watchlist header/list
(inherits from
parent)
- Updated explore market row paddingVertical from 6px to 16px
  - Added marginHorizontal: 16 to "See All Perps" button

## **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: Fix watchlist and explore header and list padding

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

- Verify Watchlist/Explore headers display with Medium font weight (500)
- Verify header padding adjusts correctly when balance is empty vs
non-empty
- Verify Explore header spacing changes when Watchlist is visible vs
hidden
  - Verify market row spacing matches Figma spec

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

- [ ] 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 UI/layout refactors, but it changes how the Perps tab renders
the watchlist and removes the pressable watchlist header in
`PerpsWatchlistMarkets`, which could impact navigation/interaction if
relied on elsewhere.
> 
> **Overview**
> Aligns Perps home/tab UI spacing with updated design specs by
switching section headers to `TextVariant.BodyLGMedium`, increasing
header bottom margins, and adjusting row/button padding.
> 
> Refactors `PerpsTabView` to render the watchlist inline (using
`PerpsMarketRowItem`) and apply *dynamic* explore header padding based
on balance visibility and whether the watchlist is present; also adds
horizontal margin to the "See all perps" button.
> 
> Simplifies `PerpsWatchlistMarkets` by removing the pressable
header/chevron navigation and updating header spacing, and updates
tests/mocks (including `usePerpsLivePrices` and market row selectors) to
match the new rendering.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0350f76. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[74f8159](74f8159)

Co-authored-by: Matt D. <85914066+geositta@users.noreply.github.com>
…domains in analytics cp-7.64.0 (#25448)

- feat: return actual host for known public domains in analytics
cp-7.64.0 (#25385)

## **Description**

Improves analytics data quality by returning the actual domain host for
known public RPC providers instead of masking them as 'custom'.

- Add `isPublicRpcDomain` helper in `rpc-domain-utils.ts` that checks if
an RPC URL has a known public domain
- Simplify `isPublicEndpointUrl` by using the new helper
- `sanitizeRpcUrl` now returns the actual host (e.g.,
`mainnet.infura.io`, `eth-mainnet.alchemyapi.io` or any RPC from
chainid.network) for known public domains, improving the accuracy of
`rpc_domain` in analytics events

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/WPC-342

## **Manual testing steps**

```gherkin
Feature: RPC domain analytics

  Scenario: Verify rpc_domain shows actual host when switching to public RPC via banner
    # Setup - Add Ink network with local RPC
    Given user navigates to Settings → Networks → Add Network
    And user adds Ink network (Chain ID: 57073) with local RPC endpoint: http://127.0.0.1:8545
    And user also adds public RPC endpoint: https://rpc-qnd.inkonchain.com
    And user sets the local RPC as the default endpoint
    And user switches to Ink network
    
    # Trigger degraded state
    When user disconnects local RPC (or it becomes unavailable)
    And user waits for banner showing "Still connecting to Ink..."
    
    # Trigger RPC update from banner
    Then the "Update RPC" button appears on the banner
    When user clicks "Update RPC" on the banner
    And user is navigated to Edit Network screen
    And user switches default RPC to https://rpc-qnd.inkonchain.com
    
    # Verify analytics in Segment
    When user checks Segment dashboard for "Network Connection Banner RPC Updated" event
    Then the event property from_rpc_domain should be "custom" (local RPC is private)
    And the event property to_rpc_domain should be "rpc-qnd.inkonchain.com" (known public domain)

  Scenario: Verify rpc_domain for Infura networks using Switch to MetaMask default
    # Setup - Configure Arbitrum with local RPC
    Given user starts a local Ganache server: npx ganache --chain.chainId 42161
    And user navigates to Settings → Networks → Arbitrum One
    And user adds a new RPC endpoint: http://127.0.0.1:8545
    And user sets the local RPC as the default endpoint
    
    # Trigger degraded state
    When user stops the Ganache server (Ctrl+C)
    And user waits for banner showing "Still connecting to Arbitrum One..."
    
    # Switch to Infura via banner button
    Then the "Switch to MetaMask default RPC" button appears on the banner
    When user clicks "Switch to MetaMask default RPC"
    Then the toast "Updated to MetaMask default" appears
    
    # Verify analytics
    When user checks Segment for "Network Connection Banner Switch To MetaMask Default RPC Clicked"
    Then rpc_domain should be "custom" (the local RPC being switched from)
```

## **Screenshots/Recordings**

N/A - Internal analytics improvement, no UI changes.

### **Before**

### **After**

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **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**
> Mainly affects analytics sanitization/allowlisting for RPC endpoint
URLs, which has privacy implications if misclassified. Also adds a new
async init step during `Engine` startup (non-blocking) that could
surface new runtime errors (captured to Sentry).
> 
> **Overview**
> **Improves RPC-domain analytics classification.** Adds
`isPublicRpcDomain` in `rpc-domain-utils.ts` to treat endpoints with
known public provider domains (from cached Safe Chains data and
allowlisted providers like Infura/Alchemy) as public, while still
excluding localhost/invalid/unknown domains.
> 
> `isPublicEndpointUrl` (network-controller utils) now delegates to this
helper, and `Engine` asynchronously warms the RPC provider domain cache
on startup (errors reported via Sentry). Tests are expanded to cover
localhost/invalid URLs and known public providers (e.g., Alchemy).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
c976dd0. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[910d769](910d769)

Co-authored-by: cryptodev-2s <109512101+cryptodev-2s@users.noreply.github.com>
…5459)

- feat: implement Url Bar Button Updates (#25418)

## **Description**

This PR updates the WebBrowser URL bar button interactions to match the
new design specifications and fix the "3 X buttons" issue.

**Jira Ticket:** https://consensyssoftware.atlassian.net/browse/MCWP-310

### Problem
Previously, the URL bar could display up to 3 "X" buttons
simultaneously:
1. Top-left back button (always an X)
2. Clear input button (CircleX inside input)
3. Cancel button (could be X when `showCloseButton` was true)

This created a confusing user experience where multiple
identical-looking buttons performed different actions.

### Solution
- **Back Button**: Changed icon from `X` to `<` (ArrowLeft) and hidden
when URL input is focused
- **Cancel Button**: Now always displays "Cancel" text (never an X
icon), styled to match the Explore search bar
- **Clear Button**: Unchanged - CircleX inside input to clear text
(already correct)
- Removed the `showCloseButton` prop that was causing the Cancel button
to show an X icon in certain flows

### Button Behavior Summary

| State | Before | After |
|-------|--------|-------|
| **Not focused** | X button (left) + Tabs + Account | `<` button (left)
+ Tabs + Account |
| **Focused** | X button (left) + Clear (X) + Cancel (X or text) | Clear
(X) + Cancel (text) |

## **Changelog**

CHANGELOG entry: Updated browser URL bar buttons - back button now shows
chevron icon and hides when typing, cancel button always shows text
instead of X icon

## **Related issues**

Fixes: <!-- Add issue number if applicable -->

## **Manual testing steps**

```gherkin
Feature: Browser URL Bar Button Interactions

  Scenario: User sees back button when browsing
    Given the user has opened a website in the browser
    And the URL bar is not focused

    When user views the browser top bar
    Then the back button should display a "<" chevron icon on the left
    And the tabs button and account button should be visible on the right

  Scenario: User focuses on URL bar to search
    Given the user has opened a website in the browser
    And the URL bar is not focused

    When user taps on the URL bar
    Then the back button should be hidden
    And the "Cancel" text button should appear on the right
    And the clear (X) button should appear inside the input field

  Scenario: User clears search input
    Given the user has focused on the URL bar
    And has typed some text

    When user taps the clear (X) button inside the input
    Then the text should be cleared
    And the URL bar should remain focused

  Scenario: User cancels search
    Given the user has focused on the URL bar

    When user taps the "Cancel" button
    Then the URL bar should lose focus
    And the back button "<" should reappear
    And the current page URL should be restored

  Scenario: User navigates back to Explore
    Given the user has opened a website in the browser
    And the URL bar is not focused

    When user taps the back button "<"
    Then user should be navigated back to the Explore/Trending page
```

## **Screenshots/Recordings**

### **Before**

<img width="450" height="316" alt="Screenshot 2026-01-29 at 16 22 49"

src="https://github.com/user-attachments/assets/3dba6e1b-9f3f-4dae-8f9c-17512524bf87"
/>

- Back button showed "X" icon
- Cancel button could show "X" icon (when opened from Trending)
- 3 X buttons could be visible simultaneously when URL bar was focused

### **After**

- Back button shows "<" chevron icon
- Back button hides when URL bar is focused
- Cancel button always shows "Cancel" text
- Only the clear button (inside input) shows an X when focused




https://github.com/user-attachments/assets/68be1901-f419-4d1e-891f-6d976709a610

<!-- Add actual screenshots/recordings here -->

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

---

## Files Changed

| File | Change |
|------|--------|
| `BrowserTab.tsx` | Changed back button icon to ArrowLeft, hide when
URL bar focused |
| `BrowserUrlBar.tsx` | Removed `showCloseButton` prop, simplified
`renderRightButton` |
| `BrowserUrlBar.types.ts` | Removed `showCloseButton` prop type |
| `BrowserUrlBar.styles.ts` | Updated `cancelButtonText` to use default
text color with medium weight |
| `BrowserUrlBar.test.tsx` | Updated tests for removed `showCloseButton`
functionality |
| `BrowserTab/index.test.tsx` | Added test for back button visibility |
| `RemoteImage/index.test.tsx` | Fixed flaky test by properly cleaning
up Dimensions mock |


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk UI behavior/styling changes in the in-app browser header plus
test updates; main risk is minor UX regressions around focus state and
navigation affordances.
> 
> **Overview**
> **Browser URL bar button behavior is simplified to match new
designs.** `BrowserUrlBar` no longer supports `showCloseButton`; when
focused it always shows a text **Cancel** button (with updated styling)
instead of sometimes rendering a close icon.
> 
> **Browser header navigation icon is updated.** `BrowserTab` replaces
the left-side close icon with an `ArrowLeft` button and hides it while
the URL bar is focused.
> 
> Tests and snapshots are updated accordingly, and `RemoteImage` tests
now properly restore the `Dimensions.get` spy to reduce test flakiness.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
be165e0. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[6471fcd](6471fcd)

Co-authored-by: Aslau Mario-Daniel <marioaslau@gmail.com>
…positions cp-7.63.0 cp-7.64.0 cp-7.62.2 (#25457)

- fix(perps): potential rate limit on close positions cp-7.63.0
cp-7.64.0 cp-7.62.2 (#25438)

## **Description**

Complete the 429 rate limiting fix for position management operations.
The previous fix (commit `425beaead7`) only addressed
`updatePositionTPSL()`. This PR extends the fix to `closePosition()`,
`closePositions()`, and `updateMargin()` methods.

**Problem:** These methods were using `skipCache: true` which forced
REST API calls on every operation, leading to 429 rate limiting errors
during prolonged app usage.

**Solution:**
- Remove `skipCache: true` from `closePositions()` and `updateMargin()`
to use WebSocket cache
- For `closePosition()`, add optional `position` parameter so callers
can pass the live WebSocket position directly, avoiding the need to
fetch positions entirely
- Update `usePerpsClosePosition` hook to pass the position it already
has

## **Changelog**

CHANGELOG entry: Fixed rate limiting errors (429) when closing positions
or updating margin after prolonged app usage

## **Related issues**

Fixes: Rate limiting issues during position close/margin update
operations


## **Manual testing steps**

```gherkin
Feature: Position close without rate limiting

  Scenario: User closes position after prolonged usage
    Given user has the app open for extended period (>30 minutes)
    And user has an open perps position

    When user closes the position
    Then the position closes successfully without 429 errors

  Scenario: User updates margin after prolonged usage
    Given user has the app open for extended period (>30 minutes)
    And user has an open perps position with isolated margin

    When user adjusts the margin
    Then the margin updates successfully without 429 errors

  Scenario: User closes all positions
    Given user has multiple open perps positions

    When user uses "close all positions" feature
    Then all positions close successfully without rate limiting errors
```

## **Screenshots/Recordings**

### **Before**

N/A - Bug fix for rate limiting, no UI changes

### **After**

N/A - Bug fix for rate limiting, no UI 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]
> **Medium Risk**
> Changes core position-management flows to rely on cached/WebSocket
position data and a new optional parameter; incorrect or stale position
inputs could cause closes/margin updates to target the wrong
size/symbol, though fallbacks remain.
> 
> **Overview**
> Prevents 429 rate limiting in HyperLiquid position-management by
**stopping forced REST refreshes** (`skipCache: true`) in
`closePositions()` and `updateMargin()`, and relying on
cached/WebSocket-backed `getPositions()`.
> 
> Extends `closePosition()` to accept an optional live `position` object
(and updates `usePerpsClosePosition` + tests to pass it) so closes can
skip fetching positions entirely when the caller already has up-to-date
WebSocket data.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
391e90b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Michal Szorad <michal.szorad@consensys.net>
[6f89dec](6f89dec)

Co-authored-by: abretonc7s <107169956+abretonc7s@users.noreply.github.com>
Co-authored-by: Michal Szorad <michal.szorad@consensys.net>
… API calls on HIP-3 markets cp-7.63.0 cp-7.64.0 (#25500)

- fix(perps): add spotMeta caching to reduce API calls on HIP-3 markets
cp-7.63.0 (#25493)

## **Description**

**fix(perps): add spotMeta caching to reduce API calls on HIP-3
markets**

This PR adds session-based caching for HyperLiquid's global `spotMeta`
endpoint to avoid redundant API calls during HIP-3 operations.

### Context
Following a rate limiting incident where excessive API calls triggered
HyperLiquid's rate limits (2000 msg/min), this is a defensive
improvement to reduce unnecessary network requests.

### Problem
The `spotMeta` API (which returns token metadata like USDC/USDH indices)
was being called multiple times per trading session:
- `getUsdcTokenId()` - called during transfers
- `isUsdhCollateralDex()` - called to check collateral type
- `swapUsdcToUsdh()` - called during HIP-3 USDH swaps

Each call was making a fresh API request, even though the data (token
indices) doesn't change during a session.

### Solution
- Added `cachedSpotMeta` property for session-based caching (no TTL -
token indices are stable)
- Added `getCachedSpotMeta()` method that returns cached data or fetches
once
- Pre-fetch spotMeta in `ensureReadyForTrading()` when HIP-3 is enabled
(non-blocking)
- Cache invalidated on `disconnect()` to ensure fresh state on
reconnect/account switch

### Design Decisions
- **Global cache** (not per-DEX): `spotMeta` is a global endpoint
returning all tokens
- **Session-based** (no TTL): Token indices don't change during a
session
- **Graceful fallback**: If pre-fetch fails, methods fetch on-demand
- Follows existing patterns: `getCachedMeta()`, `getCachedPerpDexs()`

## **Changelog**

CHANGELOG entry: Fixed excessive API calls on HIP-3 markets by caching
spot metadata

## **Related issues**

Fixes: N/A (Defensive improvement following rate limiting incident)

## **Manual testing steps**

```gherkin
Feature: SpotMeta caching for HIP-3 operations

  Scenario: User places order on HIP-3 DEX (SILVER)
    Given user has connected wallet with USDC balance
    And user is on a HIP-3 enabled DEX (e.g., SILVER)

    When user places an order
    Then order should succeed
    And spotMeta API should only be called once per session (check debug logs)

  Scenario: User disconnects and reconnects
    Given user has placed orders (spotMeta is cached)

    When user disconnects wallet
    And user reconnects wallet
    Then spotMeta cache should be cleared
    And next HIP-3 operation should fetch fresh spotMeta
```

## **Screenshots/Recordings**

N/A - Internal optimization, no UI changes

### **Before**

Multiple `spotMeta` API calls per session (one per HIP-3 operation)

### **After**

Single `spotMeta` API call per session, cached for subsequent operations

## **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**
> Medium risk due to changes in perps trading readiness flow (pre-fetch
+ session caching of `spotMeta`) and broad refactors to error
handling/logging that could affect surfaced error messages and retry
behavior.
> 
> **Overview**
> Reduces HyperLiquid HIP-3 API load by adding a session-level
`spotMeta` cache in `HyperLiquidProvider`, prefetching it during
`ensureReadyForTrading()`, and reusing it for USDC token lookup,
collateral-type checks, and USDH swap logic; the cache is cleared on
disconnect.
> 
> Standardizes error handling across perps (`PerpsController`,
connection provider/manager, stream manager, HyperLiquid provider) by
extending `ensureError` to accept optional context and produce better
messages for `null`/`undefined`, then updating call sites/tests
accordingly (including `SpotMetaResponse` typing and updated `spotMeta`
mocks).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
46e74fa. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[b5c386c](b5c386c)

Co-authored-by: abretonc7s <107169956+abretonc7s@users.noreply.github.com>
…overhead and prevent leaks cp-7.63.0 cp-7.64.0 (#25504)

- fix(perps): reduce WebSocket subscription overhead and prevent leaks
cp-7.63.0 cp-7.64.0 (#25496)

## **Description**

This PR addresses WebSocket subscription issues identified during the
rate limiting incident investigation. The fixes reduce subscription
message volume by ~75% and prevent subscription leaks.

### Root Causes Identified

1. **Subscriptions to unregistered DEXs** - System subscribed to ALL 8
DEXs from API instead of only the 2 in our allowlist (main + xyz)
2. **Duplicate DEX subscriptions from race conditions** - Concurrent
calls created 2× subscriptions per DEX
3. **Candle subscription leaks** - Cleanup failed when component
unmounted before async subscription resolved

### Fixes Implemented

#### 1. Filter DEXs by Allowlist on Mainnet (HIGH PRIORITY)
**Files:** `hyperLiquidConfig.ts`, `HyperLiquidProvider.ts`

- Added `MAINNET_HIP3_CONFIG` with `AutoDiscoverAll: false`
- DEX filtering is now dynamic - extracts DEX names from the
`allowlistMarkets` feature flag patterns
- Added `extractDexsFromAllowlist()` method that parses patterns like
`xyz:*`, `xyz:TSLA`, or `xyz`
- **Impact:** Reduces from 8 DEXs to 2 (main + xyz), ~75% reduction in
subscription messages

#### 2. Prevent Duplicate DEX Subscriptions (HIGH PRIORITY)
**File:** `HyperLiquidSubscriptionService.ts`

- Added `pendingClearinghouseSubscriptions` and
`pendingOpenOrdersSubscriptions` Maps
- Refactored `ensureClearinghouseStateSubscription()` and
`ensureOpenOrdersSubscription()` to check for pending promises
- Concurrent calls now wait for the pending promise instead of creating
duplicate subscriptions
- **Impact:** Prevents 50% redundant subscriptions from race conditions

#### 3. Fix Candle Subscription Cleanup (HIGH PRIORITY)
**File:** `HyperLiquidClientService.ts`

- Store subscription promise to enable cleanup even when pending
- Updated cleanup function to wait for pending promise and unsubscribe
- **Impact:** Prevents WebSocket subscription leaks when component
unmounts before subscription resolves

### Test Results

| Metric | Before | After | Improvement |
|--------|--------|-------|-------------|
| DEXs subscribed | 8 | 2 | 75% reduction |
| clearinghouseState subscriptions | 16 | 2 | 87% reduction |
| openOrders subscriptions | 16 | 2 | 87% reduction |
| Candle subscription leaks | Yes | No | Fixed |

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: Rate limiting incident from WebSocket over-subscription

Related: [WebSocket Subscription Investigation
Report](docs/perps/perps-websocket-subscription-investigation.md)

## **Manual testing steps**

```gherkin
Feature: WebSocket subscription optimization

  Scenario: User connects to perps and only allowlisted DEXs are subscribed
    Given user has the app installed with perps feature enabled
    And WebSocket logging is enabled in dev mode

    When user navigates to Perps home screen
    Then WebSocket logs show subscriptions only for main and xyz DEXs
    And no subscriptions for flx, vntl, hyna, km, abcd, cash DEXs

  Scenario: User navigates between markets without duplicate subscriptions
    Given user is connected to perps
    And WebSocket logging is enabled

    When user navigates from Home to xyz:XYZ100 market details
    And user returns to Home
    And user navigates back to xyz:XYZ100
    Then WebSocket logs show no duplicate clearinghouseState subscriptions
    And WebSocket logs show no duplicate openOrders subscriptions

  Scenario: User views candle chart and subscriptions are properly cleaned up
    Given user is on a market details screen with chart visible

    When user quickly navigates away from the screen
    And user waits for 2 seconds
    Then candle subscriptions are properly unsubscribed
    And no orphaned candle subscriptions exist
```

## **Screenshots/Recordings**

### **Before**

WebSocket subscription breakdown (full trading flow):
- clearinghouseState: 16 subscriptions (8 DEXs × 2 duplicates)
- openOrders: 16 subscriptions (8 DEXs × 2 duplicates)
- candle: 4 subscriptions, 0 unsubscriptions (leak)

### **After**

WebSocket subscription breakdown (full trading flow):
- clearinghouseState: 2 subscriptions (main + xyz only)
- openOrders: 2 subscriptions (main + xyz only)
- candle: 2 subscriptions, 2 unsubscriptions (balanced)

**Total outgoing messages:** 44
**Total incoming messages:** 402 (down from ~750)

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

---

### Subscription Breakdown
- `clearinghouseState`: 2 (main + xyz)
- `openOrders`: 2 (main + xyz)
- `userFills`: 1
- `webData3`: 1
- `allMids`: 1
- `assetCtxs`: 2 (xyz only, subscribed/unsubscribed on navigation)
- `activeAssetCtx`: 2 (xyz:XYZ100, subscribed/unsubscribed on
navigation)
- `candle`: 2 (1h + 15m intervals)
- `bbo`: 2 (subscribed/unsubscribed during order flow)

### Future Optimization Opportunity

Trading operations (order placement, cancellation, modification)
currently use **HTTP transport**:
- `ExchangeClient` is configured with `httpTransport` to avoid 429 rate
limiting
- `InfoClient` uses `wsTransport` for info queries (multiplexed over
single WS connection)

Now that subscription volume is reduced by 75%, we could consider moving
`ExchangeClient` to WebSocket transport (see follow-up investigation).

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches core perps WebSocket subscription logic (DEX
discovery/filtering and subscription lifecycle), so mistakes could drop
market/user updates or leave subscriptions running. Changes are targeted
and add guards against race conditions and cleanup failures.
> 
> **Overview**
> Reduces HyperLiquid HIP-3 WebSocket load by **filtering mainnet DEX
discovery** based on the `allowlistMarkets` patterns, falling back to
*main DEX only* when no HIP-3 DEXs are implied. Adds
`MAINNET_HIP3_CONFIG` and an allowlist parser
(`extractDexsFromAllowlist`) to avoid subscribing to non-allowlisted
HIP-3 DEXs.
> 
> Prevents **duplicate per-DEX subscriptions** by deduplicating
concurrent `clearinghouseState` and `openOrders` subscription attempts
via pending-promise tracking, and ensures these pending entries are
cleared during teardown.
> 
> Fixes a **candle subscription leak** by tracking the pending
subscription promise and unsubscribing even if cleanup happens before
the async subscription resolves.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
9fcf758. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude <noreply@anthropic.com>
[7a0c2a1](7a0c2a1)

Co-authored-by: abretonc7s <107169956+abretonc7s@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
… Card flow fixes (#25538)

- feat(card): cp-7.64.0 Onboarding and Metal Card flow fixes (#25473)

<!--
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 includes multiple improvements and bug fixes for the Card
feature:

### Sign Up Flow Improvements
- **Removed confirm password field**: Simplified the sign up form by
removing the redundant password confirmation step
- **Added password visibility toggle**: Users can now show/hide their
password using an eye icon
- **Reordered form fields**: Country selector is now displayed first,
followed by email and password
- **Updated copy**: Changed "Apply now" button text to "Setup now" and
updated password description

### DaimoPay Environment Toggle
- **Added experimental setting**: New toggle in Experimental Settings to
switch between DaimoPay demo and production environments (only visible
in non-production builds)
- **Refactored environment detection**: `getDaimoEnvironment` now
accepts a parameter instead of checking `__DEV__`
- **Fixed payment flow**: Payment polling now uses `orderId` instead of
`payId` for correct status tracking
- **Improved payment completion handling**: Removed premature navigation
on `paymentCompleted` WebView event - now relies on polling to confirm
actual completion

### Card Home Fixes
- **Fixed manage card options visibility**: Added `needsSetup` condition
to hide manage card, metal card order, and travel options when user
hasn't completed card setup
- **Fixed balance display for non-US locales**: Fixed an issue where
fiat balance was displaying 100x the correct value (e.g., $55 instead of
$0.55) for locales that use comma as decimal separator (Brazilian
Portuguese, German, etc.)

### Token Balance Fixes
- **Fixed potential balance mismatch**: Changed `useTokensWithBalance`
from index-based array lookup to address-based Map lookup to prevent
balance mismatches when tokens are filtered

### Spending Limit Screen Fix
- **Fixed asset selection flickering**: Resolved an issue where
selecting a different asset from the AssetSelectionBottomSheet would
immediately revert to the original asset

### Other Changes
- **PersonalDetails**: Removed fallback for nationality field (no longer
uses `countryOfResidence` as fallback)
- **CardSDK**: Added `location` parameter to `getRegistrationStatus`
method
- **Types**: Added `requestId` to `CreateOrderResponse` and `STARTED` to
`OrderStatus`

## **Changelog**

CHANGELOG entry: Improved Card sign up flow by removing confirm password
field and adding password visibility toggle. Fixed balance display for
non-US locales, fixed asset selection flickering on Spending Limit
screen, and fixed manage card options visibility for users who haven't
completed setup.

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: Card sign up flow

  Scenario: User signs up for card
    Given user opens the Card sign up screen

    When user views the form
    Then country selector should be displayed first
    And email field should be displayed second
    And password field should be displayed third
    And there should be no confirm password field
    And password field should have a visibility toggle icon

Feature: Card balance display with locale formatting

  Scenario: User views correct balance with Brazilian locale
    Given user has device set to Brazilian Portuguese locale
    And user has 0.55 USDC in their wallet

    When user navigates to Card Home
    Then balance should display as "US$ 0,55" (not "US$ 55,00")

Feature: Spending limit asset selection

  Scenario: User changes asset on spending limit screen
    Given user is on the Spending Limit screen with USDC selected
    
    When user taps "Other" to select a different asset
    And user selects USDT from the asset selection bottom sheet
    Then USDT should remain selected (not revert to USDC)

Feature: Card Home manage options visibility

  Scenario: User sees manage options only after setup
    Given user has not completed card setup (needs delegation)

    When user views Card Home
    Then "Manage Card", "Order Metal Card", and "Travel" options should be hidden

Feature: DaimoPay environment toggle (non-production only)

  Scenario: Developer toggles DaimoPay demo mode
    Given user is on a non-production build
    And user navigates to Settings > Experimental

    When user toggles "Use DaimoPay demo environment"
    Then DaimoPay should use the demo environment for payments
```

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

First case: Demo disabled. The order fails because a payment was already
completed.
Second case: Demo enabled. The demo flow starts successfully.



https://github.com/user-attachments/assets/3093aae7-276d-4351-ae8f-aee70d412f9d

<!-- [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**
> Medium risk due to changes across Card onboarding, DaimoPay payment
creation/polling/navigation, and Redux state used to select environments
and locations; could affect checkout completion and onboarding flows if
miswired.
> 
> **Overview**
> Improves Card onboarding UX by **removing the confirm-password
field**, reordering the Sign Up form (country → email → password),
adding **password visibility toggles** (Sign Up + Login), updating
onboarding copy, and disabling app auto-lock while the onboarding
navigator is mounted.
> 
> Refactors DaimoPay to support a **demo/production toggle** (new
`card.isDaimoDemo` + Experimental Settings switch shown only in
non-production builds) and to **poll by `orderId`** in production (while
demo navigates immediately). This threads `orderId` through
`ReviewOrder` → `DaimoPayModal`, updates `DaimoPayService` to return `{
payId, orderId }` (with `requestId` support), and tightens event/origin
handling.
> 
> Fixes a few Card flow issues: hides manage-card actions until setup is
complete, parses locale-formatted fiat strings correctly when deriving
balances, prevents spending-limit token selection from being overwritten
after returning from the bottom sheet, removes nationality fallback in
`PersonalDetails`, and passes `userCardLocation` into
`CardSDK.getRegistrationStatus`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
32d224d. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[7c2216d](7c2216d)

Co-authored-by: Bruno Nascimento <brunonascimentodev@gmail.com>
…TA when above minimum required balance of 1 cent (#25531)

- fix: cp-7.64.0 MUSD-268 only render Earn CTA when above minimum
required balance of 1 cent (#25454)

<!--
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**
Hides the Earn CTA for asset when the asset's balance is less than
minimum required.

<!--
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: updated Earn CTAs to not render when the asset's
balance is less than minimum required


## **Related issues**

Fixes: [MUSD-270: Earn CTA is displayed for zero balance
tokens](https://consensyssoftware.atlassian.net/browse/MUSD-268)

## **Manual testing steps**

```gherkin
Feature: Earn CTA visibility based on token balance

  Scenario: user views a token with balance below minimum earn threshold
    Given user has a token in the wallet with balance below 0.01
    When user views the token in the token list
    Then no "Earn" call-to-action is displayed

  Scenario: user views a token with balance at or above minimum earn threshold
    Given user has a token in the wallet with balance at or above 0.01
    When user views the token in the token list
    Then an "Earn" call-to-action is displayed
```

## **Screenshots/Recordings**

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

### **Before**

<!-- [screenshots/recordings] -->
<img width="450" height="81" alt="image"

src="https://github.com/user-attachments/assets/10f7fab9-8826-43dd-a7d6-99ffe8e01210"
/>

<img width="450" height="209" alt="image"

src="https://github.com/user-attachments/assets/71f2daba-9590-482c-8bec-69f2c66fcf6e"
/>


### **After**

<!-- [screenshots/recordings] -->
<img width="456" height="82" alt="image"

src="https://github.com/user-attachments/assets/241a9ff1-da48-4e3e-8802-62c0e6d08e90"
/>

<img width="450" height="209" alt="image"

src="https://github.com/user-attachments/assets/2b16a88f-ac36-4a2c-8cb3-75844dccbfff"
/>


## **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 gating change that only affects when Earn CTAs render;
main risk is accidentally hiding/showing CTAs due to balance/fiat-number
mismatches.
> 
> **Overview**
> Introduces a shared `MINIMUM_BALANCE_FOR_EARN_CTA` (0.01) and uses it
to **suppress Earn CTAs for very small/zero balances**.
> 
> `StakeButton` now derives the `earnToken` via `useEarnToken` and
returns `null` when `earnToken.balanceFiatNumber` is below the
threshold; `TokenListItem` similarly only shows the stablecoin lending
Earn secondary CTA when the balance meets the minimum (otherwise falling
back to % change).
> 
> Updates unit tests to reflect the new `earnToken` shape passed to
navigation and adds coverage for below/at-threshold behavior.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f521872. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[e4b8256](e4b8256)

Co-authored-by: Matthew Grainger <46547583+Matt561@users.noreply.github.com>
…ils page cp-7.64.0 (#25550)

- fix: O(n) api calls to ramps on token details page cp-7.64.0 (#25512)

<!--
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**
After profiling the app I found we are making O(n) API calls to

`https://on-ramp-cache.uat-api.cx.metamask.io/regions/ch/tokens?action=buy&sdk=2.1.5`
where `n` is the number of tokens. After pinpointing down the issue, I
can see this bug was introduced by
[this](#24335) PR.

I have created this PR which partly fixes the issue by reducing API
calls from O(n) to O(3). I would highly advise the @MetaMask/earn team
to develop local caching for that API call and call it only once across
the whole app since right now they are making 3 API calls every time
this hook is instantiated: useMusdCtaVisibility()

Raised it on Slack:
https://consensys.slack.com/archives/C0A0LBK7ZG8/p1770031196240769

<!--
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: fix O(n * 3) api calls to ramps on token details page

## **Related issues**

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

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



https://github.com/user-attachments/assets/6d58dfe7-c123-488c-8ae3-f670db79ec86


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

### **After**



https://github.com/user-attachments/assets/9abb0bb2-ef3f-4638-8374-922c629a75c3


<!-- [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**
> Changes the `TokenListItem` prop contract and moves mUSD CTA
visibility evaluation up to `TokenList`, which could affect token list
rendering/CTA behavior if any callers aren’t updated.
> 
> **Overview**
> Reduces repeated mUSD CTA visibility work by **moving
`useMusdCtaVisibility()` out of each `TokenListItem`** and into
`TokenList`, then passing `shouldShowTokenListItemCta` down as a prop
for per-asset evaluation.
> 
> Updates `TokenListItem`’s props/types and adjusts unit tests/mocks in
`TokenList.test.tsx` and `TokenListItem.test.tsx` to supply/mimic the
new callback-based CTA visibility flow.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
9abdd47. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[b109f5b](b109f5b)

Co-authored-by: Juanmi <95381763+juanmigdr@users.noreply.github.com>
… test (#25593)

- fix: add missing prop to fix TokenListItem test (#25559)

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

TokenListItem tests are failing.


https://github.com/MetaMask/metamask-mobile/actions/runs/21614511374/job/62290254653?pr=25557

This is a fix.

```
Error: app/components/UI/Tokens/TokenList/TokenListItem/TokenListItem.test.tsx(1043,10): error TS2741: Property 'shouldShowTokenListItemCta' is missing in type '{ assetKey: FlashListAssetKey; showRemoveMenu: Mock<any, any, any>; setShowScamWarningModal: Mock<any, any, any>; privacyMode: false; }' but required in type 'TokenListItemProps'.
Error: app/components/UI/Tokens/TokenList/TokenListItem/TokenListItem.test.tsx(1070,10): error TS2741: Property 'shouldShowTokenListItemCta' is missing in type '{ assetKey: FlashListAssetKey; showRemoveMenu: Mock<any, any, any>; setShowScamWarningModal: Mock<any, any, any>; privacyMode: false; }' but required in type 'TokenListItemProps'.
Error: Process completed with exit code 2.
```

<!--
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]
> **Low Risk**
> Low risk test-only change that fixes TypeScript compilation failures
by updating test render props; no production logic is modified.
> 
> **Overview**
> Fixes failing `TokenListItem` unit tests by passing the now-required
`shouldShowTokenListItemCta` prop in the stablecoin lending CTA
threshold test cases.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b3b39aa. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[e0cb4d3](e0cb4d3)

Co-authored-by: George Weiler <georgejweiler@gmail.com>
…atch (#25580)

- fix: cp-7.64.0 MUSD-266 staked ethereum balance mismatch (#25468)

<!--
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**
Fixed bug where Staked Ethereum balances weren't updating when switching
accounts.
<!--
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: fixed bug where Staked Ethereum balances weren't
updating when switching accounts.

## **Related issues**

Fixes: [MUSD-266: Staked Ethereum Balance
Mismatch](https://consensyssoftware.atlassian.net/browse/MUSD-266)

## **Manual testing steps**

```gherkin
Feature: Correct staked asset balances per account

  Scenario: user switches accounts and sees staked Ethereum balance update
    Given user has multiple EVM accounts with different Ethereum and Staked Ethereum balances
    When user switches the selected account
    Then the displayed Ethereum balance matches the selected account
    And the displayed Staked Ethereum balance matches the selected account

  Scenario: user views a staked token and sees the staked balance (not the native counterpart)
    Given user has a staked token balance
    When user opens the token details view for the staked token
    Then the displayed balance corresponds to the staked asset
```

## **Screenshots/Recordings**

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

### **Before**

<!-- [screenshots/recordings] -->
1. Staked Ethereum doesn't update when switching accounts
2. Staked Ethereum AssetOverview was displaying the user's **native**
ETH balance
### **After**

<!-- [screenshots/recordings] -->
1. Staked Ethereum now updates when switching accounts
2. Staked Ethereum on balance in TokenListItem now matches balance on
AssetOverview screen



https://github.com/user-attachments/assets/8ba8ed5b-b499-4739-8b8b-895d1a09a47c

## **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 core `selectAsset` lookup behavior for EVM chains and alters
displayed fiat formatting/rounding for staked balances, which could
impact multiple balance/asset UI surfaces when switching accounts.
> 
> **Overview**
> Fixes a bug where **Staked Ethereum** could display the wrong
account’s balance after switching accounts by scoping `selectAsset`
results (native and staked) to `selectSelectedInternalAccountId` on EVM
chains.
> 
> Updates `useBalance` to source staked native asset fiat values from
`selectAsset` (matching the token list’s Intl formatting) with a
`weiToFiat` fallback, and adjusts/extends tests accordingly (including
new coverage for account-scoped lookups and updated expected fiat
strings).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
32c383d. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[aeee852](aeee852)

Co-authored-by: Matthew Grainger <46547583+Matt561@users.noreply.github.com>
Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
- fix: Android ANR bug cp-7.64.0 (#25551)

<!--
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: Prevent crash caused by Notifee BlockStateBroadcastReceiver during
cold start

## Summary

Fixes a crash that occurs when notification permission changes trigger
Notifee's `BlockStateBroadcastReceiver` before React Native is fully
initialized during app cold start.

## Solution

Disable Notifee's `BlockStateBroadcastReceiver` by adding an override in
`AndroidManifest.xml`. This is the most light weight solution.

Changes (Background Tracking Only):
User Changes Settings OUTSIDE the App
Before (with receiver enabled):
1. User closes MetaMask
2. User goes to Android Settings → Apps → MetaMask → Notifications
3. User toggles "Allow notifications" OFF
4. BlockStateBroadcastReceiver fires immediately
**5. MetaMask knows about the change (while app is closed)**

After (with receiver disabled):
1. User closes MetaMask
2. User goes to Android Settings → Apps → MetaMask → Notifications
3. User toggles "Allow notifications" OFF
4. Nothing happens in the background
**5. MetaMask detects the change next time app opens**

Builds to test:
Crash version:
https://app.bitrise.io/build/f78866d9-cb88-4789-8be0-dec2d7c18e20
Fixed version:

https://app.bitrise.io/build/cd177e81-6545-44ff-a20f-6c5ed11936b5?tab=artifacts

<!--
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:Fix: Prevent crash caused by Notifee
BlockStateBroadcastReceiver during cold start

## **Related issues**

Fixes: [Fix: Prevent crash caused by Notifee BlockStateBroadcastReceiver
during cold start
](#25524)

## **Manual testing steps**

```gherkin
Scenario: App launches successfully when notification permission is disabled in Android Settings during cold start (After Fix)
  Given the MetaMask app is completely closed
  When I open Android Settings
  And I navigate to "Apps" → "MetaMask" → "Notifications"
  And I toggle "Allow notifications" to OFF
  And I return to the home screen
  And I tap the MetaMask app icon to launch it
  Then the app should launch successfully
  And I should not see any crash dialogs
  And I should see the wallet home screen
```

## **Screenshots/Recordings**

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

### **Before**


![crashed](https://github.com/user-attachments/assets/5031a720-dec4-4b4a-9daa-3fc0f19a9847)

### **After**
![no

crash](https://github.com/user-attachments/assets/7be5a943-e477-4379-8678-994584e116a6)


<!-- [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**
> Low code-change surface (manifest-only), but it alters notification
permission-change handling while the app is closed and could impact
background awareness of notification settings changes.
> 
> **Overview**
> Prevents an Android cold-start crash/ANR by disabling Notifee’s
`app.notifee.core.BlockStateBroadcastReceiver` via an
`AndroidManifest.xml` override (`android:enabled="false"` with
`tools:node="remove"`).
> 
> As a tradeoff, notification permission state changes made in Android
Settings while the app is closed will no longer be handled in the
background and will instead be detected on next app launch.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
528d65b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
[b566864](b566864)

Co-authored-by: Wei Sun <wei.sun@consensys.net>
Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
…o be next to asset name (#25600)

- feat: cp-7.64.0 MUSD-279 moved Earn CTAs to be next to asset name
(#25545)

<!--
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**
Moves the "Earn %" CTA for Ethereum and Tron to be next to the asset
name. This fix is needed because large token balances are causing the
"Earn %" CTA to clip into the percentage changed text.
<!--
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: moved the "Earn %" CTA for Ethereum and Tron to be next
to the asset name

## **Related issues**

Fixes: [MUSD-279: Move the Earn CTAs next to ETH and Tron contextually
next to the asset
name's](https://consensyssoftware.atlassian.net/browse/MUSD-279)

## **Manual testing steps**

```gherkin
Feature: Earn call-to-action placement in token list

  Scenario: user sees stake call-to-action next to token name
    When user views ETH and the token in the token list
    When user has non-zero token balance
    Then a Stake call-to-action is displayed inline next to the token name
```

## **Screenshots/Recordings**

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

### **Before**

<!-- [screenshots/recordings] -->
Earn CTA collides with the percentage changed text for large token
balances.
### **After**

<!-- [screenshots/recordings] -->
<img width="454" height="81" alt="Screenshot 2026-02-02 at 3 50 50 PM"

src="https://github.com/user-attachments/assets/21a1671f-2d66-4017-bc2b-1c78fcfd4e02"
/>
<img width="454" height="81" alt="Screenshot 2026-02-02 at 3 51 07 PM"

src="https://github.com/user-attachments/assets/690691a3-ebf9-43ea-a8a8-5f298c66c3bd"
/>

## **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 layout change within `TokenListItem`; main risk is
minor visual regressions/alignment issues across devices and long
names/labels.
> 
> **Overview**
> Moves the token-list Earn/Stake call-to-action (`renderEarnCta()`)
from the balance/percentage row to sit inline next to the asset name.
> 
> Adds a new `assetNameContainer` row style to keep the name/label and
CTA aligned, preventing the CTA from overlapping/clipping with the
secondary balance text for large balances.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
cc21dce. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[ba206df](ba206df)

Co-authored-by: Matthew Grainger <46547583+Matt561@users.noreply.github.com>
…Action cp-7.64.0 (#25628)

- chore: New Crowdin translations by Github Action cp-7.64.0 (#25362)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk localization-only change, but renamed/added keys may surface
as missing or still-English strings in German/Greek/Spanish if the app
references different translation keys.
> 
> **Overview**
> Updates German (`de`), Greek (`el`), and Spanish (`es`) locale files
with new/updated strings from Crowdin, primarily covering **MetaMask
Card** onboarding/ordering flows (password prompt, card selection, order
review/completion, recurring fees, DaimoPay errors, KYC pending, and
card management options).
> 
> Adds translations for **Perps** and **swap** UX updates (payment-token
selection and swap-to-USDC messaging, one-click trade failure copy,
deposit status text, and expanded slippage modal labels/warnings), plus
new **Rewards** copy (referral-code errors, bulk account opt-in,
“Snapshots” tab/status strings) and assorted UI labels (dapp browser
tabs, market explore tabs, prediction category additions, and
phishing/security messaging tweaks).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
e075792. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
[9007c26](9007c26)

Co-authored-by: MetaMask Bot <37885440+metamaskbot@users.noreply.github.com>
Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
…fe area by navigation source cp-7.64.0 (#25627)

- fix(perps): set confirmation header and safe area by navigation source
cp-7.64.0 (#25601)

## **Description**

Set confirmation header by navigation source

## **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 Perps confirmation screen so the header is hidden
when opening from the one-click order flow and shows a minimal header
when opening from other flows.

## **Related issues**

Fixes: #25469

## **Manual testing steps**

```gherkin
Feature: Perps confirmation screen header

  Scenario: user opens confirmation via one-click order (navigateToOrder)
    Given user is on a Perps market and taps place order (one-click flow)

    When deposit is confirmed and confirmation screen opens

    Then the confirmation screen has no header (header: () => null)

  Scenario: user opens confirmation from another flow
    Given user reaches RedesignedConfirmations from a path other than navigateToOrder

    When the confirmation screen is shown

    Then the screen shows a minimal header (header visible, no left button, empty title)
```

## **Screenshots/Recordings**

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

### **Before**
<img width="1206" height="2622" alt="Simulator Screenshot - iPhone 17
Pro - 2026-02-03 at 19 47 49"

src="https://github.com/user-attachments/assets/8ff43507-5222-426c-a86a-a30a6403baa6"
/>

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

### **After**
<img width="1206" height="2622" alt="Simulator Screenshot - iPhone 17
Pro - 2026-02-03 at 19 46 49"

src="https://github.com/user-attachments/assets/d374525a-5732-4049-9c73-da03bd5f29d6"
/>

<!-- [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 Perps navigation params and `RedesignedConfirmations` screen
options, which can affect the confirmation flow’s header visibility and
layout. Risk is limited to Perps UI/navigation but could cause
regressions if other entry points don’t pass expected params.
> 
> **Overview**
> Updates Perps confirmations to **conditionally show/hide the header
and safe area** based on the navigation source.
> 
> Adds `CONFIRMATION_HEADER_CONFIG` and a `showPerpsHeader` navigation
param; `navigateToOrder` now passes `showPerpsHeader: false` for the
deposit-and-trade (one-click) path, while other paths default to a
minimal header.
> 
> The Perps stack now derives `RedesignedConfirmations` screen options
from route params (and toggles `Confirm`’s `disableSafeArea`
accordingly), with types and tests updated to cover the new param
behavior.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
7d77188. 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>
[2bc0e0e](2bc0e0e)

Co-authored-by: Michal Szorad <michal.szorad@consensys.net>
Co-authored-by: Cursor <cursoragent@cursor.com>
runway-github Bot and others added 27 commits February 4, 2026 18:49
…oute definition (#25658)

- fix: Remove userLoggedIn conditional for route definition cp-7.64.0
(#25563)

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

This removes the `userLoggedIn` conditional route definition in the
navigation stack, which resolves a race condition associated with the
re-rendering of the stack. It caused users to be stuck on the LockScreen
post manual lock.

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

## **Manual testing steps**

- Manually lock the app from settings
- Should land on the Login screen, not stuck on the Lock screen

## **Screenshots/Recordings**

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

### **Before**

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



https://github.com/user-attachments/assets/4c85e502-6b3c-47d0-a37b-940a5165beed


### **After**

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



https://github.com/user-attachments/assets/24ebda8e-0da9-4169-a16b-9756cf48e634


## **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 the root navigation stack so `HOME_NAV` is always registered,
which can affect navigation state and route resolution during
lock/unlock/onboarding transitions. Low code churn, but touches core app
routing so regressions would surface quickly at runtime.
> 
> **Overview**
> Removes the `selectUserLoggedIn`-gated conditional that only
registered `Routes.ONBOARDING.HOME_NAV` when the wallet was unlocked.
> 
> `AppFlow` now always defines the `HOME_NAV` stack screen, preventing
stack re-creation/race conditions that could leave users stuck on
`LockScreen` after a manual lock.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
78b9228. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[2023252](2023252)

Co-authored-by: Cal Leung <cal.leung@consensys.net>
…nts (#25666)

- refactor: Market discoverability improvements cp-7.64.0 (#25610)

## **Description**

This PR addresses multiple market discovery UX issues for Perps:
1. Fix "See all perps" navigation: The button in the main perps tab now
correctly navigates to the Market List search with "all" selected,
instead of redirecting to perps home
2. Include all market categories in explore section: The explore section
in wallet home and perps tab empty state no longer filters out
commodities and forex markets
3. Add Commodities section to Perps Home: A new Commodities section is
now displayed between Crypto and Stocks on the perps home screen
4. Temporarily disable market type badges: Stock/commodity badges on
list items are commented out (can be quickly re-enabled if needed)


## **Changelog**

CHANGELOG entry: Improvements to market discoverability

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TAT-2467

## **Manual testing steps**

```gherkin
Feature: Perps market discovery improvements

  Scenario: See all perps navigates to market list with all filter
    Given I am on the wallet home Perps tab with no positions
    When I tap "See all perps"
    Then I am on the Market List with "All" filter selected

  Scenario: Explore section includes all market categories
    Given I am on the wallet home Perps tab with no positions
    Then the explore section shows crypto, stocks, commodities, and forex markets

  Scenario: Commodities section appears between Crypto and Stocks
    Given I am on the Perps Home screen
    Then sections appear in order: Crypto, Commodities, Stocks, Forex

  Scenario: Market type badges are hidden
    Given I am viewing any market list
    Then no STOCK or COMMODITY badges appear on market rows
```

## **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**
> Changes Perps home/tab navigation and market filtering logic, which
can affect user flows and the markets shown (including new commodities
section). Risk is moderate due to routing/param changes and broader
market-type exposure, but remains UI/business-logic scoped.
> 
> **Overview**
> Improves Perps market discoverability by **expanding Explore to
include all market types** (removing the crypto/equity-only filter) and
updating tests to reflect the new behavior.
> 
> Updates the Perps tab "See all perps" CTA to navigate directly to
`MARKET_LIST` with `defaultMarketTypeFilter: 'all'`, adds a new
**Commodities** section to `PerpsHomeView` between Crypto and Stocks,
and defaults `PerpsMarketRowItem` to *hide market-type badges* (can be
re-enabled via `showBadge`).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
93e23b5. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[6a5bb67](6a5bb67)

Co-authored-by: Nick Gambino <35090461+gambinish@users.noreply.github.com>
…ssage for selected rwa token cp-7.64.0 (#25690)

- fix: display specific geolocation error message for selected rwa token
cp-7.64.0 (#25663)

<!--
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 specific error message when a RWA token is selected. This
messages adds information about unsupported geolocation.

<!--
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: display specific geolocation error message for selected
rwa token

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

### **After**

#### Regular error message when quotes are empty

<img width="250" alt="Simulator Screenshot - iPhone 15 Pro Max -
2026-02-04 at 18 37 26"

src="https://github.com/user-attachments/assets/352f7d74-54a6-45c4-bf5e-cb4c2ba008ce"
/>

--------

#### Custom error message when quotes are empty and RWA source token is
selected

<img width="250" height="2796" alt="Simulator Screenshot - iPhone 15 Pro
Max - 2026-02-04 at 18 37 48"

src="https://github.com/user-attachments/assets/ce9c07a4-ac70-442c-83dd-0a93f4830eab"
/>

--------

#### Custom error message when quotes are empty and RWA destination
token is selected

<img width="250" height="2796" alt="Simulator Screenshot - iPhone 15 Pro
Max - 2026-02-04 at 18 41 48"

src="https://github.com/user-attachments/assets/3bcb9450-b8ff-441a-a4b6-d42a21ab7153"
/>


## **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**
> UI-only messaging change gated by existing token metadata and feature
flag logic, with added tests and no changes to transaction/quote
behavior.
> 
> **Overview**
> When the Bridge screen has an error/no available quotes, the error
banner message now changes based on whether the selected source or
destination token is an RWA *stock* token (via
`useRWAToken().isStockToken`).
> 
> Adds a new localized string
`bridge.stock_token_error_banner_description` explaining potential
geo-restrictions, and extends `BridgeView` tests to cover both the
default error banner and the RWA-specific banner (including mocking
`useRWAToken`).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
6a9f963. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[58f0c4b](58f0c4b)

Co-authored-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
…fication deep link handler (#25703)

- feat(card): cp-7.64.0 create card-kyc-notification deep link handler
(#25607)

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

This PR implements a deeplink handler for Card KYC push notifications,
allowing users to be routed to the appropriate screen based on their KYC
verification status when tapping on a notification about their
verification result.

**Motivation**: When users complete their KYC verification process, they
receive push notifications about the result. Previously, there was no
handler to deep link users directly to the relevant screen based on
their verification status.

**Solution**: 
- Added a new `card-kyc-notification` deeplink action that checks the
user's KYC verification state and navigates accordingly
- Handles two scenarios:
1. **Onboarding flow** (user has onboardingId): Routes to KYCFailed,
Complete (→ PersonalDetails), or KYCPending
2. **Authenticated flow** (user is already logged in): Routes to
KYCFailed, Complete (→ CardHome via SpendingLimit), or CardHome
- Updated the `Complete` screen to accept a `nextDestination` route
param for proper navigation after KYC approval
- Added logic to suppress the "keep going" modal when users are
deeplinked directly to the Complete screen
- Added `logout` method to CardSDK for proper session cleanup
- Refactored `useCardProviderAuthentication` to get location from Redux
selector instead of function parameters

## **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 deeplink handler for Card KYC push notifications
to route users to appropriate screens based on verification status

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: Card KYC Notification Deeplink Handler

  Scenario: User taps KYC approved notification during onboarding
    Given user is in the Card onboarding flow with a pending KYC verification
    And user has an onboardingId stored in Redux

    When user taps on a push notification with the card-kyc-notification deeplink
    And the KYC status is VERIFIED
    Then user is navigated to the Complete screen
    And tapping Continue navigates to PersonalDetails

  Scenario: User taps KYC approved notification when authenticated
    Given user is authenticated with the Card provider
    And user has completed KYC verification

    When user taps on a push notification with the card-kyc-notification deeplink
    And the KYC status is VERIFIED
    Then user is navigated to the Complete screen
    And tapping Continue navigates to SpendingLimit screen

  Scenario: User taps KYC rejected notification
    Given user has submitted KYC verification
    
    When user taps on a push notification with the card-kyc-notification deeplink
    And the KYC status is REJECTED
    Then user is navigated to the KYCFailed screen

  Scenario: User taps notification while KYC is still pending
    Given user has submitted KYC verification
    
    When user taps on a push notification with the card-kyc-notification deeplink
    And the KYC status is PENDING
    Then user is navigated to the KYCPending screen (onboarding) or CardHome (authenticated)
```

## **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**
> Adds a new deeplink entry point and changes navigation/auth state
handling, which could misroute users or regress card onboarding/auth
flows if state/params aren’t set as expected.
> 
> **Overview**
> Adds a new `card-kyc-notification` universal link action that inspects
Card feature flags plus the user’s onboarding/auth state, fetches KYC
verification status (via `CardSDK`), and deep-navigates to the
appropriate Card screen (e.g., `KYC_FAILED`, `KYC_PENDING`, or
`COMPLETE` with a `nextDestination` param).
> 
> Refactors Card authentication to source `location` from Redux
(`selectUserCardLocation`) rather than passing it through login/OTP
APIs, and updates UI to persist location selection in state.
> 
> Improves session cleanup by introducing `CardSDK.logout()` (server
logout + always-clear local token) and wiring `logoutFromProvider()` to
call it while still clearing Redux state on failures; `CardHome` now
shows a toast when an authentication error forces logout/redirect. Also
tweaks onboarding navigation (skip “keep going” modal when deeplinked to
`COMPLETE`), adjusts close-button behavior to `reset` to Card Home, and
updates related copy/SSN helper text and tests.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d043390. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Alejandro Machado <alejandro@macha.do>
Co-authored-by: Kevin Le Jeune <kevin.le-jeune@consensys.net>
[826b8b5](826b8b5)

Co-authored-by: Bruno Nascimento <brunonascimentodev@gmail.com>
Co-authored-by: Alejandro Machado <alejandro@macha.do>
Co-authored-by: Kevin Le Jeune <kevin.le-jeune@consensys.net>
…-7.64.0 (#25720)

- fix: background color for Perps deposit cp-7.64.0 (#25567)

## **Description**
Fixes background color for Perps deposit. It was set to white, now it's
set back to gray.

## **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: Fixes background color for Perps deposit

## **Related issues**

Fixes: 

## **Manual testing steps**
1. Go to Perps deposit, background is gray now, as it was before


## **Screenshots/Recordings**

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

### **Before**



### **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**
> Small UI-only change localized to Perps’ confirmation route wrapper;
main risk is unintended visual regressions (background color) across
Perps confirmation flows.
> 
> **Overview**
> Removes Perps’ custom `useTheme()`-driven `fullscreenStyle` background
override when rendering `Confirm` in `PerpsConfirmScreen`, leaving only
the `disableSafeArea` behavior controlled by `showPerpsHeader`.
> 
> This effectively reverts Perps deposit/confirmation screens to the
default confirmation background styling instead of forcing a theme
background color in this route wrapper.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
17d0930. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
[42a3937](42a3937)

Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
Co-authored-by: Daniel <80175477+dan437@users.noreply.github.com>
…ew unmount cp-7.64.0 (#25714)

- fix(perps): clear confirmation on order view unmount cp-7.64.0
(#25708)

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

Clear transaction confirmation when user leaves the perps order screen

## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

Fixes: #25439
 
## **Manual testing steps**

- Go to Perps
- Start a new order
- Go back to home page
- Start Send flow
- Select any token from any EVM network (on non-EVM networks the error
does not trigger, but the flow is broken)
- Input amount
- Select recipient
- NO error should be shown

## **Screenshots/Recordings**

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

### **Before**

<!-- [screenshots/recordings] -->
no visible change

### **After**

<!-- [screenshots/recordings] -->
no visible 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**
> Small UI lifecycle change that only triggers confirmation rejection on
screen exit; low risk but could affect any in-flight confirmation flow
if unmount happens unexpectedly.
> 
> **Overview**
> Ensures any active transaction confirmation is cleared when leaving
the Perps order screen by replacing `useClearConfirmationOnBackSwipe`
with an explicit unmount cleanup that calls
`useConfirmActions().onReject(undefined, true)`.
> 
> This prevents stale confirmation state from leaking into later flows
(e.g., Send) after navigating away from Perps order creation.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
ef82b75. 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>
[d270ce5](d270ce5)

Co-authored-by: Michal Szorad <michal.szorad@consensys.net>
Co-authored-by: Cursor <cursoragent@cursor.com>
This PR updates the change log for 7.64.0.

---------

Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
…on colors (#25737)

- feat(card): cp-7.64.0 change CardHome button colors (#25728)

<!--
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?
-->
Change CardHome button colors

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

<img width="200" height="900" alt="image"

src="https://github.com/user-attachments/assets/31e5700c-2387-4c73-a71a-6576036e2f95"
/>


### **After**

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

<img width="200" height="900" alt="image"

src="https://github.com/user-attachments/assets/64bb8951-f334-406e-a916-d0070723bc28"
/>


## **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**
> Purely UI styling changes (button variant/color updates) with no
logic, data, or navigation changes; risk is limited to visual
regressions and snapshot/test updates.
> 
> **Overview**
> Updates `CardHome` CTA styling by switching the main action buttons
(`Add funds`, `Enable card`, `Change asset`, and error `Try again`) from
`ButtonVariants.Secondary` to `ButtonVariants.Primary`.
> 
> Refreshes the `CardHome` Jest snapshots to reflect the new primary
button appearance (dark background with white text, removing the
previous secondary styling).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
61ad41d. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Ale Machado <alejandro@macha.do>
[51f9d36](51f9d36)

Co-authored-by: Bruno Nascimento <brunonascimentodev@gmail.com>
Co-authored-by: Ale Machado <alejandro@macha.do>
<!--
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**
Remove biometric toggle switch in Login Screen
[TO-457]

Unlock wallet will not update AuthPreference ( biometric) except
seedless password changed

This pr do not handle when seedless password changed cancel the
biometric cancel
That will be address in another pr
#25689

<!--
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: remove toggle switch from login screen

## **Related issues**

Fixes: - remove biometric toggle switch from login screen

## **Manual testing steps**

```gherkin
Feature: remove biometric switch
  Scenario: user reopen app reach Login screen
    Given biometric switch not visible on Login screen 
    When user unlock with correct password
    Then user unlock succesful without update auth preference
```

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

<!-- [screenshots/recordings] -->
<img width="412" height="944" alt="Screenshot 2026-02-05 at 12 13 32 PM"
src="https://github.com/user-attachments/assets/1b75b186-1429-4cea-baf4-5c087058dbb4"
/>

## **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 login authentication UX and how `unlockWallet` updates auth
preferences (including seedless password-outdated handling), which can
affect unlock flows and biometric/passcode enablement; covered by
updated tests but touches authentication-critical paths.
> 
> **Overview**
> Removes the biometric/remember-me toggle UI from the Login screen and
simplifies login state by no longer reading/writing biometric/passcode
disable flags or deriving an `authPreference` from UI choices.
> 
> Biometric button visibility is now driven by detected auth
type/credentials (and locked state) rather than a stored “disabled”
toggle, and login error handling broadens seedless onboarding detection
via message matching.
> 
> In `Authentication.unlockWallet`, when a seedless password sync occurs
due to an outdated password, the flow now computes an auth preference
that re-enables biometric/passcode by default before calling
`updateAuthPreference`. Tests were updated to reflect the removed toggle
behavior and related error/cancellation scenarios.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d6b2237. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->





[TO-457]:
https://consensyssoftware.atlassian.net/browse/TO-457?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
# 🚀 v7.64.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
- [x] Accounts Framework
- [x] Assets
- [x] Bots Team
- [x] Card
- [x] Confirmations
- [x] Core Platform
- [x] Design System
- [x] Earn
- [x] Mobile Platform
- [x] Mobile UX
- [x] Network Enablement
- [x] Onboarding
- [x] Perps
- [x] Predict
- [x] Product Safety
- [x] Ramp
- [x] Rewards
- [x] Shield
- [x] Swaps and Bridge
- [ ] team-new-networks
- [x] Transactions
- [x] 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
- Testing plan sheet -
https://docs.google.com/spreadsheets/d/1tsoodlAlyvEUpkkcNcbZ4PM9HuC9cEM80RZeoVv5OCQ/edit?gid=404070372#gid=404070372

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Medium risk due to broad CI/workflow and build automation changes (new
outputs, event-condition logic, build triggers/notifications) plus app
config changes that could affect pipelines and debug networking; runtime
product code changes appear limited and mostly additive.
> 
> **Overview**
> Cuts the `7.64.0` release by bumping Android version
(`versionName`/`versionCode`) and adding a full `7.64.0` section to
`CHANGELOG.md` (updating the compare links accordingly).
> 
> Updates CI/test automation: expands Smart E2E selection to also emit
*performance test tags* and display them in step summaries/comments;
migrates various E2E tool paths from `e2e/tools` to `tests/tools`,
adjusts Detox to run smoke API specs from `tests/smoke/api-specs`, and
temporarily broadens tag sharding search base to repo root.
> 
> Improves release/build workflows by adding a reusable `build.yml`,
making Bitrise BrowserStack build workflows accept an overridable
`branch_name`, hardening `ci.yml` for `merge_group` events (skip some
jobs and treat `skipped` appropriately), and adding Slack notifications
for RC builds (with Node setup + dependency install to support the new
script).
> 
> Housekeeping/config updates include new Cursor rules/docs, adding
`.env` to `.gitignore`, depcheck ignore list tweaks, appium/appwright
patches for chromedriver auto-download/webviews, `push-eas-update` env
flag adjustments (including disabling LavaMoat in CI), Android debug
network security config for user cert trust, a new optional
`infuraNetworkClientId` on network banner actions, and removal of
several legacy approval/action modules and associated tests/snapshots.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
e935da4. 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?
-->

Remove redundant bitrise step and fix Sentry sourcemaps upload process

We don't need sourcemaps to be uploaded to Bitrise. 

## **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.
…mponents (#25786)

## **Description**

Decompose the monolithic `PredictMarketDetails` view from **1,391 → 492
lines** to improve maintainability and readability.

The original component handled rendering, data transformation, and state
management for the entire market details screen in a single file. This
PR extracts focused sub-components and custom hooks while preserving all
existing behavior and test coverage.

### Extracted Components (8)

All live under
`app/components/UI/Predict/views/PredictMarketDetails/components/`:

| Component | What It Does |
|-----------|--------------|
| `PredictMarketDetailsAbout` | Volume, dates, resolution details,
description, disclaimer |
| `PredictMarketDetailsStatus` | Resolution status badges
(resolved/ended/waiting) |
| `PredictMarketDetailsPositions` | Active + claimable position list |
| `PredictMarketDetailsHeader` | Back button, market image, title, share
button, skeleton |
| `PredictMarketDetailsTabBar` | Tab navigation
(positions/outcomes/about) |
| `PredictMarketDetailsActions` | Claim button, Yes/No buy buttons,
skeleton |
| `PredictMarketDetailsOutcomes` | 4-branch conditional outcome
rendering (owns `isResolvedExpanded` state) |
| `PredictMarketDetailsTabContent` | Tab content dispatch (flat file, no
directory) |

### Extracted Hooks (3)

All live under
`app/components/UI/Predict/views/PredictMarketDetails/hooks/`:

| Hook | What It Does |
|------|--------------|
| `useChartData` | Chart memos, price history fetching, adaptive
fidelity, timeframe management |
| `useOutcomeResolution` | Winning/losing token detection, resolution
status, derived booleans |
| `useOpenOutcomes` | Real-time price-enriched outcomes via WebSocket |

### Design Principles

- All sub-components wrapped in `React.memo()` for render isolation
- Data flows via props only — no hook imports in sub-components
- Each component in its own directory with barrel `index.ts` export
- All existing `testID` strings preserved for test compatibility
- No extra DOM wrappers that would break test traversal patterns

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: PredictMarketDetails refactor

  Scenario: user navigates to a prediction market
    Given user has the Predict feature enabled

    When user taps on any prediction market from the feed
    Then market details screen renders identically to before the refactor
    And all tabs (Positions, Outcomes, About) function correctly
    And chart interactions work as expected
    And buy/claim actions work as expected
```

## **Screenshots/Recordings**

This is a pure refactor — no visual or behavioral changes. The UI is
pixel-identical before and after.

### **Before**

N/A — no visual changes

### **After**

N/A — no visual changes

https://www.loom.com/share/2fbb140ca4af4485ba8991df69214f3b

## **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**
> Primarily a refactor, but it re-plumbs complex conditional rendering
and chart/timeframe logic across new components/hooks, so regressions
could show up in edge-case market states and loading/refresh flows.
> 
> **Overview**
> Refactors `PredictMarketDetails` from a monolithic screen into a
composition of memoized subcomponents (`Header`, `Status`, `TabBar`,
`TabContent`, `Actions`, plus tab-specific
`About`/`Positions`/`Outcomes`) and pushes the prior inline render
helpers into these dedicated files.
> 
> Extracts derived-data and fetching logic into hooks: `useChartData`
(timeframe state, adaptive fidelity, price history fetch + series
building), `useOpenOutcomes` (real-time price-enriched open outcomes +
`yesPercentage`), and `useOutcomeResolution` (winning/losing token +
resolution-derived booleans), and wires the screen to use these results
for chart rendering, outcomes rendering, and action button labels.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d46a903. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

This PR implements persistent browser tab mounting to improve tab
switching performance and user experience.


Tabs should not reload when they you switch back and forth from already
opened tab to different one. Please keep in mind that Webview is managed
by system so in case of low ram system still could suspend Webview and
it reload then (and that's actually good because we don't need to manage
resources manually).

### What changed:
1. **Keep all browser tabs mounted** - Previously only the active tab
was rendered, now all non-archived tabs remain mounted in the DOM
2. **Prevent inactive tabs from handling events** - Added guards to
ensure inactive tabs don't process navigation requests, file downloads,
or JavaScript dialogs
3. **Upgraded `@metamask/react-native-webview`** - Bumped from patched
v14.5.0 to v14.6.0, which includes the Android permission dialog fixes
and iOS binary download suppression that were previously in our patch

### Why:
- Faster tab switching since tabs don't need to re-render/re-initialize
- Preserves tab state (scroll position, form data, etc.) when switching
between tabs
- Removes the need for a custom patch as fixes are now upstream

### Key implementation details:
- `onShouldStartLoadWithRequest` returns `false` for inactive tabs
- `handleOnFileDownload` early-returns for inactive tabs
- WebView props `allowFileDownloads={isTabActive}` and
`suppressJavaScriptDialogs={!isTabActive}` ensure only active tabs can
trigger downloads and dialogs

## **Changelog**

CHANGELOG entry: Improved browser tab switching performance by keeping
tabs mounted

## **Related issues**

Refs: #25701

## **Manual testing steps**

```gherkin
Feature: Browser tab persistence

  Scenario: user switches between browser tabs
    Given user has the app open with multiple browser tabs loaded

    When user switches from tab A to tab B
    Then tab B should load instantly without re-rendering
    And tab A's scroll position should be preserved when switching back

  Scenario: inactive tabs don't show JavaScript dialogs
    Given user has multiple browser tabs open
    And a background tab has a page with alert() or confirm()

    When user is viewing a different active tab
    Then no JavaScript dialogs should appear from the inactive tab

  Scenario: inactive tabs don't trigger file downloads
    Given user has multiple browser tabs open
    And a background tab initiates a file download

    When user is viewing a different active tab
    Then no download prompt should appear from the inactive tab
```

## **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**
> Changes tab rendering lifecycle and WebView event handling, which can
affect navigation, downloads, and dialogs across multiple tabs.
Dependency upgrade/removal of a patch may introduce platform-specific
behavioral differences (Android permissions/iOS downloads).
> 
> **Overview**
> **Keeps in-app browser tabs mounted** by rendering all non-archived
tabs instead of only the active one, preventing reloads/state loss when
switching tabs.
> 
> To avoid background tabs interfering, `BrowserTab` now blocks
navigation and download handling when inactive, and toggles WebView
behavior via `allowFileDownloads={isTabActive}` and
`suppressJavaScriptDialogs={!isTabActive}`. The PR also removes the
custom Yarn patch by upgrading `@metamask/react-native-webview` to
`14.6.0` (and updating iOS pods/lockfiles) to pick up the upstreamed
permission/download fixes.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0bf90fc. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Nodonisko <suchydan@gmail.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**
When new networks are added to the chainRanking remote feature flag in
LaunchDarkly, older app versions that don't support those networks would
still surface them in the UI (destination network pills, source chain
checks). This creates a forward-compatibility gap where users could see
unsupported networks.

This change adds client-side filtering of chainRanking against
ALLOWED_BRIDGE_CHAIN_IDS — the hardcoded allowlist in
@metamask/bridge-controller that defines which chains this version of
the client actually supports. This ensures that chains added to the
remote flag in the future are silently ignored by older app versions
that lack support for them.

<!--
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]
> **Low Risk**
> Narrow change to selector filtering logic with comprehensive unit test
coverage; main risk is unintentionally hiding a chain if allowlist/CAIP
formatting is incorrect.
> 
> **Overview**
> Prevents *forward-incompatible* networks from being surfaced when the
remote `bridgeConfigV2.chainRanking` feature flag adds new chains that
older clients don’t support.
> 
> Adds a shared `isAllowedBridgeChainId` guard and applies it to
`selectSourceChainRanking`, `selectDestChainRanking`, and
`selectIsBridgeEnabledSourceFactory` so only allowlisted EVM/non-EVM
CAIP chain IDs are considered. Updates/adds unit tests to cover
allowlist filtering for source/dest ranking and source-enabled checks.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
93e1367. 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?
-->

## **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**
> Workflow-only tuning of build-time resource limits; the main risk is
slightly slower repack builds or different CI memory behavior, with no
product/runtime impact.
> 
> **Overview**
> Updates the Android E2E build GitHub Actions workflow to allocate more
Node.js heap during the cached-APK repack step by bumping `NODE_OPTIONS`
from 4GB to 8GB.
> 
> To reduce overall memory pressure while repacking, it also lowers
Metro concurrency by changing `METRO_MAX_WORKERS` from 4 to 2 for that
step.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
1f9476c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
This PR syncs the stable branch to main for version 7.66.0.

*Synchronization Process:*

- Fetches the latest changes from the remote repository
- Resets the branch to match the stable branch
- Attempts to merge changes from main into the branch
- Handles merge conflicts if they occur

*File Preservation:*

Preserves specific files from the stable branch:
  - CHANGELOG.md
  - bitrise.yml
  - android/app/build.gradle
  - ios/MetaMask.xcodeproj/project.pbxproj
  - package.json

  Indicates the next version candidate of main to 7.66.0

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Documentation-only change to `CHANGELOG.md` with no runtime or build
impact.
> 
> **Overview**
> Updates `CHANGELOG.md` by adding a new **`7.64.0`** release section
with the curated *Added* and *Fixed* entries for that release.
> 
> Also updates the compare links at the bottom so `Unreleased` now
compares from `v7.64.0`, and adds a new `7.64.0` compare link
(`v7.63.1...v7.64.0`).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
958022b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…dates (#25696)

Bumps the npm_and_yarn group with 2 updates in the /.github/scripts
directory: [glob](https://github.com/isaacs/node-glob) and
[undici](https://github.com/nodejs/undici).

Updates `glob` from 10.4.5 to 10.5.0
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/isaacs/node-glob/commit/56774ef73b495eb0b17cdd0f42921f5ef62297c1"><code>56774ef</code></a>
10.5.0</li>
<li><a
href="https://github.com/isaacs/node-glob/commit/1e4e297342a09f2aa0ced87fcd4a70ddc325d75f"><code>1e4e297</code></a>
bin: Do not expose filenames to shell expansion</li>
<li>See full diff in <a
href="https://github.com/isaacs/node-glob/compare/v10.4.5...v10.5.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `undici` from 5.28.4 to 5.29.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/nodejs/undici/releases">undici's
releases</a>.</em></p>
<blockquote>
<h2>v5.29.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Fix tests in v5.x for Node 20 by <a
href="https://github.com/mcollina"><code>@​mcollina</code></a> in <a
href="https://redirect.github.com/nodejs/undici/pull/4104">nodejs/undici#4104</a></li>
<li>Removed clients with unrecoverable errors from the Pool <a
href="https://redirect.github.com/nodejs/undici/pull/4088">nodejs/undici#4088</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/nodejs/undici/compare/v5.28.5...v5.29.0">https://github.com/nodejs/undici/compare/v5.28.5...v5.29.0</a></p>
<h2>v5.28.5</h2>
<h1>⚠️ Security Release ⚠️</h1>
<p>Fixes CVE CVE-2025-22150 <a
href="https://github.com/nodejs/undici/security/advisories/GHSA-c76h-2ccp-4975">https://github.com/nodejs/undici/security/advisories/GHSA-c76h-2ccp-4975</a>
(embargoed until 22-01-2025).</p>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/nodejs/undici/compare/v5.28.4...v5.28.5">https://github.com/nodejs/undici/compare/v5.28.4...v5.28.5</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/nodejs/undici/commit/9528f6853a72a637823e863f1dd12ec47a3fc9e7"><code>9528f68</code></a>
Bumped v5.29.0</li>
<li><a
href="https://github.com/nodejs/undici/commit/f1d75a4e107866110c48003f00e5d0de52ef2cce"><code>f1d75a4</code></a>
increase timeout for redirect test</li>
<li><a
href="https://github.com/nodejs/undici/commit/2d31ed61f7ca12ef6d89a323dc236346364ac379"><code>2d31ed6</code></a>
remove fuzzing tests</li>
<li><a
href="https://github.com/nodejs/undici/commit/6b36d49cb2fa14217baa11b6fd27ee20b661ea4c"><code>6b36d49</code></a>
fix redirect test in Node v16</li>
<li><a
href="https://github.com/nodejs/undici/commit/648dd8f7ba3654db09a095361a167e3576db8cd0"><code>648dd8f</code></a>
more fix for the wpt runner on Windows</li>
<li><a
href="https://github.com/nodejs/undici/commit/a0516bae59b6aa8aa8124f9ae5cfed79541d10e2"><code>a0516ba</code></a>
don't use internal header state for cookies (<a
href="https://redirect.github.com/nodejs/undici/issues/3295">#3295</a>)</li>
<li><a
href="https://github.com/nodejs/undici/commit/87ce4af0e58657506cedb2d07a5ba24f964b733f"><code>87ce4af</code></a>
fix test/client for node 20</li>
<li><a
href="https://github.com/nodejs/undici/commit/c2c8fd55b778267ad8b2e9ee04218c038a5d02af"><code>c2c8fd5</code></a>
fix: accept v20 SSL specific error for alpn selection in http/2</li>
<li><a
href="https://github.com/nodejs/undici/commit/82200bd10b7073ac235f8fc48d4daa82b350cd4c"><code>82200bd</code></a>
[v6.x] fix wpts on windows (<a
href="https://redirect.github.com/nodejs/undici/issues/4093">#4093</a>)</li>
<li><a
href="https://github.com/nodejs/undici/commit/47546fa68d04eec5b96ab93225c3bc08b77cd94f"><code>47546fa</code></a>
test: fix windows wpt (<a
href="https://redirect.github.com/nodejs/undici/issues/4050">#4050</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/nodejs/undici/compare/v5.28.4...v5.29.0">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/MetaMask/metamask-mobile/network/alerts).

</details>

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Lockfile-only dependency bumps for GitHub automation scripts; low
blast radius, with typical risk limited to potential behavior changes in
`glob`/`undici` used by those scripts.
> 
> **Overview**
> Updates the `.github/scripts` lockfile to bump two transitive Node
dependencies: `glob` from `10.4.5` to `10.5.0` and `undici` from
`5.28.4` to `5.29.0` (lockfile checksums/resolutions updated
accordingly).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
44157aa. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: sethkfman <10342624+sethkfman@users.noreply.github.com>
## **Description**

This PR upgrades the MetaMask design system packages to their latest
versions and adjusts ButtonIcon sizes in the wallet header:
- `@metamask/design-system-react-native`: 0.5.0 → 0.5.1
- `@metamask/design-system-twrnc-preset`: 0.3.0 (no new version
available)
- `@metamask/design-system-shared`: 0.1.1 → 0.1.2 (dependency upgrade)

**Release Notes:**
https://github.com/MetaMask/metamask-design-system/releases/tag/%40metamask%2Fdesign-system-react-native%400.5.1

### Key Changes in 0.5.1

The primary update in this version is a fix to the `ButtonIcon`
component icon dimensions to match Figma designs:
- `ButtonIcon.Sm`: icon size increased to 20px (from 16px)
- `ButtonIcon.Md`: icon size increased to 24px (from 20px)
- `ButtonIcon.Lg`: icon size increased to 32px (from 24px)
- Non-floating border radius corrected to 4px (from 2px)

### Additional Changes

**Wallet Header ButtonIcon Size Reduction:**

To maintain appropriate visual hierarchy, all ButtonIcon components in
the wallet header have been reduced from Large (32px) to Medium (24px):
- Copy button (AddressCopy component)
- Card button (CardButton component)
- QR Code Scanner button
- Notifications button
- Menu button

This ensures the header icons remain properly sized after the design
system update and provides better visual balance.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: N/A

## **Manual testing steps**

```gherkin
Feature: Design System Package Upgrade

  Scenario: user uses the app with upgraded design system
    Given the app is built with the upgraded design system packages

    When user navigates through the app and interacts with UI components using ButtonIcon
    Then all ButtonIcon components should render with the correct icon sizes and border radius
    And the wallet header icons should be properly sized at 24px (Medium)
```

## **Screenshots/Recordings**

### **Before**


https://github.com/user-attachments/assets/8703ff8a-75e0-4615-9abf-7d730dda6bda

### **After**


https://github.com/user-attachments/assets/81c59794-a24c-4814-bc28-c01454304a8b

## **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
- [ ] 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**
> Primarily UI-sizing and styling changes plus snapshot updates; low
functional risk beyond potential visual/layout regressions.
> 
> **Overview**
> Updates `@metamask/design-system-react-native` to `^0.5.1` and aligns
the app with upstream `ButtonIcon` visual changes (larger icon glyph
sizes and updated non-floating border radius).
> 
> To keep wallet header icon hierarchy consistent after the
design-system update, reduces several header `ButtonIcon` usages from
`Lg` to `Md` (copy, card, QR scan, notifications, menu) and adds spacing
between header action buttons (`gap: 8`). Snapshot tests are updated
accordingly across multiple UI surfaces (Earn, Ramp, Bridge, Perps,
Multichain).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
90b95a2. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@pull pull Bot locked and limited conversation to collaborators Feb 7, 2026
@pull pull Bot added the ⤵️ pull label Feb 7, 2026
@pull pull Bot merged commit 0bad657 into Reality2byte:main Feb 7, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants