Skip to content

release: 7.61.0#23381

Merged
joaoloureirop merged 394 commits into
stablefrom
release/7.61.0
Dec 18, 2025
Merged

release: 7.61.0#23381
joaoloureirop merged 394 commits into
stablefrom
release/7.61.0

Conversation

@metamaskbot
Copy link
Copy Markdown
Collaborator

@metamaskbot metamaskbot commented Nov 27, 2025

🚀 v7.61.0 Testing & Release Quality Process

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


📋 Key Processes

Testing Strategy

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

GitHub Signoff

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

Issue Resolution

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

Cherry-Picking Criteria

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

🗓️ Timeline and Milestones

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

✅ Signoff Checklist

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

Team sign-off checklist

  • Accounts Framework
  • Assets
  • Bots Team
  • Card
  • Confirmations
  • Core Platform
  • Design System
  • Earn
  • Extension Platform
  • Mobile Platform
  • Mobile UX
  • Network Enablement
  • New Networks
  • Onboarding
  • Perps
  • Predict
  • Product Safety
  • Ramp
  • Rewards
  • Swaps and Bridge
  • team-web3auth
  • Transactions
  • Wallet Integrations
  • web3auth
  • Web3auth

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

caieu and others added 30 commits November 20, 2025 22:59
<!--
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**

Update withdrawal toast messages to be clearer and more user-friendly:
- Simplify pending withdrawal title from "Withdrawing {amount} USDC" to
"Withdrawal in progress"
- Change pending subtitle to "Available in about 1 minute" for clearer
expectation
- Update completed message from "Withdrawal completed" to "Withdrawal
complete"
- Revise completed subtitle to "{amount} USDC moved to your wallet" for
clarity
- Format withdrawal amounts using formatPrice utility for consistent
display

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

## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

Fixes:
https://consensyssoftware.atlassian.net/browse/PRED-312?atlOrigin=eyJpIjoiYjZjMTlkNjRjYzEwNDY5OGE1ODczMjI4MGRlNGEwYzkiLCJwIjoiaiJ9

## **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]
> Simplifies Predict withdrawal toasts and locales, removing dynamic
placeholders and formatting amounts with `formatPrice`.
> 
> - **Predict UI**:
>   - `app/components/UI/Predict/hooks/usePredictWithdrawToasts.ts`:
>     - Format confirmed withdrawal amounts with `formatPrice`.
> - Pending toast no longer passes `amount`/`time`; uses static
`withdrawing`/`withdrawing_subtitle` strings.
>     - Updated pending/confirmed toast configs to match new copy.
> - **Locales**:
>   - `locales/languages/en.json`:
> - Simplified `predict.withdraw` strings (static pending
title/subtitle; refined completed title/subtitle).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
eaaea2d. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…22231)

## **Description**

This PR implements a simplified A/B testing framework for Perps to
support TAT-1937 (Long/Short button color test). The framework leverages
LaunchDarkly for user identification, variant assignment, and
persistence, keeping our implementation minimal and focused on reading
variants and applying them.

**What is the reason for the change?**
- We need to test which button colors (green/red vs white/white) drive
better trading behavior
- This is the first A/B test for Perps and establishes the framework for
future tests
- The test will help us understand if traditional colors or neutral
colors lead to better metrics (trade initiation rate, execution rate,
misclick rate)

**What is the improvement/solution?**
- Created lightweight A/B testing utilities in
`app/components/UI/Perps/utils/abTesting/`
- LaunchDarkly handles all complex logic (assignment, persistence,
tracking)
- Simple hook (`usePerpsABTest`) reads variant and applies button colors
- Flat property pattern supports multiple concurrent AB tests (TAT-1937,
TAT-1940, TAT-1827)
- Dual tracking approach: screen views (baseline exposure) + button
presses (engagement) to calculate engagement rate

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: TAT-1937

## **Manual testing steps**

### Testing Control Variant (Production - LaunchDarkly)
```gherkin
Feature: Button Color A/B Test - Control Variant

  Scenario: user sees traditional green/red buttons
    Given LaunchDarkly assigns user to "control" variant

    When user navigates to Perps home
    And user selects any asset (e.g., BTC)
    Then user sees asset details screen with green Long / red Short buttons
    And dev banner shows "control (LaunchDarkly)"
```

### Testing Monochrome Variant (Production - LaunchDarkly)
```gherkin
Feature: Button Color A/B Test - Monochrome Variant

  Scenario: user sees neutral white buttons
    Given LaunchDarkly assigns user to "monochrome" variant

    When user navigates to asset details screen
    Then user sees white Long / white Short buttons
    And dev banner shows "monochrome (LaunchDarkly)"
```

### Testing Fallback Behavior
```gherkin
Feature: Button Color A/B Test - Fallback

  Scenario: LaunchDarkly unavailable
    Given LaunchDarkly flag is disabled or unavailable

    When user navigates to asset details screen
    Then user sees control variant (green/red) as fallback
    And dev banner shows "control (Fallback)"
```

### Quick Local Testing Instructions

**For LaunchDarkly Testing (Default):**
1. Configure LaunchDarkly flag `perps-abtest-button-color` to return
`"control"` or `"monochrome"`
2. App automatically uses the feature flag value
3. **Navigate to**: Perps � Select any asset (view asset details screen)
4. **Check dev banner**: Shows current variant and source
(LaunchDarkly/Fallback)

**For Local Dev Testing (Temporary Hardcode):**
If you need to test a specific variant locally without LaunchDarkly:
1. Open `PerpsMarketDetailsView.tsx`
2. Temporarily hardcode the variant after the `usePerpsABTest` call:
   ```typescript
   const buttonColorVariant = 'monochrome'; // Force specific variant
   ```
3. **Remember to remove before committing!**

**Dev Info Banner:**
- Blue banner at top of asset details screen
- Shows: variant name, source (LaunchDarkly/Fallback), and raw flag
value
- Read-only informational display
- Helps debug which variant is active

### Verifying AB Test Tracking

**Dual Tracking Approach:**

1. **Screen View (Baseline Exposure)**
- **Event:** `PERPS_SCREEN_VIEWED` with `screen_type: 'asset_details'`
- **Properties:** `ab_test_button_color` (only when test enabled),
`asset`, `source`
- **Purpose:** Establishes how many users were exposed to each variant

2. **Button Press (Engagement)**
   - **Event:** `PERPS_UI_INTERACTION` with `interaction_type: 'tap'`
- **Properties:** `ab_test_button_color` (only when test enabled),
`asset`, `direction`
   - **Purpose:** Measures which variant drives more button presses

**Metric Calculation:**
- **Engagement Rate** = Button presses / Screen views per variant
- Answers: "Which button color makes users more likely to press the
button?"

## **Screenshots/Recordings**

### **Before**
N/A - New feature

### **After**

<!-- TODO: Add screenshots showing:
1. Control variant (green Long button, red Short button)
2. Monochrome variant (white Long button, white Short button)
3. Event tracking in analytics showing AB test properties
-->

