release: 7.61.0#23381
Conversation
<!--
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] -->  ### **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 -->
|
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
|
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). |
|
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). |
|
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). |
|
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). |
|
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). |
|
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). |
|
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). |
|
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). |
|
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). |
|
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). |
|
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). |
|
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). |
|
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). |
|
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). |
|
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). |
|
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>
|
@SocketSecurity ignore-all |
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsThis is a release PR for version 7.61.0 that consolidates numerous changes across the codebase. Here's my analysis: Key Changes Identified:
Risk Assessment:
Test Coverage Rationale:
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. |
|
|
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
|
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). |
|
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). |
|
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). |
|
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). |
|
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). |
|
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). |




🚀 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
Conduct regression and exploratory testing for your functional areas, including automated and manual tests for critical workflows.
Focus on exploratory testing across the wallet, prioritize high-impact areas, and triage any Sentry errors found during testing.
Validate new functionalities and provide feedback to support release monitoring.
GitHub Signoff
Issue Resolution
Cherry-Picking Criteria
🗓️ Timeline and Milestones
✅ Signoff Checklist
Each team is responsible for signing off via GitHub. Use the checkbox below to track signoff completion:
Team sign-off checklist
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