## **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 (manual validation first, unit
tests will be added later)
- [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.

---

## **Additional Context**

### Architecture

```
LaunchDarkly (Remote)
    � Returns variant name ('control' | 'monochrome')
Feature Flag Selector (selectPerpsButtonColorTestVariant)
    �
usePerpsABTest Hook
    � Returns variant data (e.g., button colors)
Component (PerpsMarketDetailsView)
```

### Files Changed

**New Files:**
- `app/components/UI/Perps/utils/abTesting/types.ts` - Type definitions
- `app/components/UI/Perps/utils/abTesting/usePerpsABTest.ts` - Main
hook
- `app/components/UI/Perps/utils/abTesting/tests.ts` - Test
configurations
- `app/components/UI/Perps/constants/buttonColors.ts` - Color mappings
- `docs/perps/perps-ab-testing.md` - Centralized AB testing
documentation

**Modified Files:**
- `app/components/UI/Perps/selectors/featureFlags/index.ts` - Added
variant selector
- `app/components/UI/Perps/constants/eventNames.ts` - Added flat AB test
properties (per test)
-
`app/components/UI/Perps/Views/PerpsMarketDetailsView/PerpsMarketDetailsView.tsx`
- Dual tracking: screen view (baseline) + button press (engagement)
- `docs/perps/perps-metametrics-reference.md` - Documented dual tracking
approach in both events

### Backend Requirements

**LaunchDarkly Flag Setup:**

**IMPORTANT: Use String flag type, not Boolean or JSON**

**Naming Convention:** `perps-abtest-{test-name}` (no `-enabled` suffix
needed)

**MetaMetrics Requirement:** Users must have MetaMetrics enabled
(Settings → Security & Privacy → MetaMetrics) for A/B testing (for
privacy).

1. **Flag key**: `perps-abtest-button-color` (kebab-case)
2. **Flag type**: **String** (select from dropdown)
3. **String Variations**:
   - Variation 0: Name=`Control`, Value=`control`
   - Variation 1: Name=`Monochrome`, Value=`monochrome`
4. **Targeting Rules**:
- IF user `anonymous` is one of `false` (filters MetaMetrics opted-in
users)
   - THEN serve percentage rollout:
     - 50% → `control`
     - 50% → `monochrome`
   - Optional: Add custom rule for `appVersion >= 7.60.0`
5. **Default Variations**:
   - When ON: `control` (for opted-in users)
   - When OFF: flag disabled (returns null/undefined)

**What the app receives:**
```typescript
// Redux state (kebab-case converted to camelCase)
{
  remoteFeatureFlags: {
    perpsAbtestButtonColor: "control"  // Simple string value
  }
}
```

### Metrics to Monitor

**Analytics Approach:** Dual tracking (screen views + button presses)
enables engagement rate calculation.

Once deployed with LaunchDarkly enabled:
- **Engagement rate**: (Button presses / Screen views) per variant -
PRIMARY METRIC
- **Button presses**: Total Long/Short button presses per variant
- **Trade execution rate**: % users pressing buttons → completing trades
(by variant)
- **Misclick rate**: % trades cancelled/reversed within 10s (by variant)
- **Transaction speed**: Time from button press to trade execution (by
variant)

**Key Question:** Which button color makes users more likely to press
the button?

### Documentation

Full framework documentation available in:
- `docs/perps/perps-ab-testing.md` - AB testing architecture and
patterns
- `docs/perps/perps-metametrics-reference.md` - Event properties and
tracking

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds LaunchDarkly-driven A/B testing with a button color experiment,
integrates variant-driven UI and analytics on Perps market details, and
updates selectors, utilities, tests, and docs.
> 
> - **Perps UI (Market Details)**:
> - Integrates A/B test for Long/Short buttons; renders monochrome
(Secondary) or semantic green/red based on `perpsAbtestButtonColor`.
> - Tracks variant on screen view and button press for analytics
(baseline + engagement).
> - **AB Testing Framework**:
> - New hook `usePerpsABTest`, types, and test config
`BUTTON_COLOR_TEST`.
>   - Button color utilities (`constants/buttonColors.ts`).
> - **Feature Flags & Selectors**:
> - New selector `selectPerpsButtonColorTestVariant` with version-gated
handling.
> - Adds type guard `isVersionGatedFeatureFlag` and enhances remote flag
validation.
> - **Analytics**:
> - Extends `eventNames` with AB test properties/values (e.g.,
`ab_test_button_color`).
> - **Tests**:
> - Unit tests for selector variants, hook behavior, and remote feature
flag type guard/validation.
> - **Docs**:
> - Adds `perps-ab-testing.md`; updates MetaMetrics reference for
dual-tracking and flat AB test properties.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
61fbc1b. 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?
-->

Bump slippage for Sell orders to 3% (from 1.5%). This will help reducing
the failure rate.

## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

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

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Increase sell-order slippage to 3% and introduce separate buy/sell
slippage constants, applying them in order previews.
> 
> - **Polymarket provider**:
> - **Slippage constants**: Replace `SLIPPAGE` with `SLIPPAGE_BUY`
(1.5%) and `SLIPPAGE_SELL` (3%) in
`app/components/UI/Predict/providers/polymarket/constants.ts`.
> - **Order preview**: In
`app/components/UI/Predict/providers/polymarket/utils.ts`, use
`SLIPPAGE_BUY` for buy previews and `SLIPPAGE_SELL` for sell previews;
update imports accordingly.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
582821f. 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?
-->

Currently the GTM modal for Predict looks funky as it seems to render
different pieces at different times.
This PR attempts to fix this by introducing two main changes:
- Animate opacity for the whole modals 0 -> 1
- Only start animation when the background image finishes loading

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


https://github.com/user-attachments/assets/a8b61805-9f8a-4518-b37c-7cedf56d806b




### **After**

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



https://github.com/user-attachments/assets/41d44fed-56ff-4ec6-b800-867d5530e15f



## **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]
> Adds a reanimated opacity fade-in for the Predict GTM modal that
starts once the background image finishes loading.
> 
> - **UI/Animation**:
> - Wraps modal root in `Animated.View` and animates `opacity` from 0→1
with `withTiming`.
> - Starts animation on background image `onLoad` via `useState` +
`useEffect` and `useSharedValue`/`useAnimatedStyle`.
> - Ensures content appears only after image loads for smoother reveal.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
ae4bba0. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…2232)

## **Description**

### Problem
The `PerpsMarketDetailsView` was creating duplicate Sentry traces for
"Perps Fetch Historical Candles" due to two concurrent REST API calls
for the same coin:
1. **Chart Data**: User-selected interval (e.g., 3m, 5m, 15m) via
`usePerpsPositionData`
2. **24h Stats**: Fixed 1h interval for high/low calculation via
`usePerpsMarketStats`

Both used `setInterval` polling, resulting in:
- Unnecessary network traffic from repeated REST calls
- No cache sharing between different intervals
- Mixed architecture (prices use WebSocket, candles use REST)
- Identical Sentry trace names making debugging difficult

### Solution
Migrated candle data from REST polling to WebSocket streaming pattern,
following the established architecture for prices, orders, and
positions:

1. **Created `CandleStreamChannel`** - Lazy-loaded streaming
infrastructure (no prewarm)
2. **Added `subscribeToCandles()`** to HyperLiquidClientService and
PerpsController
3. **Created `usePerpsLiveCandles`** hook - Drop-in replacement for
`usePerpsPositionData`
4. **Migrated consumers** - Updated `usePerpsMarketStats` and
`PerpsMarketDetailsView`
5. **Removed old implementation** - Deleted `usePerpsPositionData` and
tests

### Benefits
� **Eliminates duplicate Sentry traces** - Each (coin, interval)
combination gets distinct subscription
� **Real-time updates** - WebSocket push instead of polling (no
`setInterval`)
� **Cache sharing** - Multiple components using same (coin, interval) =
1 WebSocket connection
� **Auto-cleanup** - Unsubscribe when components unmount
� **Protocol-agnostic** - Architecture supports future providers
(Binance, dYdX, etc.)
� **Consistent pattern** - Matches existing streaming channels (prices,
orders, positions)

### Trade-off
The system maintains **2 WebSocket subscriptions per coin** as required
by product:
- **Chart**: User-selected interval (3m/5m/15m/etc) for visual detail
- **Stats**: Fixed 1h interval for 24h high/low calculation

This is **not a bug** - different granularities are needed for different
use cases. If product unifies to a single interval in the future, the
architecture will automatically reduce to 1 subscription (no code
changes needed).

### Android Rendering Fix
During testing, we discovered that the WebSocket migration exposed a
race condition on Android devices. The chart data often arrived before
the WebView finished initializing (Android WebView is 2-3x slower than
iOS), causing:
- Black screens when switching markets or intervals
- Skeleton loader staying visible indefinitely
- Poor user experience on mid-range Android devices

**Fix:** Added data buffering to hold early-arriving data until the
chart is ready, and kept the chart component mounted during interval
switches to avoid expensive WebView reinitialization.

**Impact:** Chart now loads smoothly on Android with no black screens,
even on slower devices. This was caught during testing of the WebSocket
streaming feature.

## **Changelog**

CHANGELOG entry: Improved candle data loading with real-time WebSocket
updates

## **Related issues**

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

## **Manual testing steps**

**⚠️ Important:** Test on Android device (especially mid-range) - chart
should display smoothly when switching markets/intervals with no black
screens.

```gherkin
Feature: Real-time Candle Data via WebSocket

  Scenario: User views market details with live chart updates
    Given user is on the Perps Market Details screen for BTC
    And the chart displays candle data with user-selected interval (e.g., 3m)

    When market price changes
    Then the chart updates in real-time without manual refresh
    And the 24h high/low stats update automatically
    And no duplicate Sentry traces appear in monitoring

  Scenario: User switches between different chart intervals
    Given user is viewing BTC market with 1h candles

    When user switches to 3m interval
    Then the chart loads 3m candles via WebSocket
    And the old 1h subscription is cleaned up
    And the new 3m subscription is established

  Scenario: Multiple components share candle cache
    Given two components both need BTC 1h candles

    When both components mount
    Then only 1 WebSocket subscription is created
    And both components receive the same cached data

  Scenario: User navigates away from market details
    Given user is viewing BTC market with active candle subscriptions

    When user navigates away
    Then WebSocket subscriptions are automatically cleaned up
    And no orphaned connections remain

  Scenario: User switches between markets
    Given user is viewing BTC market with candles loaded

    When user switches to ETH market
    Then BTC candle subscription is cleaned up
    And ETH candle subscription is established
    And each market has its own cached data
```

## **Screenshots/Recordings**

### **Before**
- REST polling via `setInterval` every 1-4 hours depending on interval
- Duplicate Sentry traces with identical names
- No cache sharing between intervals
- Manual refresh required for updates

### **After**
- Real-time WebSocket streaming
- Distinct subscriptions per (coin, interval)
- Automatic cache sharing across components
- Live updates without manual refresh


https://github.com/user-attachments/assets/0eda7d8a-6469-478e-b13f-dbe2a6239ee9


## **Technical Details**

### Architecture
```
Component (usePerpsLiveCandles)
    � (React integration, throttling)
CandleStreamChannel
    � (cache sharing, lazy load/cleanup)
PerpsController.subscribeToCandles()
    � (protocol-agnostic abstraction)
HyperLiquidClientService.subscribeToCandles()
    � (REST initial + WebSocket append)
SDK: subscriptionClient.candle()
    � (individual CandleEvent objects)
```

### Files Changed

**Created (2)**:
- `providers/channels/CandleStreamChannel.ts` - Core streaming
infrastructure
- `hooks/stream/usePerpsLiveCandles.ts` - React hook API

**Modified (8)**:
- `services/HyperLiquidClientService.ts` - Added `subscribeToCandles()`
method
- `controllers/PerpsController.ts` - Added protocol-agnostic delegation
- `providers/PerpsStreamManager.tsx` - Integrated CandleStreamChannel
- `hooks/usePerpsMarketStats.ts` - Migrated to new hook
- `Views/PerpsMarketDetailsView/PerpsMarketDetailsView.tsx` - Migrated
to new hook, removed conditional chart rendering
- `components/TradingViewChart/TradingViewChart.tsx` - Added data
buffering and fixed skeleton logic for Android
- `app/util/trace.ts` - Removed unused trace name

**Deleted (2)**:
- `hooks/usePerpsPositionData.ts`
- `hooks/usePerpsPositionData.test.ts`

### Performance Impact
**Before (REST Polling)**:
- 2 REST calls per market (different intervals)
- Polling every 60s - 4h depending on interval
- No cache sharing

**After (WebSocket Streaming)**:
- 2 WebSocket subscriptions per market
- Real-time push updates (no polling)
- Cache shared across components using same (coin, interval)
- Auto-cleanup when unmounted � 0 connections

## **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]
> Replaces REST/polling candles with WebSocket streaming across stack,
updates UI chart to consume live data and fetch more history, and adds
provider/controller support with tests.
> 
> - **Streaming architecture**:
> - Add `subscribeToCandles` in provider (`HyperLiquidClientService`),
controller (`PerpsController`), and types (`SubscribeCandlesParams`).
> - Introduce `CandleStreamChannel` in `providers/channels` and wire
into `PerpsStreamManager` as `candles`.
> - Expose `usePerpsLiveCandles` hook (`hooks/stream`) for real-time
candles (with `fetchMoreHistory`).
> - **UI integration**:
> - Migrate `PerpsMarketDetailsView` to `usePerpsLiveCandles`; remove
manual refresh of candles.
> - Enhance `TradingViewChart`/template: data buffering, symbol
validation, `CLEAR_DATA`, `NEED_MORE_HISTORY` edge-detection callback,
skeleton logic, `onNeedMoreHistory` prop.
> - Update `usePerpsMarketStats` to derive 24h high/low from live 1h
candles.
> - **Historical candles API**:
> - Support `endTime` in `MarketDataService.fetchHistoricalCandles` and
provider client; use dynamic limits and merge older candles on demand.
> - **Removals/cleanup**:
> - Remove `usePerpsPositionData` and related tests; adjust existing
tests to WebSocket behavior (no candle refresh expectations).
> - **Tests**:
> - Add comprehensive tests for `usePerpsLiveCandles`,
`CandleStreamChannel`, `HyperLiquidClientService.subscribeToCandles`,
and updated services; update `MarketDataService` tests for `endTime`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
59514c6. 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?
-->

* fix: race condition in rive animations when animation fail to start.
* Jira: https://consensyssoftware.atlassian.net/browse/SL-332
* Issue: #23048

In some device on edge cases, sometime the MetaMask riv logo does not
appear during the onboarding screen animation.
This is due to race conditions between state triggers and the rive
onPlay state.

This PR wait for onPlay state before fire the inputState

## **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:
#23048
* race condition in rive animations when animation fail to start.
## **Manual testing steps**

```gherkin
Feature: onboarding

  Scenario: user open the app after install
    Given user open the app after install
    Then user should see the Metamask riv logo 
```

## **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/834c82d8-9fbf-4c96-943d-1ea067115401




### **After**
<!-- [screenshots/recordings] -->


https://github.com/user-attachments/assets/c4bca6d3-3bec-4be8-a68a-882770676ac4


## **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]
> Delay animation triggers until Rive reports onPlay, fixing race
conditions that caused onboarding/fox animations to not start.
> 
> - **UI**
> - `FoxAnimation`: add `isPlaying` state and `onPlay` handler; trigger
`fireState('FoxRaiseUp', ...)` only after play starts; remove `autoplay`
usage.
> - `OnboardingAnimation`: gate `startRiveAnimation` on `isPlaying`; add
`onPlay` to set ready state; remove `autoplay` usage.
> - **Testing/Mocks**
> - Update `app/__mocks__/rive-react-native.tsx` to accept `onPlay` and
invoke it on mount for tests.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b36851c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Gaurav Goel <grvgoel19@gmail.com>
## **Description**

Improves bottom sheet responsiveness by reducing animation duration from
`300ms` to `150ms`. This makes interactions feel 2x faster while
remaining smooth and within industry standards (150-300ms range).

**Why this change:**
- Current 300ms feels slightly sluggish for frequent interactions
- 150ms strikes the optimal balance between speed and smoothness
- Aligns with modern UI expectations for responsive interactions

**Technical change:**
- Updated `DEFAULT_BOTTOMSHEETDIALOG_DISPLAY_DURATION` constant
- Changed from `AnimationDuration.Regularly` (300ms) to
`AnimationDuration.Fast` (150ms)
- Single line change in
`/app/.../foundation/BottomSheetDialog/BottomSheetDialog.constants.ts`

## **Impacted Bottom Sheets**

This affects **all** bottom sheet components across the app:

#### Account Management
- `AccountSelector` - Account picker/switcher
- `AddAccountActions` - Add account options menu
- `AddNewAccountBottomSheet` - New account creation flow
- `DeleteAccount` - Account deletion confirmation
- `EditAccountName` - Rename account sheet
- `EditMultichainAccountName` - Rename multichain account
- `MultichainAccountActions` - Multichain account options
- `ShareAddress` / `ShareAddressQR` - Address sharing sheets
- `WalletAddAccountActions` - Wallet details add account menu

#### Network & Connections
- `NetworkSelector` - Network picker/switcher
- `NetworkListBottomSheet` - Network selection list
- `NetworkFilterBottomSheet` - Network filter options
- `RpcSelectionModal` - RPC endpoint selector
- `AccountConnect` - dApp connection flow
- `AccountPermissions` - Connection permissions manager
- `MultichainAccountConnect` - Multichain connection flow
- `MultichainPermissionsSummary` - Permissions overview
- `ConnectedAccountsModal` - Connected accounts list

#### Wallet Actions & Trading
- `WalletActions` - Buy, Sell, Send, Receive, Bridge actions
- `TradeWalletActions` - Trading-specific actions
- `SendActionBottomSheet` - Send flow actions

#### Transactions & Confirmations
- `ConfirmComponent` - Transaction confirmation sheet
- `PersonalSign` - Personal signature requests
- `TypedSign` - Typed signature requests
- `SignatureRequest` - Generic signature requests
- `ContractApprovalBottomSheet` - Contract approval confirmations
- `SmartAccountUpdateModal` - Smart account updates
- `SwitchAccountTypeModal` - Account type switching

#### Settings & Configuration
- `ContactForm` - Add/edit contact
- `DeleteContactBottomSheet` - Contact deletion confirmation
- `NetworkSettings` - Network configuration
- `FiatOnTestnetsFriction` - Testnet fiat warning
- `DataCollectionModal` - Analytics preferences
- `ExperienceEnhancerModal` - Onboarding enhancement

#### Assets & NFTs
- `AddAsset` - Import token/NFT flow
- `AssetOptions` - Asset action menu
- `NftOptions` - NFT action menu
- `ShowTokenIdSheet` - Token ID display
- `ShowIpfsGatewaySheet` - IPFS gateway display
- `ShowDisplayNFTMediaSheet` - NFT media display

#### SDK & Browser
- `SDKSessionModal` - SDK session management
- `SDKLoadingModal` - SDK loading state
- `SDKFeedbackModal` - SDK feedback collection
- `SDKDisconnectModal` - SDK disconnect confirmation
- `MaxBrowserTabsModal` - Browser tab limit warning

#### Other UI Components
- `TooltipModal` - Contextual tooltips
- `SuccessErrorSheet` - Success/error messages
- `OriginSpamModal` - Spam origin warnings
- `ChangeInSimulationModal` - Simulation change alerts
- `SelectSRPBottomSheet` - SRP selection
- `OnboardingSheet` - Onboarding flows
- `AmbiguousAddressSheet` - Address disambiguation

---

## **Changelog**

CHANGELOG entry: Improved bottom sheet animation speed for more
responsive interactions

## **Related issues**

N/A

## **Manual testing steps**

```gherkin
Feature: Faster bottom sheet animations

  Scenario: User opens and closes bottom sheets
    Given the user is on the wallet home screen
    When the user opens account selector or network selector
    Then the bottom sheet should animate up in 150ms (noticeably faster than 300ms)
    When the user dismisses the sheet by swiping down or tapping outside
    Then it should animate down in 150ms
    
  Scenario: User interacts with wallet actions
    Given the user is on the wallet home screen
    When the user taps "Buy & Sell" or any wallet action button
    Then the wallet actions bottom sheet should appear quickly with 150ms animation
    
  Scenario: User connects to a dApp
    Given the user is browsing a dApp
    When the dApp requests connection
    Then the account connect bottom sheet should animate up smoothly in 150ms
```

## **Screenshots/Recordings**

### **Before**
300ms animation (`AnimationDuration.Regularly`)

### **After**
150ms animation (`AnimationDuration.Fast`) - 2x faster, more responsive
feel

## **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]
> Speeds up BottomSheetDialog initial display by changing duration from
`AnimationDuration.Regularly` to `AnimationDuration.Fast`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
c432773. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Brian August Nguyen <brianacnguyen@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**
Fixes bug where bridge transactions didn't have network badges in the
activity list

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

## **Changelog**

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

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

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

CHANGELOG entry: Fixed bug where bridge transactions didn't have network
badges in the activity list

## **Related issues**

Fixes: #22868

## **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]
> Adds a network badge overlay to bridge transaction icons in the
activity list using the source asset’s chain ID.
> 
> - **UI**:
> - **Bridge Activity List Item
(`MultichainBridgeTransactionListItem.tsx`)**:
> - Wraps transaction icon with `BadgeWrapper` and `Badge` (Network
variant) showing the network image.
> - Derives `chainId` from `quote.srcAsset.assetId` via
`parseCaipAssetType` and fetches image with `getNetworkImageSource`.
>     - Falls back to the original icon when `chainId` is unavailable.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
c538bac. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…tInput` (#23037)

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

This PR adds zero balance check before `onAmountInput` RPC call to
nonEVM send flow amount validations.

<!--
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: #22812

## **Manual testing steps**

1. Go to send flow
2. Don't have any Tron / SOL / BTC
3. Try sending it but see "insufficient balance" error

## **Screenshots/Recordings**

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

### **Before**

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

### **After**



https://github.com/user-attachments/assets/ab16a8fe-7da7-4da5-9ee5-684bb0a62e50



## **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]
> Adds a zero-balance pre-check for non-EVM assets in amount validation
and updates tests to cover it.
> 
> - **Validation (useAmountValidation)**:
> - Add non-EVM pre-check `rawBalanceBN.isZero()` to return
`"send.insufficient_funds"` before `onAmountInput` snap validation in
`useAmountValidation.ts`.
>   - Update hook dependencies to include `rawBalanceBN`.
> - **Tests**:
> - Extend `useAmountValidation.test.ts` with SOLANA mocks and a test
asserting error when non-EVM asset balance is zero.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
bf695af. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…states cp-7.60.0 (#23090)

<!--
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 fixes the calculation of return on equity (ROE) percentage for
aggregated account states across multiple DEX accounts in the Perps
feature. Previously, the ROE was calculated using a simple formula that
didn't account for the different margin amounts across accounts, which
could lead to inaccurate percentage values.


## **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 return on equity percentage calculation for
aggregated Perps positions across multiple DEX accounts

## **Related issues**

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

## **Manual testing steps**

```gherkin
Feature: Perps aggregated account ROE calculation

  Scenario: user views aggregated account state with multiple DEX positions
    Given user has multiple Perps positions across different DEX accounts with varying margin amounts
    And each position has different unrealized PnL and ROE values
    
    When user views the aggregated account state
    Then the displayed ROE percentage should be a weighted average based on margin used
    And the calculation should correctly handle accounts with zero or negative values
    And invalid or NaN values should be skipped in the calculation
```

## **Screenshots/Recordings**

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

### **Before**

<!-- [screenshots/recordings] -->
![Screenshot_20251121_104805_MetaMask
(1)](https://github.com/user-attachments/assets/17e6528f-981d-4b36-a83b-4fa43762645d)


### **After**

<!-- [screenshots/recordings] -->
<img width="1170" height="2532" alt="Simulator Screenshot - iPhone 16e -
2025-11-21 at 11 23 26"
src="https://github.com/user-attachments/assets/23a33e94-e8b2-4b63-b57a-031fc5276653"
/>


## **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]
> Replaces aggregate ROE with a margin-weighted calculation and adds
comprehensive unit tests.
> 
> - **Perps utils**:
> - **Weighted ROE**: Add `calculateWeightedReturnOnEquity` (and
`ReturnOnEquityInput`) in
`app/components/UI/Perps/utils/accountUtils.ts` to compute
margin-weighted ROE across accounts.
> - Integrate weighted ROE in
`HyperLiquidSubscriptionService.aggregateAccountStates()` by using
`calculateWeightedReturnOnEquity` instead of the previous simple ratio.
> - **Tests**:
> - Add extensive unit tests in
`app/components/UI/Perps/utils/accountUtils.test.ts` covering mixed
types, edge cases (zero/negative/NaN), precision, and multi-account
scenarios.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
334fcd6. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…ing `getNetworkImageSource` (#23089)

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

Incorrect Network (Solana) is displayed on dapp browsing when I have
Bitcoin/ or Tron selected in my wallet, because current logic either
renders EVM selected network, or defaults to Solana when something other
than EVM is selected.

This PR proposes a fix to handle non EVM networks accordingly.

<!--
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: Add logic to compute the correct non-EVM network image
source using `getNetworkImageSource`

## **Related issues**

Fixes: #22787

## **Manual testing steps**

```gherkin
Feature: Non EVM Image for AccountRightButton Component

  Scenario: user selects non evm network
    Given he does so in In App Browser

    When user selects non evm network via In App Browser AccountRightButton
    Then the correct network image should be displayed
```

## **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/e2d114cb-2a99-497b-9417-ee7877e98fc7

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

### **After**


https://github.com/user-attachments/assets/5ca5dc99-e94a-41e3-a48c-371762a7320c

<!-- [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]
> Computes the proper non-EVM network image using getNetworkImageSource
and replaces the hardcoded Solana fallback in AccountRightButton.
> 
> - **UI**:
> - **AccountRightButton
(`app/components/UI/AccountRightButton/index.tsx`)**:
> - Compute non-EVM network image via `useMemo` and
`getNetworkImageSource` using `selectedNonEvmNetworkChainId`.
> - Replace hardcoded Solana fallback with computed `imageSource`; EVM
logic unchanged.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
2851891. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…3064)

## **Description**

Reduce loading time when starting Perps and Predict deposit
confirmations.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:
[#6162](MetaMask/MetaMask-planning#6162)
[#6165](MetaMask/MetaMask-planning#6165)

## **Manual testing steps**

## **Screenshots/Recordings**

### **Before**

### **After**

## **Pre-merge author checklist**

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

## **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]
> Speeds up confirmation flows with memoization and streamlined
pay-token logic, adds safer Perps/Predict transaction options, updates
alerts/UI, and bumps transaction-controller.
> 
> - **Confirmations/Pay UX & Performance**:
> - Memoize calculations in `useGasFeeToken`, `useTokenAmount`, and
`pay-token-amount` with skeleton fallback; reduce recomputations and
unnecessary renders.
> - Refactor `useAutomaticTransactionPayToken` to use
`useTransactionPayAvailableTokens`, simplify selection logic, and remove
count-return path; update related tests.
> - Update `useTransactionPayMetrics` to derive payment token list size
from available tokens and drop dependency on automatic selector.
> - Improve `useTransactionPayToken` by making gas estimate fetch
non-blocking and flushing Engine state immediately.
> - Tighten recipient detection in `useTransferRecipient` to explicit
transfer types only.
> - **Perps/Predict Transactions**:
> - Perps deposit: add `skipInitialGasEstimate: true` when calling
`TransactionController.addTransaction`; test updated.
> - Predict deposit: add `disableUpgrade: true` and
`skipInitialGasEstimate: true` to `addTransactionBatch` options; tests
updated.
> - Safe utils: mark generated proxy/allowance/claim transactions as
`TransactionType.contractInteraction`.
> - **Alerts & Localization**:
> - `useInsufficientPayTokenBalanceAlert`: handle zero/negative target
amounts with alternate copy; add
`insufficient_pay_token_balance_fees_no_target` locale string.
> - **Engine**:
> - `EngineService`: flush Redux updates immediately for
`ApprovalController` and expose `flushState()`.
> - **Dependencies**:
> - Bump `@metamask/transaction-controller` to `62.1.0` (package.json
and yarn.lock).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f7c039c. 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**

Upgrading tron to `1.10.0`
https://github.com/MetaMask/snap-tron-wallet/releases/tag/v1.10.0

<!--
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: #22889

## **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]
> <sup>[Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) is
generating a summary for commit
cfa573a. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
#23105)

## **Description**

Fixed bottom padding in the Perps tab view where the "Start trading"
button was overlapping with the bottom navigation's "+" action button,
particularly noticeable on Android. Increased bottom padding from 12px
to 20px for both the positions/orders view and empty state to provide
adequate clearance.

**Changes:**
- Updated `tradeInfoContainer` style: paddingBottom from 12 to 30
- Added `emptyStateContainer` style with paddingBottom: 30
- Wrapped `PerpsEmptyState` component with styled View to apply
consistent padding

## **Changelog**

CHANGELOG entry: Fixed bottom padding in Perps tab to prevent overlap
with bottom navigation button

## **Related issues**

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

## **Manual testing steps**

```gherkin
Feature: Perps tab bottom padding

  Scenario: user views Perps tab with positions/orders
    Given user has open positions or orders in the Perps tab

    When user navigates to the Perps tab
    Then the "Start trading" button should have adequate clearance from the bottom navigation
    And the button should not overlap with the "+" action button

  Scenario: user views empty Perps tab
    Given user has no positions or orders

    When user navigates to the Perps tab
    Then the empty state should have adequate clearance from the bottom navigation
    And content should not overlap with the "+" action button
```

## **Screenshots/Recordings**

### **Before**

<!-- Android: Start trading button overlapping with + button -->
<img width="397" height="376" alt="image"
src="https://github.com/user-attachments/assets/1df51259-b43f-4f5f-99ec-e415e7fbad17"
/>

<!-- iOS: Tight spacing with + button -->
<img width="412" height="476" alt="image"
src="https://github.com/user-attachments/assets/3e2ae99e-ec12-4a9d-967a-b7e5b815c243"
/>

### **After**

<!-- Android: 20px clearance from + button -->
<!-- iOS: 20px clearance from + button (consistent with Android) -->
<img width="397" height="432" alt="image"
src="https://github.com/user-attachments/assets/221fe494-181a-4122-924b-0107ee8b7f8c"
/>

## **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]
> Increase bottom padding for trade info and empty states in
`PerpsTabView` and wrap empty state in a padded container to avoid
overlap with bottom navigation.
> 
> - **UI (PerpsTabView)**:
>   - **Padding adjustments**:
> - `tradeInfoContainer` `paddingBottom`: `12` -> `30` in
`app/components/UI/Perps/Views/PerpsTabView/PerpsTabView.styles.ts`.
>     - Add `emptyStateContainer` with `paddingBottom: 30`.
>   - **Empty state layout**:
> - Wrap `PerpsEmptyState` in a `View` using
`styles.emptyStateContainer` in
`app/components/UI/Perps/Views/PerpsTabView/PerpsTabView.tsx` to apply
consistent bottom spacing.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f5dc7ad. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…3057)

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

Adds error and unsupported routing handling to the `useRampNavigation`
hook. The `goToBuy` function now checks the routing decision first and
navigates to the appropriate modal when the routing decision is `ERROR`
or `UNSUPPORTED`, before any other routing logic executes.

**Changes:**
- Added imports for `createEligibilityFailedModalNavigationDetails` and
`createRampUnsupportedModalNavigationDetails`
- Added early return checks in `goToBuy` to handle
`UnifiedRampRoutingType.ERROR` and `UnifiedRampRoutingType.UNSUPPORTED`
routing decisions
- When `ERROR` is detected, navigates to the eligibility failed modal
- When `UNSUPPORTED` is detected, navigates to the unsupported region
modal

This ensures users see appropriate error messages when ramp services are
unavailable or unsupported in their region, rather than attempting to
navigate to unavailable flows.

## **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 error and unsupported region handling to ramp
navigation flow

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: Ramp navigation error handling
Scenario: user attempts to buy when routing decision is ERROR
Given the app has a routing decision of ERROR
When user triggers the buy flow
Then the eligibility failed modal should be displayed
Scenario: user attempts to buy when routing decision is UNSUPPORTED
Given the app has a routing decision of UNSUPPORTED
When user triggers the buy flow
Then the unsupported region modal should be displayed
```

## **Screenshots/Recordings**

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

### **Before**

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

### **After**


https://github.com/user-attachments/assets/6eb13363-2412-481b-b268-3ef1c3a58070



https://github.com/user-attachments/assets/5ffd32ef-6798-41a0-b868-dc258bb1b294


<!-- [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]
> Adds early routing in `useRampNavigation.goToBuy` to show
eligibility-failed or unsupported modals when unified V1 is enabled,
with accompanying tests.
> 
> - **Hook updates**
>   - In `app/components/UI/Ramp/hooks/useRampNavigation.ts`:
> - `goToBuy` now checks `UnifiedRampRoutingType` first under unified
V1.
> - Routes to `createEligibilityFailedModalNavigationDetails()` on
`ERROR` and to `createRampUnsupportedModalNavigationDetails()` on
`UNSUPPORTED` (early return).
> - Preserves existing token selection and smart routing for `DEPOSIT`
vs `AGGREGATOR` when an `assetId` is present.
> - **Tests**
>   - In `app/components/UI/Ramp/hooks/useRampNavigation.test.ts`:
> - Adds test coverage for `ERROR` and `UNSUPPORTED` decisions
navigating to the respective modals (with and without intent).
>     - Retains tests for token selection and smart routing behaviors.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
7e686bb. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
….60.0 (#23102)

<!--
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 an issue where the `filterTabs` array in `PerpsTransactionsView`
was using translated strings, which could cause mismatches with the
filter logic that expects hardcoded values ('Trades', 'Orders',
'Funding', 'Deposits').

## **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 an issue where orders, and deposits would not
show if the user is not using english locale

## **Related issues**

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

## **Manual testing steps**

```gherkin
Feature: Perps Transactions View Filter Tabs

  Scenario: user switches between transaction filter tabs
    Given the user is on the Perps Transactions screen
    And the user uses French language
    And the user has transaction history data

    When user taps on the "Orders" tab
    Then the Orders filter should be active
    And only order transactions should be displayed

    When user taps on the "Funding" tab
    Then the Funding filter should be active
    And only funding transactions should be displayed

    When user taps on the "Deposits" tab
    Then the Deposits filter should be active
    And only deposit/withdrawal transactions should be displayed

    When user taps on the "Trades" tab
    Then the Trades filter should be active
    And only trade transactions should be displayed
```

## **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/53fd37db-a03c-4b68-985b-68d3beab20a7



### **After**

<!-- [screenshots/recordings] -->
<img width="1170" height="2532" alt="Simulator Screenshot - iPhone 16e -
2025-11-21 at 13 02 25"
src="https://github.com/user-attachments/assets/aaa03b7f-746c-46ab-b471-87c2e176ed70"
/>

## **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]
> Use static `['Trades','Orders','Funding','Deposits']` for `filterTabs`
in `PerpsTransactionsView` to align with `FilterTab` and avoid locale
mismatches.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
22cf93d. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

This PR updates the Deposit BuildQuote screen title from "Deposit" to
"Buy" to better align with user-facing terminology and improve clarity
of the feature's purpose.

**Context**: As part of TRAM-2853, we're standardizing the naming across
the ramps experience. The Deposit feature is fundamentally a "buy
crypto" flow, so the title should reflect that action.

**Changes**:
- Updated `deposit.buildQuote.title` in `locales/languages/en.json` from
"Deposit" to "Buy"
- Updated test snapshots to reflect the title change

## **Changelog**

CHANGELOG entry: Changed Deposit BuildQuote screen title to "Buy"

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TRAM-2855
Refs: https://consensyssoftware.atlassian.net/browse/TRAM-2853

## **Manual testing steps**

```gherkin
Feature: Deposit BuildQuote Title

  Scenario: user views the Deposit BuildQuote screen
    Given the user has opened MetaMask Mobile
    And the user navigates to the Deposit flow

    When the user reaches the BuildQuote screen
    Then the screen title should display "Buy" instead of "Deposit"
```

## **Screenshots/Recordings**

### **Before**

<img width="300" alt="image"
src="https://github.com/user-attachments/assets/94e7a4fe-c74d-4fdb-ac57-eb0368deb36b"
/>


### **After**

<img width="300" alt="image"
src="https://github.com/user-attachments/assets/a13043e8-2dfc-4c1b-83fc-2256e32b9b4a"
/>


## **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]
> Renames the Ramp BuildQuote screen title from "Deposit" to "Buy" and
updates corresponding snapshots and localization.
> 
> - **Localization**:
> - Update `deposit.buildQuote.title` in `locales/languages/en.json`
from `"Deposit"` to `"Buy"`.
> - **Tests**:
> - Refresh `BuildQuote` snapshots to reflect UI text change from
`"Deposit"` to `"Buy"` in
`app/components/UI/Ramp/Deposit/Views/BuildQuote/__snapshots__/BuildQuote.test.tsx.snap`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
ab0383d. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…gated balance (#23113)

<!--
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 aggregated balances on mobile
core PR: MetaMask/core#7216

<!--
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 missing native token balances in wallet balance

## **Related issues**

Fixes: #22775 

## **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]
> Patches @metamask/assets-controllers to lowercase account addresses
when updating token balances, resolving missing aggregated balances.
> 
> - **Assets Controllers Patch**:
> - Normalize account addresses to lowercase in
`dist/TokenBalancesController.{cjs,mjs}` when reading/writing
`d.tokenBalances[account]` to ensure balance updates persist.
> - **Dependencies**:
> - Switch `@metamask/assets-controllers@89.0.1` to a Yarn `patch:`
source in `package.json` and register the patch in `yarn.lock`
(`.yarn/patches/@metamask-assets-controllers-npm-89.0.1-02fa7acd54.patch`).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0fb1c03. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

This PR updates the copy for the Sell/Withdraw functionality in the
Ramps flow to improve clarity and consistency across the application.

**What is the reason for the change?**
The current implementation uses "Withdraw" terminology in various places
when referring to the sell crypto functionality. This can be confusing
for users as "Withdraw" typically implies moving funds from one account
to another, rather than selling crypto for cash.

**What is the improvement/solution?**
Updated all user-facing strings to consistently use "Sell" instead of
"Withdraw" for the sell crypto flow:
1. Fund Action Menu button and description
2. Asset Overview sell button  
3. Build Quote screen titles (simplified from "Amount to buy/sell" to
just "Buy/Sell")

This creates a clearer mental model for users and aligns with the actual
functionality - selling crypto for cash.

## **Changelog**

CHANGELOG entry: Changed "Withdraw" to "Sell" in the Fund Action Menu
and Asset Overview for improved clarity.

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TRAM-2854 (subtask
of https://consensyssoftware.atlassian.net/browse/TRAM-2853)

## **Manual testing steps**

```gherkin
Feature: Sell button copy changes

  Scenario: User views Fund Action Menu
    Given user is on the Wallet screen
    And user has a token with balance

    When user taps the "Buy" button on a token
    Then the Fund Action Menu should display
    And the sell option should read "Sell" (not "Withdraw")
    And the description should read "Sell crypto for cash"

  Scenario: User navigates to Build Quote for Sell
    Given user is on the Wallet screen
    And user has opened the Fund Action Menu

    When user taps the "Sell" button
    Then the Build Quote screen should open
    And the header title should display "Sell" (not "Amount to sell")

  Scenario: User navigates to Build Quote for Buy
    Given user is on the Wallet screen
    And user has opened the Fund Action Menu

    When user taps the "Buy" button
    Then the Build Quote screen should open
    And the header title should display "Buy" (not "Amount to buy")
```

## **Screenshots/Recordings**

| **Before** | **After** |
|------------|-----------|
| **Fund Action Menu - "Withdraw" button** | **Fund Action Menu - "Sell"
button** |
| <img width="300" alt="image"
src="https://github.com/user-attachments/assets/3de0e566-499b-46b5-8a14-4f3773c459b9"
/> | <img width="300" alt="image"
src="https://github.com/user-attachments/assets/1ba9354e-74f8-439c-8a1f-ba3c95dd9ae8"
/> |
| **Asset Overview - "Withdraw" button** | **Asset Overview - "Sell"
button** |
| <img width="300" alt="image"
src="https://github.com/user-attachments/assets/bedbab7c-ee06-4131-a149-3e3c90c67052"
/> | <img width="300" alt="image"
src="https://github.com/user-attachments/assets/6a60c1ef-4ae5-4b56-a070-f99987b39d74"
/> |
| **Build Quote - "Amount to buy" title** | **Build Quote - "Buy"
title** |
| <img width="300" alt="image"
src="https://github.com/user-attachments/assets/89559466-ec4b-4552-b878-19a778746901"
/> | <img width="300" alt="image"
src="https://github.com/user-attachments/assets/a71ffc50-ed6e-40af-8be5-636c170b7b71"
/> |
| **Build Quote - "Amount to sell" title** | **Build Quote - "Sell"
title** |
| <img width="300" alt="image"
src="https://github.com/user-attachments/assets/cd1f863c-7a2b-4315-a49a-0c15d7005be5"
/> | <img width="300" alt="image"
src="https://github.com/user-attachments/assets/116cc053-14a9-41e0-a7b8-295a833701a1"
/> |



## **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]
> Replaces "Withdraw" with "Sell" across ramp UI strings and updates
Build Quote headers from "Amount to buy/sell" to "Buy/Sell", with
snapshots refreshed.
> 
> - **i18n (en)**:
> - Update `fund_actionmenu.sell` and `asset_overview.sell_button` from
`Withdraw` to `Sell` in `locales/languages/en.json`.
> - Simplify Build Quote labels: `fiat_on_ramp_aggregator.amount_to_buy`
-> `Buy`, `amount_to_sell` -> `Sell`.
> - **UI tests**:
> - Refresh snapshots in
`app/components/UI/Ramp/Aggregator/Views/BuildQuote/__snapshots__/BuildQuote.test.tsx.snap`
reflecting title changes from `Amount to buy/sell` to `Buy/Sell`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
93c5b2d. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

This PR updates the README.md to improve branding consistency and visual
presentation:

1. **Updated main heading**: Changed from "MetaMask" to "MetaMask
Mobile" to better reflect that this is the mobile repository
2. **Refined logo display**: Converted the logo from markdown image
syntax to HTML `<img>` tag with a fixed width of 50px for better size
control and consistency

These changes improve the README's visual hierarchy and make it
immediately clear that this is the MetaMask Mobile repository.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Refs: 

## **Manual testing steps**

```gherkin
Feature: README documentation

  Scenario: user views the repository README
    Given the user navigates to the repository on GitHub
    
    When the user views the README.md
    Then the logo should display at 50px width
    And the main heading should read "MetaMask Mobile"
```

## **Screenshots/Recordings**

### **Before**
- Large logo using markdown syntax
- Heading: "MetaMask"

### **After**
- Compact logo (50px) using HTML img tag
- Heading: "MetaMask Mobile"

## **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]
> Update README: switch logo to 50px HTML image and rename main heading
to “MetaMask Mobile.”
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
a8669a1. 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**
Adds the first iteration of the mUSD conversion flow. This PR includes
the core flow that we will iterate on.
<!--
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: add mUSD conversion core flow

## **Related issues**

Fixes: 
- [MUSD-64: Mobile Proof of Concept using Transactions
Confirmations](https://consensyssoftware.atlassian.net/browse/MUSD-64)
- [MUSD-69: Use relay for quotes and execution in the Mobile one click
proof of
concept](https://consensyssoftware.atlassian.net/browse/MUSD-69)
- [MUSD-42: Merge mobile mUSD conversion to
production](https://consensyssoftware.atlassian.net/browse/MUSD-42)
- [MUSD-86: As a user I want to see information about the relay quote
when converting to mUSD so that I know how much money I will spend on
fees and gas](https://consensyssoftware.atlassian.net/browse/MUSD-86)

## **Manual testing steps**

```gherkin
Feature: mUSD Token Conversion

  Scenario: user converts stablecoin to mUSD on Ethereum mainnet (happy path)
    Given user has USDC, USDT, or DAI in their wallet on a supported chain
    
    When user clicks the "Convert" button next to a supported mUSD conversion stablecoin
    Then user sees the mUSD conversion confirmation screen
    And user can select from available stablecoins in the PayWith modal
    And user can input desired conversion amount
    And user sees Relay quotes with fees and estimated time
    And user completes the conversion flow successfully
    
  Scenario: user views unsupported token
    Given user has a non-convertible token in their wallet
    
    When user views their token list
    Then user sees the existing "Earn X.X%" CTA
    And user does NOT see the mUSD conversion button
```

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

https://github.com/user-attachments/assets/be636076-79bd-4b6d-818a-6f6f5b707b06

## **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]
> Adds mUSD conversion flow with Convert CTA, confirmations, global
status toasts, feature flags, and localization.
> 
> - **Earn/mUSD**:
> - Add `mUSD` conversion flow with `Convert` CTA in `StakeButton` and
token list for allowlisted stablecoins.
> - Introduce global `EarnTransactionMonitor` and
`useMusdConversionStatus` to show in-progress/success/failure toasts.
> - Add `MusdConversionInfo` screen and wire into redesigned
confirmations stack.
> - **Confirmations**:
> - Define `MUSD_CONVERSION_TRANSACTION_TYPE`; hide footer by default;
add custom button label and fees tooltip; include in
redesigned/full-screen types.
>   - Update transaction parsing/labels to recognize mUSD conversion.
> - **Feature Flags/Selectors**:
> - Add `MM_MUSD_CONVERSION_FLOW_ENABLED` and convertible tokens
allowlist (remote/local) with symbol→address conversion.
> - **Constants/Utils**:
> - mUSD token constants, chain/token allowlists, and
`isMusdConversionPaymentToken` helper.
> - **Navigation**:
> - Register redesigned confirmations route in Earn stack; mount
`EarnTransactionMonitor` in main nav.
> - **Localization**:
> - Add strings for mUSD conversion (CTA, toasts, fees, review titles).
> - **CI/Env**:
> - Expose env/Bitrise flags for mUSD conversion; sample allowlist var.
> - **Tests**:
> - Comprehensive unit tests for hooks, selectors, utils, components
(CTA rendering, navigation, error cases).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
8a6f35d. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…ing the omnisearch and other minor improvements (#22872)

<!--
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**
According to the
[these](https://www.figma.com/design/w4EHAWR5h0OTuqeqZKaCAH/Trending?node-id=2067-19515&p=f&t=6z6WJZtGvd6H9A8L-0)
designs. I have implemented the following:

<img width="685" height="501" alt="image"
src="https://github.com/user-attachments/assets/9e52f5b0-b16e-4b29-abab-02f0d356b1c1"
/>


Furthermore I have done some code cleanup 🧹  and 🐛 fixes:
- Added screen sliding animation to Perps
- Removed debounce from useSearchRequest
- When going back from browser we should be able to go back to search
results
- Removed pagination dots in carrousel
- Used TW in carrousel
- Updated "View all >" to match styles
- Updated search for trending tokens to merge Trending and non-trending
tokens
- Fix searchbar causing app crash due to showing and hiding element
- Show loading while isDebouncing on useExploreSearch
- Refactored sections to be react elements rather than functions
- Adjust pills padding
- Update size of section titles
- Update color of search section titles
- Add icons to pills
- Add grey arrow in view all and change "View all" color
- Change screen title to "Explore"
- Change bottom menu icon and name to "Explore"
- Change the icon to explore icon instead of plus [+]
- Make the tab number container thinner [1]
- Remove carrousel padding left to be aligned
- Remove padding from section titles

NOTE: There are still some bugs 🐛 that will be solved in upcoming PRs:
- Clicking on native token in search throws error
- Tokens from search API do not have "Volume" "Market Cap"...

<!--
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: allow navigating to a website or search on google using
the omnisearch

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/ASSETS-1800 &
https://consensyssoftware.atlassian.net/browse/ASSETS-1801 &
https://consensyssoftware.atlassian.net/browse/ASSETS-1822

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



https://github.com/user-attachments/assets/e0994d22-01d9-4a7a-a23e-4b960b1e6675



<!-- [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]
> Adds Explore search footer to open URLs or Google results, rebrands
Trending to Explore, refactors section components/UI, and improves
navigation/animations.
> 
> - **Explore/Search**:
> - Add footer actions to open direct URLs and Google searches from
`ExploreSearchResults`; navigates via `TrendingBrowser` with
`fromTrending`.
> - Integrate token search (`useSearchRequest`) with trending results;
show loading while debouncing; remove debounce delay (0ms).
> - Update `ExploreSearchBar`: autofocus by type, non-destructive clear
with opacity toggle, always-visible cancel, color tweaks.
> - **UI Refactor**:
> - Convert section config to component-based API (`RowItem`,
`Skeleton`, `Section`); update usages in `SectionCard`,
`SectionCarrousel`, `TrendingView`.
> - Redesign QuickActions to pill buttons with icons and TW styles;
adjust section headers (“View all” with arrow, sizes/colors).
> - Simplify carousel (remove pagination dots; TW spacing) and align
layouts/padding.
> - **Navigation/Browser**:
> - `BrowserTab` back behavior respects `fromTrending` to return to
search; trending browser wrapper intercepts navigation.
> - **Perps**:
>   - Enable slide-in animation for Perps stack screens.
> - **Localization & Tab Bar**:
> - Rename Bottom Tab “Trending” to “Explore” and change icon
(`Search`); update `trending.title` and bottom nav strings.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
cab5efc. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: sahar-fehri <sahar.fehri@consensys.net>
… cp-7.60.0 (#23128)

<!--
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 a bug where staked energy and staked bandwidth were displaying in
the swap tokens lists

<!--
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 a bug where staked energy and staked bandwidth
were displaying in the swap tokens lists

## **Related issues**

Fixes: #23141

## **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]
> Switches non-tradable Tron token detection to symbol-based checks
using shared constants and updates tests accordingly.
> 
> - **Bridge utils**:
> - Update `isTradableToken` to determine non-tradable Tron tokens by
`symbol` using `TRON_RESOURCE_SYMBOLS` (from
`core/Multichain/constants`) instead of name matching.
> - **Tests**:
> - Adjust `isTradableToken` tests to validate symbol-based filtering
(e.g., `energy`, `bandwidth`, `max-bandwidth`, mixed/upper case).
> - Update `useTokens` tests to use `symbol: 'Max-Bandwidth'` and verify
filtering of non-tradable Tron tokens across `tokensWithBalance`,
`topTokens`, and `remainingTokens`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
9b18269. 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]
> Expands Sentry app state mask to include
`engine.backgroundState.AppMetadataController` (all properties) and
`user.existingUser`.
> 
> - **Sentry utils (`app/util/sentry/utils.ts`)**:
>   - Expand `sentryStateMask`:
> - Add `engine.backgroundState.AppMetadataController` with
`[AllProperties]: true`.
>     - Add `user.existingUser: true`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
a3ac483. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Earn banner border and background are wrong colors

## **Changelog**

CHANGELOG entry:null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MDP-398

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

`~`

### **Before**

<img width="500" alt="Simulator Screenshot - iPhone 16 Pro Max -
2025-11-06 at 12 28 10"
src="https://github.com/user-attachments/assets/a1d1dab8-db90-4aff-8a14-b43ab7a69f5c"
/>

### **After**

<img width="500" height="2868" alt="Simulator Screenshot - iPhone 16 Pro
Max - 2025-11-06 at 12 28 00"
src="https://github.com/user-attachments/assets/0aaae517-ae69-45e5-9eac-0545c601a184"
/>

## **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]
> Switch Earn banner and Stake EstimatedAnnualRewardsCard to muted
backgrounds without borders; update snapshots accordingly.
> 
> - **UI**:
> - `EarnInputView` banner: set background to `#3c4d9d0f`; remove
`borderWidth`/`borderColor`.
> - `Stake/components/EstimatedAnnualRewardsCard`: use
`colors.background.muted`; remove border styling.
> - **Tests**:
> - Update snapshots in `EarnInputView.test.tsx.snap` to reflect new
styles.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
ccc5689. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

This PR refactors the Card onboarding flow to improve the KYC
verification process and user experience:

- **New VerifyingRegistration screen**: Adds a dedicated screen showing
users their registration is being verified
- **Enhanced navigation**: Restructures onboarding navigator with
`cardUserPhase` parameter, removes `Complete` screen, implements proper
navigation resets
- **Improved KYC polling**: Better polling lifecycle management with
manual `startPolling` control and automatic stopping on completion
- **Authentication UI refactor**: Updates `CardAuthentication` to use
`KeyboardAwareScrollView` and Tailwind styles
- **Code cleanup**: Replaces `useIsCardholder` hook with
`selectHasCardholderAccounts` selector
- **SDK enhancements**: Adds `getUserDetails` method and exposes
`fetchUserData` in CardSDKProvider
- **Bug fix**: Fixes `validateDateOfBirth` to accept negative timestamps
(dates before 1970)

## **Changelog**

CHANGELOG entry: Improved Card onboarding flow with new verification
screen and enhanced KYC process navigation

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: Card Onboarding Flow

  Scenario: user completes card onboarding with address verification
    Given user is on the Card welcome screen
    And user has not completed onboarding

    When user proceeds through authentication
    And user enters their physical address
    And user confirms their mailing address
    Then user should see the Verifying Registration screen
    And KYC verification polling should start automatically

  Scenario: user returns to app during verification
    Given user has submitted their registration details
    And KYC verification is pending

    When user opens the app
    Then user should be directed to the Verifying Registration screen
    And polling should resume to check verification status

  Scenario: user completes KYC verification
    Given user is on the Verifying Registration screen
    And KYC verification completes successfully

    When the polling detects verification completion
    Then user should be navigated to the appropriate next screen
    And polling should stop automatically
```

## **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]
> Refactors Card onboarding/KYC with a new Verifying Registration screen
and polling, KYC-gated home actions and alerts, SDK/user data
enhancements, updated navigation, and UI/auth improvements.
> 
> - **Onboarding/KYC Flow**:
> - Add `VerifyingRegistration` screen with polling and
success/timeout/rejected states; new route
`Routes.CARD.VERIFYING_REGISTRATION`.
> - Refactor `OnboardingNavigator` to use `cardUserPhase`, fetch user on
mount, remove `Complete`, and rework initial routing.
> - Update navigation to reset stacks after phone/mailing/physical
address steps.
> - Make `ValidatingKYC` start/stop polling via
`useUserRegistrationStatus` (manual start, auto-stop on terminal
states).
> - **Card Home**:
> - Gate “Enable card” by KYC; show status/error alerts; integrate new
`useGetUserKYCStatus` hook.
> - **Authentication/UI**:
> - Refactor `CardAuthentication` to `KeyboardAwareScrollView` and
Tailwind styles; minor styles cleanup.
> - `CardWelcome` switches to `selectHasCardholderAccounts` for copies
and routing.
> - **SDK/Provider**:
> - Add `CardSDK.getUserDetails` and expose `fetchUserData` in provider;
reset onboarding on invalid ID.
> - **Hooks**:
> - New `useGetUserKYCStatus`; updates across hooks to use SDK context
shape; caching fetchOnMount=false with manual triggers in multiple
hooks.
> - **Validation**:
> - Fix `validateDateOfBirth` to accept negative timestamps (pre‑1970).
> - **Localization**:
>   - Add strings for verifying registration and KYC status alerts.
> - **Routes/Selectors**:
> - Add `Routes.CARD.VERIFYING_REGISTRATION`; new selector
`selectHasCardholderAccounts`; deprecate `useIsCardholder`.
> - **Tests**:
> - Extensive updates/additions covering new screens, KYC gating,
navigator logic, hooks, SDK, and DOB validation.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
73e431e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

This PR implements volume histogram and fullscreen chart mode for Perps
trading, addressing the lack of volume data visualization and limited
screen real estate for chart analysis on mobile.

### What is the reason for the change?

The current Perps chart lacks essential trading features:
- No volume data visualization (critical for confirming price movements)
- No fullscreen/landscape mode for detailed chart analysis
- Limited screen space forces traders to use external platforms
(TradingView, CEX apps)

### What is the improvement/solution?

**Volume Histogram**
- USD notional volume bars (volume × price) displayed below candlesticks
- Smart formatting with K/M/B/T suffixes (e.g., "120M" vs "120,000,000")
- Color-coded bars (green/red) matching candle direction
- Clean presentation with hidden Y-axis labels and transparent separator

**Fullscreen Chart Modal**
- Immersive chart experience with minimized UI chrome
- Auto-unlock device orientation (follows rotation in fullscreen, locks
to portrait when closed)
- Cross-platform safe area handling (iOS notch + Android navigation bar)
- OHLCV data bar shows Open/High/Low/Close/Volume values

**Key Changes**
- Added `PerpsChartFullscreenModal` component with orientation
management
- Added `PerpsOHLCVBar` component for real-time OHLC/volume display
- Enhanced `TradingViewChartTemplate` with multi-pane architecture (80%
candlesticks / 20% volume)
- Added `expo-screen-orientation` dependency for native orientation
control
- Updated Android/iOS config to support landscape orientation in
fullscreen only

## **Changelog**

CHANGELOG entry: Added fullscreen chart mode with landscape orientation
support and volume histogram for Perps trading

## **Related issues**

Relates to: Mobile Perps charting UX v2 PRD - Chart Foundations (P0)

## **Manual testing steps**

```gherkin
Feature: Fullscreen chart with volume histogram

  Scenario: User views volume bars in market detail view
    Given user is on Perps market detail screen
    When user scrolls to chart section
    Then volume histogram bars are visible below candlesticks
    And volume values are formatted with K/M/B suffixes
    And volume bars use green/red colors matching candle direction

  Scenario: User enters fullscreen chart mode
    Given user is on Perps market detail screen
    When user taps fullscreen icon in chart header
    Then chart expands to fullscreen modal
    And header shows interval selector and close button
    And volume bars are always visible
    And device orientation unlocks to follow device rotation

  Scenario: User rotates device in fullscreen
    Given user is in fullscreen chart mode (portrait)
    When user rotates device to landscape
    Then chart automatically follows orientation change
    And volume bars properly rescale to new dimensions

    When user rotates device back to portrait
    Then chart returns to portrait orientation
    And volume bars rescale appropriately

  Scenario: User exits fullscreen mode
    Given user is in fullscreen chart mode (any orientation)
    When user taps Close button (X icon)
    Then chart exits fullscreen
    And device orientation locks back to portrait
    And user returns to market detail view

  Scenario: Cross-platform safe area handling
    Given user is on iOS device with notch
    When user enters fullscreen chart mode
    Then header content avoids notch area
    And chart content avoids bottom safe area
```

## **Screenshots/Recordings**

### **Before**

- No volume data visible on chart
- No fullscreen/landscape mode
- Limited chart analysis capability on mobile

### **After**

**Volume Histogram in Market Detail View:**
- Volume bars visible below candlesticks with USD notional values
- Smart formatting: "120M" instead of "120,000,000"
- Color-coded green (up) / red (down)

**Fullscreen Modal - Portrait:**
- Clean fullscreen interface with minimal chrome
- Header: Interval selector (left), Close button (right)
- Volume bars always visible
- OHLCV data bar with proper padding
- Safe area handling for iOS notch and Android status bar

**Fullscreen Modal - Landscape:**
- Maximum screen real estate for chart analysis
- Volume bars automatically rescale after rotation
- Orientation locks back to portrait when exiting


https://github.com/user-attachments/assets/f9582cfa-fa5c-449b-a5de-d9750e0da05d


## **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]
> Adds a fullscreen Perps chart with device rotation handling,
introduces volume histogram and an OHLCV bar, upgrades the chart engine,
and wires in expo-screen-orientation with config and tests.
> 
> - **Perps UI**:
> - Add `PerpsChartFullscreenModal` with orientation lock/unlock, header
controls, safe area handling, and tests.
> - Add `PerpsOHLCVBar` and render it in `PerpsMarketDetailsView` and
fullscreen modal.
> - Update `PerpsMarketHeader` to include a fullscreen button; minor
styles; make interval selector horizontally scrollable.
> - Enhance `PerpsMarketDetailsView`: integrate new components, skeleton
fallback, auto-zoom on interval change, improved error logging.
> - **Chart Engine**:
> - Extend `TradingViewChart` and template: volume histogram in separate
pane, OHLCV callbacks, overlay/volume toggles, pane sizing/resizing,
improved time/price formatting, and ref methods; expose `OhlcData`
types.
> - Adjust TPSL line styling/colors and add skeleton/error handling;
comprehensive unit tests added.
> - **Config/Dependencies**:
> - Add `expo-screen-orientation` (plugin, mock, Jest mapping); enable
landscape orientations in `ios/MetaMask/Info.plist`; register in
`app.config.js`; update Pods/Yarn.
> - **Logging/Services**:
> - Replace `console.error` with `Logger.error` in Perps flows; add
error logging in `HyperLiquidSubscriptionService` unsubscriptions.
> - **Selectors/i18n**:
> - Add E2E selectors for OHLCV bar and fullscreen modal; add i18n
strings for OHLC labels.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
5032204. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Nicholas Smith <nick.smith@consensys.net>
…ponents (#23109)

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

## **Description**

**What is the reason for the change?**

The "Token List Item Clicked" Segment event currently sends the same
`source` property value (`mobile-token-list`) regardless of whether
users click a token from the wallet home page or from the dedicated full
token list page. This makes it impossible to differentiate user behavior
between these two contexts in analytics.

**What is the improvement/solution?**

This PR adds differentiation to the token click tracking by introducing
a new `source` value:
- `mobile-token-list` - sent when tokens are clicked from the wallet
home page (existing behavior, maintains backward compatibility)
- `mobile-token-list-page` - sent when tokens are clicked from the full
token list page (accessed via "View all tokens")

The implementation adds an `isFullView` prop that flows through the
component hierarchy (`TokensFullView` → `Tokens` → `TokenList` →
`TokenListItem/TokenListItemBip44`) and conditionally sets the source
property in the Segment tracking event.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:
[TMCU-207](https://consensyssoftware.atlassian.net/browse/TMCU-207)

## **Manual testing steps**

```gherkin
Feature: Token List Item Click Tracking Differentiation

  Scenario: user clicks token from wallet home page
    Given the user is on the wallet home page
    And tokens are visible in the token list
    When user taps on any token in the list
    Then a "Token List Item Clicked" event is sent to Segment
    And the event contains property source="mobile-token-list"
    And the user navigates to the token details page

  Scenario: user clicks token from full token list page
    Given the user is on the wallet home page
    And tokens are visible in the token list
    When user taps "View all tokens" button
    And user is navigated to the full token list page
    And user taps on any token in the list
    Then a "Token List Item Clicked" event is sent to Segment
    And the event contains property source="mobile-token-list-page"
    And the user navigates to the token details page
```

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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


[TMCU-207]:
https://consensyssoftware.atlassian.net/browse/TMCU-207?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds an isFullView prop plumbed through TokenList ->
TokenListItem/TokenListItemBip44 to set analytics source to
'mobile-token-list-page' vs 'mobile-token-list', with minor full-view
layout padding.
> 
> - **Analytics/Tracking**:
> - `TOKEN_DETAILS_OPENED` event now sets `source` based on `isFullView`
in `TokenListItem` and `TokenListItemBip44` (`mobile-token-list-page` vs
`mobile-token-list`).
> - **UI/Props flow**:
> - Introduces optional `isFullView` prop on `TokenList`,
`TokenListItem`, and `TokenListItemBip44` and passes it through both
FlashList rendering and homepage list mapping.
> - Applies horizontal padding (`contentContainerStyle`) to `FlashList`
when `isFullView` is true.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
a75e04b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
This is a follow-up to address feedback from
#23060.

### Changes
- Bumped @metamask/transaction-controller to version ^62.2.0
- Replaced `MUSD_CONVERSION_TRANSACTION_TYPE` with
`TransactionType.musdConversion` from transaction-controller
- Added `skipInitialGasEstimate: true` when creating mUSD conversion
transaction to improve performance. Gas estimate is now calculate
asynchronously
- Fixed case where user could be redirected to previous page prematurely
when calling `initiateConversion` from `useMusdConversion` hook.
- Removed transition header from mUSD conversion confirmation screen. We
no longer see the default blue back arrow and screen title while
navigating to the confirmation screen.
<!--
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: follow up musd conversion optimizations based on #23060
feedback
## **Related issues**

## **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]
> Switch to TransactionType.musdConversion with async gas estimation, UX
tweaks, and controller bump to ^62.2.0.
> 
> - **mUSD conversion flow (Earn)**:
> - Use `TransactionType.musdConversion` across hooks, components, and
tests (replacing custom `MUSD_CONVERSION_TRANSACTION_TYPE`).
> - Create transactions with `skipInitialGasEstimate: true` for faster
first paint; add nested transactions; improve error handling to avoid
stuck screens.
> - Hide header on `REDESIGNED_CONFIRMATIONS` route for a cleaner
transition.
> - Update confirmation UI to recognize new type: `info-root`, `footer`,
`custom-amount-info`, `bridge-fee-row`, and `musd-conversion-info`
label/tooltip logic.
> - **Controller/engine**:
> - Bump `@metamask/transaction-controller` to `^62.2.0` and update Yarn
lock; minor init adjustments (registry access, typings).
> - **Tests**:
> - Update unit tests to reflect new transaction type and async gas
estimation behavior.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
865d6a4. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

16 similar comments
@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

This PR updates the change log for 7.61.0. (Hotfix - no test plan
generated.)

---------

Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
@joaoloureirop
Copy link
Copy Markdown
Contributor

@SocketSecurity ignore-all

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokeCore, SmokeWalletUX, SmokeRamps, SmokeAssets, SmokeTrade, SmokeAccounts, SmokeWalletPlatform
  • Risk Level: high
  • AI Confidence: 85%
click to see 🤖 AI reasoning details

This is a release PR for version 7.61.0 that consolidates numerous changes across the codebase. Here's my analysis:

Key Changes Identified:

  1. Analytics Refactor (Ramps): Replaced BUY_BUTTON_CLICKED with RAMPS_BUTTON_CLICKED across multiple components (AssetOverview, FundActionMenu, BalanceEmptyState, Card/AddFundsBottomSheet) with enhanced tracking properties (ramp_type, ramp_routing, is_authenticated, preferred_provider, order_count)

  2. UI Component Updates:

    • AssetOverview: Analytics changes for buy button
    • Tron resources display (TronEnergyBandwidthDetail): Refactored to use custom hook, improved UI with max values display
    • Toast component: Added ButtonIcon variant support
    • SelectorButton: Icon library migration and styling updates
    • Navigation: Added Pna25BottomSheet route
  3. Legal Notices: New PNA25 acknowledgement system added

  4. Account Management: Analytics event renamed from CONNECT_HARDWARE_WALLET to ADD_HARDWARE_WALLET

  5. CI/CD: Minor cleanup (whitespace, removed NODE_OPTIONS for iOS bundle)

  6. Version: Build version code bumped from 3092 to 3294

Risk Assessment:

  • HIGH risk due to being a release PR with widespread changes
  • Changes touch critical user flows: buying/ramps, asset display, wallet navigation
  • Analytics changes across multiple entry points could affect tracking
  • UI component changes (especially core components like Toast, SelectorButton) have wide usage
  • The CHANGELOG shows extensive features added in this release (100+ PRs worth of changes)

Test Coverage Rationale:

  • SmokeCore: Navigation changes (Pna25BottomSheet), core wallet flows affected
  • SmokeWalletUX: UI component changes (Toast, SelectorButton), settings, notifications
  • SmokeRamps: Analytics refactor for all ramps flows (buy, sell, deposit), critical path
  • SmokeAssets: Asset overview changes, Tron resource display updates
  • SmokeTrade: Bridge components touched (though no actual diff shown, file is in list)
  • SmokeAccounts: Account actions analytics change, multichain account components
  • SmokeWalletPlatform: Core wallet functionality with navigation and account management

The extensive nature of this release PR, combined with changes to analytics tracking, UI components, and critical user flows warrants comprehensive testing. While individual changes may seem minor, the aggregate risk of a release consolidating many features requires thorough validation.

View GitHub Actions results

@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

6 similar comments
@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

@metamaskbot
Copy link
Copy Markdown
Collaborator Author

More than one release label on PR. Keeping the lowest one (release-7.60.2) on PR and removing other release labels (release-7.61.0).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.