Skip to content

[pull] main from MetaMask:main#449

Merged
pull[bot] merged 383 commits into
Reality2byte:mainfrom
MetaMask:main
Jan 13, 2026
Merged

[pull] main from MetaMask:main#449
pull[bot] merged 383 commits into
Reality2byte:mainfrom
MetaMask:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Jan 13, 2026

See Commits and Changes for more details.


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

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

runway-github Bot and others added 30 commits November 28, 2025 14:56
…implification (#23417)

- fix(perps): segment violations and event simplification cp-7.60.0
(#23189)

## **Description**

This PR fixes **589 Segment tracking plan violations** in Perps
MetaMetrics events that are blocking analytics data quality in Mixpanel
dashboards.

**Problem:** Numeric properties were being sent as strings, optional
fields were sent as `null` instead of omitted, and some required fields
were missing. This caused:
- Analytics dashboards unable to perform numeric calculations
- 589 violation records across 5 events over 31 days
- Data quality issues in Mixpanel

**Solution:**
- `TrackingData` interface uses `number` types matching parsed values
from hooks
- Views pass numeric values directly without conversion wrappers
- `parseFloat()` applied only to direct event properties (e.g.,
`leverage`, API result prices)
- Optional fields use conditional spreads instead of `|| null` pattern
- Enum constants used throughout instead of string literals
- Documentation accurately reflects all implemented properties
- Minimal tracking approach for cleaner analytics

**Files Modified:** 7 files (6 source files + 1 documentation file)

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: 
- https://consensyssoftware.atlassian.net/browse/TAT-2082
- https://consensyssoftware.atlassian.net/browse/TAT-1835

## **Manual testing steps**

```gherkin
Feature: Perps MetaMetrics tracking

  Scenario: user completes a trade transaction
    Given user is on the Perps trading screen
    When user places a market order for BTC
    Then Segment event sends numeric properties as JavaScript numbers (not strings)
    And optional fields are omitted when undefined (not sent as null)

  Scenario: user views a screen
    Given user navigates to Perps connection error screen
    When screen loads
    Then PERPS_SCREEN_VIEWED event includes required screen_type property
    And error_type uses valid enum value
```

**Verification in Browser Console:**
1. Open DevTools � Network tab � Filter "segment"
2. Place trade / view screen / withdraw funds
3. Verify event payloads have:
   - `order_size`: `0.5` (number, not `"0.5"` string)
- Optional fields either present as numbers or completely omitted (not
`null`)
   - Required fields always present

## **Screenshots/Recordings**

### **Before**
- 589 Segment violations blocking analytics
- Properties sent as strings: `"0.5"`, `"50000.00"`
- Optional fields sent as `null`

### **After**
- 0 violations (589 � 0, 100% reduction)
- Properties sent as numbers: `0.5`, `50000.00`
- Optional fields properly omitted

## **Pre-merge author checklist**

- [x] I've followed MetaMask Contributor Docs and MetaMask Mobile Coding
Standards
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable (updated only broken tests per
plan)
- [x] I've documented my code using JSDoc format if applicable
- [x] I've applied the right labels on the PR

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

---

## **Technical Details**

### Changes Summary

**Service Layer (403 violations):**
- **TradingService.ts**: `trackOrderResult()` and
`buildCloseEventProperties()` use `parseFloat()` for direct event
properties (372 violations)
- **AccountService.ts**: `withdraw()` method uses `parseFloat()` for
withdrawal_amount (31 violations)

**View Layer (155 violations):**
- **PerpsConnectionErrorView.tsx**: Includes `screen_type: 'error'` enum
value (93 violations)
- **PerpsMarketDetailsView.tsx**: Watchlist toggle uses enum constants
(31 violations)
- **PerpsOrderView.tsx**: `parseFloat()` applied to `leverage_used`
event property (31 violations)

**Constants & Types (31 violations):**
- **eventNames.ts**: Enum constants for all event values
(FAVORITE_TOGGLED, FAVORITE_MARKET, UNFAVORITE_MARKET, FAVORITES_COUNT,
ERROR)
- **types/index.ts**: **ROOT CAUSE FIX** - `TrackingData` interface uses
`number` types matching hook return values (hooks parse API strings)

**Documentation:**
- **perps-metametrics-reference.md**: Accurately documents all
implemented properties (100% alignment with code)

### Implementation Patterns
1. **Direct Number Usage**: TrackingData interface uses `number` types;
hooks parse API strings once, views pass values directly
2. **Selective parseFloat()**: Applied only to direct event properties
outside TrackingData (e.g., leverage, API result prices)
3. **Optional Field Handling**: Conditional spreads `...(value && {
prop: value })` ensure undefined fields are omitted (not sent as null)
4. **Enum Constants**: All event values use constants (e.g.,
`PerpsEventValues.INTERACTION_TYPE.TAP`) instead of string literals
5. **Type Safety**: TrackingData types match hook return types, ensuring
compile-time validation of numeric properties
6. **Minimal Tracking**: Only implemented properties included in events
for cleaner analytics

### Type Safety
- `TrackingData` interface types match hook return values (`number` for
all numeric properties)
- Single conversion point: API strings → numbers in hooks, then used
directly
- All TypeScript validations pass without suppressions

### Validation
- ✅ ESLint: All files pass
- ✅ TypeScript: No errors, zero suppressions
- ✅ Documentation: 100% accurate with implementation

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Standardizes Perps MetaMetrics tracking: numeric properties,
enum-based values, conditional optional fields, and updated docs;
applies across UI views and controller (trades/close/cancel/withdraw).
> 
> - **Analytics normalization**:
> - Convert numeric properties (e.g., `leverage_used`, `order_size`,
`withdrawal_amount`) to numbers; use conditional spreads to omit
undefined optionals.
> - Replace string literals with enums for `interaction_type`,
`action_type`, and add `FAVORITE_TOGGLED`, `FAVORITE_MARKET`,
`UNFAVORITE_MARKET`.
> - Add/update properties: `favorites_count`, `screen_type: 'error'`,
and include `error_message` where applicable.
> - **Views**:
> - `PerpsMarketDetailsView.tsx`: Track favorites using enum values;
include `favorites_count`.
> - `PerpsOrderView.tsx`: Ensure `leverage_used` tracked as number; pass
numeric tracking data for fees/prices; cleanup deps.
> - `PerpsConnectionErrorView.tsx`: Track `PERPS_SCREEN_VIEWED` with
`screen_type: error`; retry button logs `tap` with `action` and
`attempt_number`.
> - **Controller (`PerpsController.ts`)**:
> - Trade/close/cancel/withdraw events: parse floats for `leverage`,
`order_size`, `limit_price`, `asset_price`; include optional fee/price
fields only when defined; add partial-fill fields and error messages;
parse `withdrawal_amount`.
> - **Constants/Types**:
> - `eventNames.ts`: Add/align values and keys (e.g.,
`FAVORITE_TOGGLED`, `FAVORITES_COUNT`, `ERROR`).
> - `types/index.ts`: Clarify `TrackingData` numeric fields (parsed by
hooks).
> - **Docs**:
> - Update MetaMetrics reference to match implemented properties and
required fields.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3b666af. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[de4bc54](de4bc54)

Co-authored-by: abretonc7s <107169956+abretonc7s@users.noreply.github.com>
- feat: convert onboarding page to tsx (#22912)

<!--
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**
* Convert onboarding component code from javascript to typescript.
* Jira: https://consensyssoftware.atlassian.net/browse/SL-315
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

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

### **After**



https://github.com/user-attachments/assets/7652f646-cd17-4e6b-a5b3-abf8f256437a




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

## **Pre-merge author checklist**

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

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

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

## **Pre-merge reviewer checklist**

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


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Converts the `Onboarding` screen to a typed TSX functional component
with hooks, updates metrics/navigation/OAuth handling, and extracts
styles to a separate typed module.
> 
> - **Onboarding screen**:
> - Migrates `app/components/Views/Onboarding/index.js` to TypeScript
functional component `index.tsx` using React hooks and React Navigation
hooks.
> - Replaces Redux `connect`/PropTypes with `useSelector`/`useDispatch`
and removes HOC `withMetricsAwareness` in favor of `useMetrics`.
> - Types key pieces (e.g., `OnboardingState`, `OAuthLoginResult`,
`TraceContext`, `AuthConnection`) and adds stricter navigation/route
typings.
> - Refactors network check to `netInfoFetch`, and updates
OAuth/social-login, tracing, metrics, and error handling to hook-based
callbacks/refs while maintaining existing flows.
> - **Styles**:
> - Extracts `createStyles` into
`app/components/Views/Onboarding/styles.ts` with typed
`Theme['colors']`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
c6bc88d. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Aslau Mario-Daniel <marioaslau@gmail.com>
Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
[8e712ab](8e712ab)

Co-authored-by: Gaurav Goel <grvgoel19@gmail.com>
Co-authored-by: Aslau Mario-Daniel <marioaslau@gmail.com>
Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
…essary pull_request trigger (#23438)

- chore(release pr validation): remove unnecessary pull_request trigger
(#23436)

It adds friction to the release cherry-pick merge process without adding
any benefit

<!--
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: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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

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

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Removes the pull_request trigger so the Release PR Approval workflow
runs only on submitted pull request reviews.
> 
> - **CI/GitHub Actions**:
> - Update `/.github/workflows/release-pr-approval.yml` to trigger only
on `pull_request_review: submitted`.
> - Remove the `pull_request` trigger; no changes to job logic or steps.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
913b63a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
…to spawn worker (#23443)

- chore(metro bundler): allow metro bundler to spawn worker (#23437)

Improving js bundle size check workflow by allowing Metro bundle process
to spawn an additional worker even on a low resource machine

Lowers JS heap memory limit, in an attempt to stabilize some resource
intensive workflows, such as android apk build for E2E

<!--
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: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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

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

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Guarantees Metro spawns at least two workers and removes the custom
NODE_OPTIONS from the iOS bundle generation step in CI.
> 
> - **Build/Metro**:
> - Ensure `maxWorkers` is at least `2` by wrapping the computed value
with `Math.max(2, ...)` in `metro.config.js`.
> - **CI**:
> - Remove `NODE_OPTIONS` env override from `js-bundle-size-check` job's
`Generate iOS bundle` step in `.github/workflows/ci.yml`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d379bf4. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
…d Energy in along with the current values (#23410)

- feat: cp-7.61.0 display total Bandwidth and Energy in along with the
current values (#23203)

## **Description**

Adds the maximum resources available along the existing current values
for Tron resources: Energy + Bandwidth

## **Changelog**

CHANGELOG entry: Added maximum Energy and maximum Bandwidth in TRX asset
details

## **Related issues**

Fixes:

https://consensyssoftware.atlassian.net/browse/NWNT-748?atlOrigin=eyJpIjoiZjlkMWQ3OTQ5MzY1NDlkYWJmNjdkZGEzYzZkNTRhNWUiLCJwIjoiaiJ9

## **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="1320" height="2868" alt="image"

src="https://github.com/user-attachments/assets/4b538e5d-e710-4989-85da-faa7b33a5845"
/>

### **After**

<img width="413" height="193" alt="Screenshot 2025-11-25 at 12 06 17"

src="https://github.com/user-attachments/assets/fd32bfd2-f203-4508-bbfb-af728a90341b"
/>

## **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]
> Displays current and total Tron Energy/Bandwidth with accurate
progress, refactors logic into a reusable hook, adds tests, and updates
pluralized copy.
> 
> - **Asset Overview (Tron)**:
> - Refactor `TronEnergyBandwidthDetail` to use `useTronResources` for
resource aggregation and progress (`percentage/100`).
> - UI now shows `current/max` values for `energy` and `bandwidth` with
muted max text.
>   - Uses singular/plural i18n for transfer coverage lines.
> - **Hook**:
> - Add `useTronResources` to parse Tron resources, derive max from base
caps, compute capped percentages; includes parsing of commas/invalid
values.
> - **Tests**:
>   - New tests for `useTronResources` (parsing, capping, edge cases).
> - Update `TronEnergyBandwidthDetail` tests to assert new progress,
values, and pluralized strings.
> - **Localization**:
> - Update `en.json` keys to
`asset_overview.tron.sufficient_to_cover_*_transfer(s)` and adjust copy
to “Covers … transfers/transfer.”
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
6f1c5a9. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Antonio Regadas <antonio.regadas@consensys.net>
[18185db](18185db)

Co-authored-by: Ulisses Ferreira <ulisses@hey.com>
Co-authored-by: Antonio Regadas <antonio.regadas@consensys.net>
Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
#23404)

- feat(perps): A/B test consistency cp-7.61.0 (#23392)

## **Description**

This PR fixes an inconsistency in the button color A/B test (TAT-1937)
between the asset screen and trade screen.

**Problem:** When the "monochrome" variant is active, the asset screen
(`PerpsMarketDetailsView`) correctly shows white/neutral Long/Short
buttons, but the trade screen (`PerpsOrderView`) still showed green/red
semantic buttons.

**Solution:** Added the `usePerpsABTest` hook to `PerpsOrderView` with
conditional button rendering that matches the pattern already
implemented in `PerpsMarketDetailsView`. When the variant is
"monochrome", the button uses `ButtonVariants.Secondary` (white on dark
mode, dark on light mode) instead of the semantic Success/Danger colors.

**Bonus (Dev only):** Added faster feature flag polling interval (1
second) in development mode to make A/B test iteration faster.
Production still uses the default fetch interval.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

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

## **Manual testing steps**

```gherkin
Feature: A/B test button color consistency

  Scenario: Monochrome variant shows white buttons on both screens
    Given the A/B test is enabled with "monochrome" variant
    And I am on the asset screen (PerpsMarketDetailsView)

    When I view the Long/Short buttons
    Then they should be white/neutral colored (Secondary variant)

    When I tap the Long or Short button
    Then I navigate to the trade screen (PerpsOrderView)
    And the place order button should also be white/neutral colored

  Scenario: Control variant shows semantic colored buttons on both screens
    Given the A/B test is enabled with "control" variant
    And I am on the asset screen (PerpsMarketDetailsView)

    When I view the Long/Short buttons
    Then the Long button should be green and Short button should be red

    When I tap the Long button
    Then I navigate to the trade screen (PerpsOrderView)
    And the place order button should be green (Success)

    When I tap the Short button from asset screen
    Then the place order button should be red (Danger)
```

## **Screenshots/Recordings**

### **Before**

Asset screen (monochrome): White buttons �
Trade screen (monochrome): Green/red buttons � (inconsistent)
<img width="401" height="848" alt="image"

src="https://github.com/user-attachments/assets/384bd1ed-c5ab-4306-b8a3-06c569f55cb9"
/>
<img width="403" height="824" alt="image"

src="https://github.com/user-attachments/assets/db936535-c8ba-4b09-86be-2350644d8a60"
/>
<img width="901" height="481" alt="image"

src="https://github.com/user-attachments/assets/56648625-69bf-41a4-9e42-cd9b72d63417"
/>

### **After**

Asset screen (monochrome): White buttons �
Trade screen (monochrome): White button � (consistent)
<img width="558" height="230" alt="image"

src="https://github.com/user-attachments/assets/4f5d27b1-4b35-41b0-bcc4-bb99f268c72a"
/>
<img width="398" height="840" alt="image"

src="https://github.com/user-attachments/assets/17341145-d11c-4e9b-9564-c6f06bdbba3c"
/>
<img width="401" height="834" alt="image"

src="https://github.com/user-attachments/assets/d7762779-abce-4954-9cea-2c05695dec3b"
/>

## **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]
> Applies the A/B test variant to `PerpsOrderView` place-order button
and reduces remote feature flag fetch interval to 1s in development.
> 
> - **Perps UI**:
> - A/B test integration in
`app/components/UI/Perps/Views/PerpsOrderView/PerpsOrderView.tsx` using
`usePerpsABTest` with `BUTTON_COLOR_TEST` and
`selectPerpsButtonColorTestVariant`.
>   - Conditional place-order button:
> - `monochrome` → `Button` with `ButtonVariants.Secondary`,
`ButtonSize.Lg`, `ButtonWidthTypes.Full`.
> - otherwise → `ButtonSemantic` with `Success`/`Danger` severity based
on direction.
> - **Feature Flags**:
> - In
`app/core/Engine/controllers/remote-feature-flag-controller-init.ts`,
set `fetchInterval` to `1000` ms in `__DEV__`, otherwise use default.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
e3d8dac. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[c5cb5fd](c5cb5fd)

Co-authored-by: abretonc7s <107169956+abretonc7s@users.noreply.github.com>
Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
…cation analytics events (#23430)

- fix: cp-7.61.0 resolve missing push notification analytics events
(#23423)

## **Description**

Push Notification Click analytics are missing because the new Generic
Platform Notifications does not hold any data or metadata. This is a
pre-emptive fix so that:
1. We always emit a push notification click event (we can capture events
that are missing data)
2. Pre-emptively add support for the data and metadata fields for when
our backend adds these to push notifications and in-app notifications.

## **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: resolve missing push notification analytics events

## **Related issues**

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

## **Manual testing steps**

1. Receive a push notification for perps.
2. Click on push notification
3. Inpsect segment and mixpanel to see if these events are coming
through.

## **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]
> Always emits PUSH_NOTIFICATION_CLICKED events and parses both on-chain
`data` and platform `metadata` payloads, while preserving deeplink
handling.
> 
> - **Notifications Analytics**:
> - Always track `PUSH_NOTIFICATION_CLICKED` via
`analyticsTrackPushClickEvent`, even when properties are missing.
> - Add parsing for on-chain notifications from `data`
(`OnChainRawNotification`) and generic platform notifications from
`metadata`; extract `notification_type` and include `rawData` and
`deeplink` in properties.
> - **FCM Service**:
> - `onClickPushNotificationWhenAppClosed` and
`onClickPushNotificationWhenAppSuspended` now invoke analytics tracking
consistently and return/callback with `deeplink` when present.
> - **Tests**:
> - Update tests to use `metadata`-based payloads; assert tracking
occurs with parsed `notification_type` and `data`.
> - Verify events are tracked even when notification is `null`, and
deeplink behavior remains correct on Android/iOS.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
362a03f. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[8f5bf8e](8f5bf8e)

Co-authored-by: Prithpal Sooriya <prithpal.sooriya@consensys.net>
Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
…p-7.61.0 (#23402)

- fix(perps): missing oracle price tooltip cp-7.61.0 (#23391)

## **Description**

Adds an info tooltip to the Oracle Price field in the market statistics
card. When tapped, it displays: "The median of external prices reported
by validators, used for computing funding rate."

## **Changelog**

CHANGELOG entry: null

## **Related issues**

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

## **Manual testing steps**

```gherkin
Feature: Oracle price tooltip

  Scenario: user views oracle price tooltip
    Given user is on the Perps market details screen

    When user taps the info icon next to "Oracle price"
    Then a bottom sheet appears with title "Oracle price" and content "The median of external prices reported by validators, used for computing funding rate."
```

## **Screenshots/Recordings**

### **Before**

Oracle price row has no info icon

### **After**

Oracle price row displays info icon; tapping shows tooltip



https://github.com/user-attachments/assets/4ad3394e-19bd-480d-86b7-5485113ca298


## **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 an info tooltip to the Oracle price row and wires it into the
bottom-sheet tooltip system with new i18n strings.
> 
> - **Perps Market Stats UI**:
> - Add info icon to `Oracle price` label in
`PerpsMarketStatisticsCard.tsx`; triggers
`onTooltipPress('oracle_price')` with test ID.
> - **Tooltip System**:
> - Extend `PerpsTooltipContentKey` with `oracle_price` in
`PerpsBottomSheetTooltip.types.ts`.
> - Register `oracle_price` in `contentRegistry.ts` (default
string-based content).
> - **Localization**:
> - Add `perps.tooltips.oracle_price` title and content to
`locales/languages/en.json`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f3cb363. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[227d6d9](227d6d9)

Co-authored-by: abretonc7s <107169956+abretonc7s@users.noreply.github.com>
Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
…ing accounts (#23421)

- fix: cp-7.61.0 balance updates when switching accounts (#23377)

## **Description**

This resolves balance update issues when switching accounts. This was
uncovered when users send funds (via send or swap flow) between
accounts. Examples of issues are in this notion testing doc.

The underlying issue:
1. WS only runs on the selected account, so any balance changes on other
accounts (e.g. sending funds to other accounts) are not captured.
2. WS also causes polling mechanisms to take up to 5 mins per cycle. So
users would need to wait 5 mins for the update.
3. We also don't have a "pull down to refresh" which could allow users
to manually update their balances.

NOTE - this is only impacting RC builds.



https://www.notion.so/metamask-consensys/Balance-Update-Slowness-lack-of-updates-2b7f86d67d688038a072ed99af7967e7

## **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`
5. 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: balance updates when switching accounts

## **Related issues**

Fixes:

## **Manual testing steps**

**Swap Flow**
1. Swap tokens (either multichain swap or single chain swap)
2. Make sure the receiver is a second account.
6. Wait for swap/bridge to complete
7. Go to home screen. Expected - source account balance and tokens
should update
8. Switch to the second account. Expected - destination account balance
and tokens should update

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

https://www.loom.com/share/08ca2be3e16c441d856c60d39135f476

## **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 selectedAccountGroupId to token balances polling to restart on
account switch and refactors tests to validate polling behavior.
> 
> - **Hook**
(`app/components/hooks/AssetPolling/useTokenBalancesPolling.ts`):
> - Add `selectedAccountGroupId` via
`useSelector(selectSelectedAccountGroupId)` to polling input.
>   - Support override input `{ chainIds, selectedAccountGroupId }`.
>   - Ensures polling restarts when the selected account group changes.
> - **Tests**
(`app/components/hooks/AssetPolling/useTokenBalancesPolling.test.ts`):
> - Refactor to use `initialRootState`, mock
`selectSelectedAccountGroupId`, and assert `selectedAccountGroupId` is
passed to `startPolling`.
> - Add helpers to arrange mocks and assert mount/unmount polling
behavior.
> - Add cases for chainIds override, no networks, and restarting when
account group changes.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
2646f3f. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[11b8f60](11b8f60)

Co-authored-by: Prithpal Sooriya <prithpal.sooriya@consensys.net>
Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
This PR updates the change log for 7.60.0.

---------

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

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

## **Description**

This PR cherry-picks
#22911

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

## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Upgrades `@metamask/network-controller` to v27 with related dependency
updates, applies a typing workaround for network state in
`transaction-controller-init`, and bumps Android/iOS build numbers to
3183.
> 
> - **Dependencies**:
>   - Upgrade `@metamask/network-controller` to `^27.0.0`.
> - Update related packages: `@metamask/controller-utils` `^11.16.0`,
`@metamask/eth-json-rpc-middleware` `^22.0.0`,
`@metamask/json-rpc-engine` `^10.2.0`.
>   - Refresh `yarn.lock` entries accordingly.
> - **Engine**:
> - `app/core/.../transaction-controller-init.ts`: add typing
workaround/comments for `getNetworkState` with new network status enum;
minor TS annotation adjustments.
> - **Build/CI**:
> - Bump Android `versionCode` to `3183` and iOS
`CURRENT_PROJECT_VERSION` to `3183`.
> - Update Bitrise env vars `VERSION_NUMBER`/`FLASK_VERSION_NUMBER` to
`3183`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
fb4cc38. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Elliot Winkler <elliot.winkler@gmail.com>
Co-authored-by: sethkfman <setk.kaufman@consensys.net>
Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
…1.0 (#23413)

- feat: rewards hold musd way to earn cp-7.61.0  (#23363)

## **Description**

This PR makes it so that, depending on the relevant featureflag, the
hold musd ways to earn tile/card will render on the rewards dashboard.
When clicking/pressing it a bottom sheet will open with information. In
that bottom sheet, if the cta is clicked/pressed, the user navigates to
the buy flow and the token to buy is preset to MUSD on Linea.

## **Changelog**

CHANGELOG entry: feat: rewards hold musd ways to earn

## **Screenshots/Recordings**

### **After**

<img width="628" height="736" alt="Screenshot-2025-11-27-13:59:41"

src="https://github.com/user-attachments/assets/81947968-5ad2-4b56-b7ba-1335eaebce3e"
/>

<img width="663" height="377" alt="Screenshot-2025-11-27-14:00:06"

src="https://github.com/user-attachments/assets/8d611243-ac4f-4539-9d8a-793c4c3eb318"
/>


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Introduces a feature-flagged “Hold mUSD” earning option that opens a
bottom sheet and routes to the Buy flow preselected to mUSD on Linea,
with supporting flags, i18n, and tests.
> 
> - **Rewards Overview (`WaysToEarn`)**:
>   - Add `WayToEarnType.HOLD_MUSD` with bottom sheet content and CTA.
> - CTA uses `useRampNavigation().goToBuy` with CAIP-19 `assetId` built
via `NETWORKS_CHAIN_ID.LINEA_MAINNET` → `getDecimalChainId` →
`toCaipAssetType`.
> - Gate visibility with
`useFeatureFlag(FeatureFlagNames.rewardsEnableMusdHolding)`; filter list
accordingly.
>   - Minor refactor: memoize mUSD `assetId`.
> - **Feature Flags**:
>   - Add `FeatureFlagNames.rewardsEnableMusdHolding`.
> - **Localization**:
>   - Add `rewards.ways_to_earn.hold_musd.*` strings.
> - **Tests** (`WaysToEarn.test.tsx`):
> - Expand unit tests and mocks for Ramp navigation, CAIP conversion,
chain ID conversion, and feature flags.
> - Verify modal content, CTA behavior (navigates to Buy with correct
`assetId`), and hook integrations.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
249db40. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[cb8426a](cb8426a)

Co-authored-by: VGR <VanGulckRik@gmail.com>
Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
… refresh (#23400)

- fix(perps): cp-7.61.0 invalid transactions refresh (#23393)

## **Description**

Fixes a bug where funding payments in the Activity/Transactions view
would alternate between showing different date ranges on each refresh
(e.g., Nov 5th � Oct 31st � Nov 5th).

**Root cause:** Multiple race conditions in the transaction history
fetching logic:

1. **Dependency array issue:** The `fetchAllTransactions` callback had
`userHistory` (an array) in its dependency array, causing callback
recreation on every fetch.

2. **Initial fetch race condition:** Both `useUserHistory` and
`usePerpsTransactionHistory` had their own `useEffect` hooks that
triggered fetches on mount. These ran in parallel, so
`fetchAllTransactions` would read an empty `userHistoryRef.current`
before user history completed.

3. **Epoch time fallback:** When `startTime` was undefined, it defaulted
to `0` (epoch time 1970), causing the HyperLiquid API to return the
oldest 500 records instead of the newest.

**Solution:**
1. Use a `useRef` to hold the latest `userHistory` value, removing it
from the callback's dependency array.
2. Remove the auto-fetch `useEffect` from `useUserHistory` - let the
parent hook control the fetch flow.
3. Use an `initialFetchDone` ref to ensure initial fetch runs once, and
use `refetch()` for the initial load. The `refetch()` function fetches
user history first, updates the ref, then fetches all transactions -
ensuring sequential data flow.
4. Replace the `startTime || 0` fallback with a configurable constant
(`DEFAULT_FUNDING_HISTORY_DAYS = 365`).
5. Fixed duplicate React key warning in `PerpsTransactionsSkeleton` by
adding section/item indices to keys.

## **Changelog**

CHANGELOG entry: Fixed funding payments alternating between different
date ranges on refresh in Activity view

## **Related issues**

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

## **Manual testing steps**

```gherkin
Feature: Funding payments display consistency

  Scenario: user refreshes Activity view multiple times
    Given user has funding payment history in their account
    And user navigates to the Activity/Transactions view
    And user selects the "Funding" tab

    When user refreshes the page multiple times (pull-to-refresh)
    Then the same funding payments should be displayed consistently
    And the latest funding payments should always be visible
    And the data should not alternate between different date ranges
```

## **Screenshots/Recordings**

### **Before**

Data alternates between Nov 5th and Oct 31st on each refresh due to race
conditions in the useCallback dependency array.

### **After**

Data remains consistent across refreshes, always showing the latest
funding payments.



https://github.com/user-attachments/assets/cc252246-7518-497c-934f-2315648b27ee


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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Sequentialize perps transaction history fetching, default funding
history to recent days, and fix skeleton keys to prevent render
warnings.
> 
> - **Perps hooks**:
> - `usePerpsTransactionHistory`: Remove `userHistory` from deps via
ref, add one-time init guard, and use `refetch()` to fetch `userHistory`
first then all data; pass `startTime` as given (no `0` fallback);
combine loading/error states.
> - `useUserHistory`: Drop auto-fetch; `refetch()` now performs fetch
and returns results; initial loading is false.
> - **Provider**:
> - `HyperLiquidProvider.getFunding`: Use `DEFAULT_FUNDING_HISTORY_DAYS`
to compute a recent `startTime` when undefined; import new constants.
> - **Constants**:
> - Add `PERPS_TRANSACTIONS_HISTORY_CONSTANTS` with
`DEFAULT_FUNDING_HISTORY_DAYS`.
> - **UI**:
> - `PerpsTransactionsSkeleton`: Add stable, unique keys using
`sectionIndex`/`itemIndex`.
> - **Tests**:
> - Update tests to reflect new fetch sequencing, loading states, and
funding params.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
92a9885. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: abretonc7s <107169956+abretonc7s@users.noreply.github.com>
Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
…in alert on iOS cp-7.61.0 (#23452)

- fix: remove do you want to download file.bin alert on iOS cp-7.61.0
(#23383)

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

## **Description**
Remove "do you want to download file.bin" alert on iOS 
PR for react-native-webview-mm:
MetaMask/react-native-webview-mm#74

## **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 we prompt do you want to download
file.bin alert

## **Related issues**

Fixes: #20359

## **Manual testing steps**

```gherkin
Feature: remove do you want to download file.bin alert 

  Scenario: user not seeing the alert
    Given user navigates to browser tab

    When user navigates to sites like https://adtech.org/metamask-iframe-example/
    Then user should not see an alert that says "do you want to download file.bin"
```

## **Screenshots/Recordings**

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

### **Before**
<img width="211" height="458" alt="Screenshot 2025-11-27 at 12 31 40 PM"

src="https://github.com/user-attachments/assets/0bfbd86f-1196-4320-b6f8-2dd499349437"
/>


### **After**
Not showing the alert
![iOS

after](https://github.com/user-attachments/assets/8b55ad4c-acf6-4de8-a303-215219d1b191)

Can still download files 


![downloads](https://github.com/user-attachments/assets/9c722df1-e6e6-4905-898c-e1775dce6915)

## **Pre-merge author checklist**

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

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

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

## **Pre-merge reviewer checklist**

- [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]
> Suppresses generic iOS data-URL .bin download alerts and consolidates
Android WebView permission prompts into a single confirmation with safer
granting.
> 
> - **iOS (`apple/RNCWebViewImpl.m`)**:
> - `downloadBase64File`: infer file extension early; ignore `.bin`
(application/octet-stream) data-URL downloads to avoid the "do you want
to download File.bin" alert; add log.
> - **Android (`RNCWebChromeClient.java`)**:
> - `onPermissionRequest`: reset state; aggregate already OS-granted
permissions, show a single confirmation dialog (with combined labels),
map selections to WebView resources, and either grant immediately or
request remaining system permissions.
> - `onRequestPermissionsResult` flow: wrap `grant` in try/catch and
ensure cleanup to avoid `IllegalStateException`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0e62d5a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[6352721](6352721)

Co-authored-by: Wei Sun <wei.sun@consensys.net>
- fix: cp-7.60.1 bump bitcoin (#23488)

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

## **Description**

Updates bitcoin to 1.8.0, which removes onRpcRequest method.

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

## **Changelog**

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

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

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

CHANGELOG entry: Removed `onRpcRequest`
([#568](MetaMask/snap-bitcoin-wallet#568))

## **Related issues**

Fixes: Remove `onRpcRequest`.

## **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]
> Update @metamask/bitcoin-wallet-snap from ^1.6.0 to ^1.8.0 and refresh
yarn.lock.
> 
> - **Dependencies**:
> - Bump `@metamask/bitcoin-wallet-snap` from `^1.6.0` to `^1.8.0` in
`package.json`.
>   - Update `yarn.lock` to reflect the new version.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
6118426. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[90ac48c](90ac48c)

Co-authored-by: Fred <frederic.heng@consensys.net>
This PR updates the change log for 7.60.0. (Hotfix - no test plan
generated.)

---------

Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
Co-authored-by: sethkfman <seth.kaufman@consensys.net>
…cent activity cp-7.61.0 (#23455)

- fix(perps): auto display latest info in recent activity cp-7.61.0
(#23394)

## **Description**

This PR fixes the issue where recent activity doesn't update after
executing a trade or closing a position in the Perps feature.

**Root Cause:** The recent activity section was fetching data via REST
API only on mount, not responding to real-time WebSocket updates from
trades.

**Solution:**
1. Updated `usePerpsHomeData` to use WebSocket fills directly via
`usePerpsLiveFills` for instant activity updates
2. Updated `usePerpsTransactionHistory` to merge WebSocket fills with
REST data for the TransactionsView
3. Removed duplicate WebSocket subscriptions in `PerpsWatchlistMarkets`
by passing positions/orders as props instead

## **Changelog**

CHANGELOG entry: Fixed Perps recent activity not updating after trades

## **Related issues**

Fixes: TAT-2036

## **Manual testing steps**

```gherkin
Feature: Perps Recent Activity Updates

  Scenario: User sees recent activity update after executing a trade
    Given user is on the Perps home screen with some USDC balance
    And user can see the Recent Activity section

    When user executes a market buy order for any asset (e.g., BTC)
    Then the trade appears immediately in the Recent Activity section
    And no page refresh or navigation is required

  Scenario: User sees recent activity update after closing a position
    Given user is on the Perps home screen with an open position
    And user can see the Recent Activity section

    When user closes the position
    Then the close trade appears immediately in the Recent Activity section
    And no page refresh or navigation is required

  Scenario: User sees recent activity in Transactions view
    Given user navigates to the Perps Transactions view
    And user has no recent trades

    When user executes a trade from the market details screen
    And user returns to the Transactions view
    Then the new trade appears at the top of the list
```

## **Screenshots/Recordings**

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

### **Before**

<!-- Recent activity did not update after trades without manual refresh
-->

### **After**

<!-- Recent activity updates instantly via WebSocket when trades execute
-->



https://github.com/user-attachments/assets/7f55f23f-ded3-451d-9d3c-4ae7b7d31aef


## **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]
> Switches recent activity/trades to WebSocket fills with REST
fallback/merge, adds snapshot handling, and removes duplicate WS
subscriptions; updates transforms and tests.
> 
> - **UI/Components**
> - `PerpsMarketTradesList`: replace `usePerpsOrderFills` with
`usePerpsLiveFills`; instant updates, sorted/limited; navigation uses
new transaction id format.
> - `PerpsHomeView`: pass `positions`/`orders` down to
`PerpsWatchlistMarkets`.
> - `PerpsWatchlistMarkets`: accept `positions`/`orders` props to avoid
duplicate subscriptions.
> - **Hooks/Data**
> - `usePerpsHomeData`: use `usePerpsLiveFills` (no throttle) + fetch
REST fills once; merge/dedup (orderId-timestamp), transform to
transactions; loading state reflects fills; keep markets via REST.
> - `usePerpsTransactionHistory`: subscribe to live fills and
merge/dedup with REST-derived transactions; preserve non-trade items;
improved error/loading handling.
> - **Streaming/Services**
> - `PerpsStreamManager` `FillStreamChannel`: handle snapshot vs
streaming; cache newest-first and cap to 100.
> - `HyperLiquidSubscriptionService`: pass `isSnapshot` through
`subscribeToOrderFills` callback; propagate to listeners.
> - Types: update `SubscribeOrderFillsParams.callback` signature to
`(fills, isSnapshot?)`.
> - **Transforms**
> - `transformFillsToTransactions`: support `Buy`/`Sell` directions; new
stable id format `orderId|fill-timestamp-index`; adjust titles/amount
signs.
> - **Tests**
> - Update unit tests across hooks/components/services to mock
`usePerpsLiveFills`, new id/key formats, and snapshot flag handling.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
96daa4f. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
Co-authored-by: João <castrofjoao@gmail.com>
Co-authored-by: Daniel <80175477+dan437@users.noreply.github.com>
Co-authored-by: Michal Szorad <michal.szorad@consensys.net>
[11ea6e9](11ea6e9)

Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
Co-authored-by: abretonc7s <107169956+abretonc7s@users.noreply.github.com>
Co-authored-by: João <castrofjoao@gmail.com>
Co-authored-by: Daniel <80175477+dan437@users.noreply.github.com>
Co-authored-by: Michal Szorad <michal.szorad@consensys.net>
…son cp-7.61.0 (#23412)

- fix: opt in for rewards when no active season cp-7.61.0  (#23395)

## **Description**

Due to the upcoming end of season 1, the onboarding flow doesn't make
sense any more when there's no active season. This PR changes that so
that users end up on a simplified onboarding.

## **Changelog**

CHANGELOG entry: fix opt in for no rewards active season

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/RWDS-855,
#23396

## **Screenshots/Recordings**

### **After**

<img width="676" height="1482" alt="image"

src="https://github.com/user-attachments/assets/827f2cec-1fa3-4e80-bd88-ffc6db27a493"
/>

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Introduces a simplified Rewards opt-in when no season is active, adds
a reusable legal disclaimer, and updates onboarding to query season
status and branch accordingly.
> 
> - **Rewards Onboarding**:
> - **Intro gating**: `OnboardingIntroStep` queries
`RewardsController:hasActiveSeason`; shows `Skeleton` while loading and
renders `OnboardingNoActiveSeasonStep` when inactive. Extracts
`canContinue` validation logic and refines geo error handling.
> - **New step**: `OnboardingNoActiveSeasonStep` enables direct opt-in
(no referral), handles loading/redirect, and displays legal disclaimer.
> - **Progress UI**: `OnboardingStep` adds optional
`showProgressIndicator` prop (used to hide bars for the new step).
> - **Legal disclaimer**: New reusable `RewardsLegalDisclaimer`
component; `OnboardingStep4` updated to use it.
> - **Tests**: Add comprehensive tests for the new step and update
`OnboardingIntroStep`/`OnboardingStep4` tests for season gating and
disclaimer.
> - **Localization**: Add `rewards.onboarding.no_active_season.*`
strings and minor copy tweaks.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
fb0ace1. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[43f351b](43f351b)

Co-authored-by: VGR <VanGulckRik@gmail.com>
Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
…metrics (#23485)

- feat: cp-7.61.0 add PNA25 messaging for updated metametrics (#23316)

## **Description**

This PR implements PNA25 (Privacy Notice Announcement) messaging to
inform existing users about MetaMetrics updates. The changes introduce a
new toast that alerts existing users who have opted into MetaMetrics
about the association of in-app activity with on-chain data.

**What is the reason for the change?**
As part of the PNA25 initiative, we need to notify existing users who
have opted into MetaMetrics about the updated data collection practices,
specifically that some in-app activity will be associated with on-chain
data to better understand usage patterns.

**What is the improvement/solution?**
- Added a new Redux action and state management for tracking PNA25
acknowledgement
- Created selectors to determine when the PNA25 toast should be
displayed based on user state and feature flags
- Implemented a toast notification on the Wallet screen that appears for
existing users with MetaMetrics enabled
- Updated onboarding flow to automatically acknowledge PNA25 for new
users
- Refactored legal notices actions from reducer to dedicated actions
file
- Updated MetaMetrics description strings to reflect the new data
collection approach
- Updated MetaMetrics support URL to the latest documentation

There are very specific testing instructions below as there are several
different cases for this.

## **Changelog**

CHANGELOG entry: Added PNA25 toast message to inform existing users
about MetaMetrics updates and on-chain data association

## **Related issues**

https://consensyssoftware.atlassian.net/browse/CEUX-728
https://consensyssoftware.atlassian.net/browse/CEUX-729
https://consensyssoftware.atlassian.net/browse/CEUX-727

## **Manual testing steps**

Test changes using the LaunchDarkly feature flag `extension-ux-pna25`

```
Update from previous versions (existing users)

Scenario: MetaMetrics opt in = true

Step 1: Download & install 7.60.0 or earlier
Step 2: Complete onboarding with MetaMetrics opt in = true
Step 3: Update to 7.61
Step 4: Open home screen

Expected Result
Toast appears

 

Scenario: MetaMetrics opt in = false

Step 1: Download & install 7.60.0 or earlier
Step 2: Complete onboarding with MetaMetrics opt in = false
Step 3: Update to  7.61
Step 4: Open home screen

Expected Result
No toast appears

 

Scenario: Feature flag disabled

Step 1: Download & install 7.60.0 or earlier
Step 2: Complete onboarding with MetaMetrics opt in = false
Step 3: Update to  7.61
Step 4: Feature flag is disabled (disable main-dev for flag extension-ux-pna25 (same on Mobile and Extension)
Step 5: Open home screen

Expected Result
No toast appears

 

New install (new users)

Scenario: MetaMetrics opt-in = true

Step 1: Download RC
Step 2: Complete onboarding with MetaMetrics opt in = true
Step 5: Open home screen

Expected Result
No toast appears

 

Scenario: MetaMetrics opt-in = false

Step 1: Download RC
Step 2: Complete onboarding with MetaMetrics opt in = false
Step 5: Open home screen

Expected Result
No toast appears
 

Scenario: Social login onboarding

Step 1: Download RC
Step 2: Complete onboarding with Social login
Step 5: Open home screen

Expected Result
No toast appears


MetaMetrics opt out / opt in

Scenario: Enable MetaMetrics post onboarding

Step 1: Download RC OR follow the steps for existing user
Step 2: Complete onboarding with MetaMetrics opt out
Step 3: Enable MetaMetrics in Settings

Expected Result
No toast appears
```

## **Screenshots/Recordings**

### **Before**


### **After**

During onboarding, the 'Gather basic usage data' copy is updated when
the feature flag is on:

<img width="397" height="868" alt="image"

src="https://github.com/user-attachments/assets/56f166fa-3b8b-4dc0-8e2b-74044ce7042e"
/>

When the toast should appear, it looks like this and should persist
until either the Learn more or Close button is pressed:

(NOTE: the close button is going to have UI tweaks in a later PR)

<img width="395" height="821" alt="image"

src="https://github.com/user-attachments/assets/1df6db8f-3fc8-466a-9529-159031c7fbd0"
/>

In security settings the Metametrics copy is updated (regardless of
feature flag on or off):

<img width="364" height="126" alt="image"

src="https://github.com/user-attachments/assets/ec9b116f-626c-4683-a1fb-9fc94689fa78"
/>



## **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]
> Introduce PNA25 (Privacy Notice) feature flag, state, and user toast,
refactor legal notices actions/selectors, and wire into onboarding,
metrics opt-in, settings, and analytics.
> 
> - **Privacy Notice (PNA25)**:
> - Add `MM_EXTENSION_UX_PNA25` flag (env + selector with override) and
Redux state `isPna25Acknowledged` with new actions
(`storePna25Acknowledged`).
> - Show persistent PNA25 toast in `Wallet` when enabled, with "Learn
more" link and close/acknowledge; track via new
`MetaMetricsEvents.TOAST_DISPLAYED`.
> - Auto-acknowledge PNA25 on onboarding for new users; acknowledge when
enabling MetaMetrics in Settings if needed.
> - Update Opt-in copy conditionally under flag and adjust Settings
MetaMetrics description.
> - **Refactor/Selectors**:
> - Move legal notices actions out of reducer; add selectors
`selectIsPna25FlagEnabled`, `selectIsPna25Acknowledged`,
`selectShouldShowPna25Toast` and keep
`shouldShowNewPrivacyToastSelector`.
> - **Constants/Strings**:
> - Update support URL (`HOWTO_MANAGE_METAMETRICS`), add new locale
strings for PNA25, and tweak existing copy.
> - **Analytics**:
>   - Add `TOAST_DISPLAYED` event.
> - **Tests/Snapshots**:
> - Add comprehensive unit tests and snapshot updates across actions,
reducers, selectors, OptinMetrics, Settings, Wallet, Sentry masking,
fixtures.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
876c65b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

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

Co-authored-by: Amélie <amelie.chan@gmail.com>
Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
# 🚀 v7.60.0 Testing & Release Quality Process

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

---

## 📋 Key Processes

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

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

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

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

---

## 🗓️ Timeline and Milestones

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

---

## ✅ Signoff Checklist

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

# Team sign-off checklist
- [x] Accounts Framework
- [x] Assets
- [x] Card
- [x] Confirmations
- [x] Core Platform
- [x] Design System
- [x] Earn
- [x] Mobile Platform
- [x] Mobile UX
- [x] Network Enablement
- [x] New Networks
- [x] Onboarding
- [x] Perps
- [x] Predict
- [x] Ramp
- [x] Rewards
- [x] Swaps and Bridge
- [x] Transactions
- [x] Wallet Integrations

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

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

Many thanks in advance

# Reference
- Testing plan sheet -
https://docs.google.com/spreadsheets/d/1tsoodlAlyvEUpkkcNcbZ4PM9HuC9cEM80RZeoVv5OCQ/edit?gid=404070372#gid=404070372

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds unified token selection and settings for Ramp, refactors Checkout
into a bottom sheet with new nav, enhances Predict sell/transactions UIs
and metrics, and improves error handling across flows.
> 
> - **Ramp**
> - **Checkout Refactor**: Migrates `Checkout` to a fullscreen bottom
sheet with updated navbar (`getDepositNavbarOptions`), improved error
handling/messages, and consolidated tests/snapshots.
> - **Settings**: Introduces `SettingsModal` (and
`createBuySettingsModalNavigationDetails`) with actions (order history,
new buy experience) and analytics; integrates from Build Quote screen.
> - **Navigation/Header Updates**: Replaces legacy navbar helper across
Deposit/Aggregator views; standardizes close button testIDs and header
titles in bottom sheets.
> - **Token Selection**: Adds `TokenSelection`, `TokenNetworkFilterBar`,
and `TokenListItem` with search/filter support; introduces mock crypto
constants; refactors network filtering to shared token network info.
> - **Configuration Modal**: Updates menu layout; adds “More ways to
buy” action; improved logout flow feedback.
> - **Eligibility & Basic Info**: Adds `EligibilityFailedModal`; handles
phone-already-registered (errorCode 2020) with logout path to email and
message formatting.
> - **Predict**
> - **Sell Preview**: Reworks UI (skeletons, localized copy),
recalculates PnL from preview, removes consent gating, and auto-pop on
success.
> - **Transactions View**: Switches to `SectionList` grouped by date
(Today/Yesterday/Date), enriches activity mapping, and adds performance
measurement traces.
>   - **Tab View**: Adds load performance measurement.
> - **Tests/Snapshots**
> - Broad snapshot updates and new unit tests to cover new modals, nav
changes, token selection, and updated analytics paths.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
e6e7053. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
This PR updates the change log for 7.60.1. (Hotfix - no test plan
generated.)

---------

Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
Co-authored-by: sethkfman <seth.kaufman@consensys.net>
…7.61.0 (#23496)

- chore: Asset Details page v2 followups cp-7.61.0 (#23339)

## **Description**

Some followups to Perps AssetDetails V2

**Add margin/Reduce margin**
2 decimal defaults ✅
Add max withdrawable/Margin available to add ✅
Reduce Margin is now Remove Margin ✅

**Increase exposure:**
Should default to current position leverage (this was already working)
✅
borders for leverage should be rounded ✅

Details View / and limit price bottomsheet hip3 market prefix removed
✅
Flip position > Reverse position, fix background ✅

## **Changelog**

CHANGELOG entry: Perps Asset Details cleanup

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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

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

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

## **Pre-merge reviewer checklist**

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



<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds 2-decimal margin inputs with available add/remove info, renames
Reduce to Remove, passes existingPosition when adding to a position, and
applies minor UI/i18n tweaks.
> 
> - **Perps Adjust Margin**:
> - Keep 2-decimal precision for slider, Max, and percentage inputs;
keypad set to `decimals=2`.
> - Show `margin_available_to_add` / `margin_available_to_remove` with
`maxAmount`.
>   - Safety clamp in remove mode respects `maxAmount`.
> - **Order Flow**:
> - When selecting “Increase exposure,” navigate to `PerpsOrder` with
`existingPosition` and `hideTPSL: true`.
>   - Type updates: `PerpsOrder` route accepts `existingPosition`.
> - **Components/Styles**:
> - `PerpsOrderView`: use `detailItemOnly` for single detail card; add
rounded border style.
> - `PerpsFlipPositionConfirmSheet`: set detail background to
`background.section`.
> - `PerpsLimitPriceBottomSheet`: show market as
`{getPerpsDisplaySymbol(asset)}-USD`.
> - **i18n**:
> - Rename labels from “Reduce Margin” to “Remove Margin”; flip action
strings to “Reverse Position/Reverse/Reversing…”.
> - Add `margin_available_to_add` and `margin_available_to_remove` keys.
> - **Tests**:
> - Update expectations for new labels, available margin row, 2-dec
displays, loading state button text, error handling when missing route
params, and remove-mode calculations.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
303b9c5. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[13b410e](13b410e)

Co-authored-by: Nick Gambino <35090461+gambinish@users.noreply.github.com>
runway-github Bot and others added 27 commits January 9, 2026 19:20
…ectly set to 1 instead of 0 cp-7.61.6 (#24376)

- fix(tron): max energy and bandwidth incorrectly set to 1 instead of 0
cp-7.61.6 (#24368)

<!--
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 Tron resources calculation and default value.

## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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

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

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

## **Pre-merge reviewer checklist**

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



<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Fix Tron resources calculation and defaults**
> 
> - In `useTronResources`, keep actual `max` values from data (can be
`0`) and compute `percentage` using `Math.max(1, max)` to avoid division
by zero
> - Remove prior clamping of `max` to at least `1` for energy/bandwidth
> - Update tests in `useTronResources.test.ts` to expect `max: 0` when
resources are absent and validate parsing/percentage behavior
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
df247ca. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Antonio Regadas <antonio.regadas@consensys.net>
[ae67bf2](ae67bf2)

Co-authored-by: Ulisses Ferreira <ulisses@hey.com>
Co-authored-by: Antonio Regadas <antonio.regadas@consensys.net>
…version 1.19.0 cp-7.61.6 (#24378)

- chore: bump @metamask/tron-wallet-snap to version 1.19.0 cp-7.61.6
(#24365)

<!--
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: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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

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

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

## **Pre-merge reviewer checklist**

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


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Upgrades dependency to latest patch version.
> 
> - Bumps `@metamask/tron-wallet-snap` from `^1.17.0` to `^1.19.0` in
`package.json`
> - Updates `yarn.lock` to resolve the new version
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
912fe97. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Alejandro Garcia Anglada <aganglada@gmail.com>
[72cd316](72cd316)

Co-authored-by: Ulisses Ferreira <ulisses@hey.com>
Co-authored-by: Alejandro Garcia Anglada <aganglada@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**

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

update changelog

## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

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

---

## 📋 Key Processes

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

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

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

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

---

## 🗓️ Timeline and Milestones

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

---

## ✅ Signoff Checklist

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

# Team sign-off checklist
- [ ] Mobile Platform

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

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

Many thanks in advance

# Reference
- Testing plan sheet -
https://docs.google.com/spreadsheets/d/1tsoodlAlyvEUpkkcNcbZ4PM9HuC9cEM80RZeoVv5OCQ/edit?gid=404070372#gid=404070372

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Perps (HyperLiquid) — HIP-3 overhaul and TP/SL fixes**
> 
> - Switches HIP-3 to individual `clearinghouseState` + `openOrders`
subscriptions with DEX discovery wait/sync; `webData3` now only for OI
caps (`HyperLiquidSubscriptionService.ts`)
> - Preserves/re-extracts TP/SL from cached orders; adds price-based
fallback for ambiguous `Trigger` types; includes `triggerPrice` and uses
`triggerPx` when needed (`types`, `extractTPSLFromOrders`, adapter)
> - Improves subscription restoration/cleanup, reference counting, L2
book handling, and extensive tests now use fake timers (`*.test.ts`)
> 
> **Tron UI and resources**
> 
> - Shows TRON APY conditionally in staking nav; only displays APR
override when > 0 (`EarnInputView`, `EarnWithdrawInputView`, `Navbar`)
> - `useTronResources`: avoid div-by-zero by using divisor max(1, max)
while keeping `max`=0 for display; tests updated
> 
> **Stake button copy & APY**
> 
> - Updates label to `Convert to mUSD` and surfaces TRON APY on TRX
staking (`StakeButton`, `en.json`)
> 
> **Build/Versioning & deps**
> 
> - Bumps version to `7.61.6` / code `3412` across Android/iOS/CI and
`package.json`
> - Updates `@metamask/tron-wallet-snap` to `^1.19.0`; minor Bitrise
pipeline tweaks
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d4b97da. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

This PR updates the header components in the Buy/Sell (Ramp Aggregator
and Deposit) flows to use the new `HeaderCenter` component from
`components-temp`.

**Reason for change:**
The Buy/Sell flows were using the older `BottomSheetHeader` component
for headers in modals and screens. This was inconsistent with the new
standardized header patterns being adopted across the app.

**Improvement/Solution:**
- Replaced `BottomSheetHeader` with `HeaderCenter` in Ramp Aggregator
views and modals:
  - `Quotes.tsx`
  - `FiatSelectorModal.tsx`
  - `PaymentMethodSelectorModal.tsx`
  - `RegionSelectorModal.tsx`
  - `TokenSelectModal.tsx`
- Replaced `BottomSheetHeader` with `HeaderCenter` in Deposit modals:
  - `WebviewModal.tsx`
  - `PaymentMethodSelectorModal.tsx`
  - `RegionSelectorModal.tsx`
  - `TokenSelectorModal.tsx`
  - `SsnInfoModal.tsx`
- Updated `getDepositNavbarOptions` in Navbar to use
`getHeaderCenterNavbarOptions` for consistent header styling across the
deposit flow

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:
https://consensyssoftware.atlassian.net/jira/software/c/projects/MDP/boards/2972?assignee=62afb43d33a882e2be47c36f&quickFilter=3325&selectedIssue=MDP-658

## **Manual testing steps**

```gherkin
Feature: Buy/Sell Header Consistency

  Scenario: User navigates through Buy flow modals
    Given the user is on the Buy screen
    
    When user taps on the currency selector
    Then the currency selector modal should display with the new centered header style
    
    When user taps on the region selector
    Then the region selector modal should display with the new centered header style
    
    When user taps on the payment method selector
    Then the payment method selector modal should display with the new centered header style
    
    When user proceeds to quotes
    Then the quotes screen should display with the new centered header style

  Scenario: User navigates through Deposit flow
    Given the user is on the Deposit screen
    
    When user interacts with various modals in the deposit flow
    Then all modals should display consistent centered headers with proper close buttons
```

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

https://www.figma.com/board/amtdUklN4zx1I4P6cyMNFh/HeaderQuestions?node-id=17-779&t=Ymcmh0vrFlTPyPX4-4

<!-- [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]
> Standardizes headers in Buy/Sell and Deposit flows to the new centered
header pattern.
> 
> - Refactors `getDepositNavbarOptions` to delegate to
`getHeaderCenterNavbarOptions`, introducing `startButtonIconProps`
(back/config) and `closeButtonProps`; adds `includesTopInset`
> - Updates unit test to expect `options.header()` and to trigger back
via `startButtonIconProps.onPress`
> - Refreshes snapshots across Ramp Aggregator/Deposit views to reflect
new header structure (`testID="header"`), spacing, and reduced
icon/button sizes (40→32, 24→20)
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
8728192. 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?
-->
  Smoke Test Workflows
- Updated Report job conditions to skip when selected_tags is [] or
["FlaskBuildTests"] only
  - Removes unnecessary job runs when no smoke tests are selected

## **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).
- [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]
> Refines smoke test reporting conditions to avoid unnecessary report
runs.
> 
> - In `run-e2e-smoke-tests-android.yml` and
`run-e2e-smoke-tests-ios.yml`, the `report-*-smoke-tests` job `if` now
checks `inputs.selected_tags != '[]' && inputs.selected_tags !=
'["FlaskBuildTests"]'`, preventing report execution when only Flask
build tests are selected.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
dc65394. 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**

A small UI update in the TRX detail page to be a bit more aligned with
what we have in the EVM side.
Also removes files that are not needed anymore.
Shows the tron apr in the trade menu (It was still hardcoded).

Before:
<img width="365" height="267" alt="Screenshot 2026-01-12 at 15 27 58"
src="https://github.com/user-attachments/assets/267f5500-696b-4e6b-a558-1652c560ee60"
/>

After:
<img width="397" height="387" alt="Attached_image"
src="https://github.com/user-attachments/assets/ce87cfc4-64e7-4460-990a-34f51d4b90ca"
/>

Also it now shows the tron apr coming from the Trade menu.
<img width="426" height="229" alt="Screenshot 2026-01-13 at 10 26 30"
src="https://github.com/user-attachments/assets/f9c1303c-f6f5-480a-996f-c94fb232876a"
/>



## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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



<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Aligns TRX staking UI with EVM and surfaces real TRX APR.
> 
> - Replace `TronStakingCta` with embedded CTA inside
`TronStakingButtons`; add theme-based styles, new `aprText` prop, and
CTA shown only when `hasStakedPositions` is false; keep Unstake/Stake
more actions
> - `EarnBalance`: for TRX without staked positions render only
`TronStakingButtons` and pass APR from `useTronStakeApy`
> - `EarnTokenList`: use `useTronStakeApy` to prefer real TRX APR
(`getTokenApr`); truncate APR values and update displayed text (e.g.,
`2.29% APR`, `4% APR`); highest APR and header now respect Tron APY;
preserve TRX inclusion when staking enabled
> - Remove obsolete `TronStakingCta` component, styles, and tests;
update related tests and snapshots to new UI and props
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b4315c1. 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**

- Remove SmokeCore as there is no tests currently

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

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> <sup>[Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) is
generating a summary for commit
ee92aa8. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

This PR adds real-time WebSocket infrastructure for live NFL game
updates in the Predict feature. It enables live score tracking, game
state synchronization, and real-time price updates for NFL prediction
markets.

**Why**: Users betting on live NFL games need real-time updates to make
informed decisions. Without WebSocket connections, the app would require
constant polling, creating poor UX and unnecessary server load.

**Solution**: Implemented a singleton WebSocket manager with two
connection types:
- **Sports WS** (`wss://sports-api.polymarket.com/ws`): Live game state
(scores, quarter, clock, possession)
- **Market WS**
(`wss://ws-subscriptions-clob.polymarket.com/ws/market`): Real-time
price updates

Key features:
- Auto-reconnection with exponential backoff
- GameCache singleton with 5-minute TTL for state persistence
- Subscription-based architecture with automatic cleanup
- 57 unit tests (23 GameCache + 34 WebSocketManager)

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: N/A (Internal feature development)

## **Manual testing steps**

```gherkin
Feature: Live NFL WebSocket Updates

  Scenario: User views live NFL game market
    Given the app is running with Predict feature enabled
    And there is an active NFL game

    When user navigates to an NFL market details page
    Then WebSocket connections are established
    And live game updates appear in Metro console logs
    And price updates stream in real-time

  Scenario: WebSocket reconnects after disconnect
    Given user is viewing an NFL market with active WebSocket
    
    When the WebSocket connection is lost
    Then the manager automatically reconnects with backoff
    And subscriptions are restored
```

## **Screenshots/Recordings**

### **Before**

N/A - New feature

### **After**

WebSocket test logs visible in Metro bundler console showing:
- `🧪 [WS-TEST] 🏈 GAME UPDATE RECEIVED:` - Live game state
- `🧪 [WS-TEST] 💰 PRICE UPDATE RECEIVED:` - Real-time prices

## **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 real-time infrastructure and caching for Polymarket NFL markets.
> 
> - **New `WebSocketManager`**: Manages sports
(`wss://sports-api.polymarket.com/ws`) and market
(`wss://ws-subscriptions-clob.polymarket.com/ws/market`) sockets with
subscriptions, PING heartbeats, exponential backoff reconnects, and
AppState-aware connect/disconnect
> - **New `GameCache`**: Singleton with 5‑minute TTL, periodic pruning,
and overlay helpers (`overlayOnMarket`/`overlayOnMarkets`) to merge live
`GameUpdate` onto `market.game`
> - **Provider integration**:
`PolymarketProvider.getMarkets`/`getMarketDetails` now apply `GameCache`
overlays to API results
> - **Tests/exports**: Comprehensive unit tests for cache and WS
manager; exports added in `index.ts`
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
a2aed48. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

The workflow to block stable sync branches from being squashed was
misconfigured to not run on the merge queue. This resulted in the merge
queue being blocked, as this check needs to be a required status check
to be effective.

The workflow has been updated to trigger upon `merge_group`, which fixes
the issue. It will be skipped for `merge_group` checks because the `if`
condition on the job is never satisfied (`github.head_ref` is not set
for `merge_group`), but `skipped` is enough to pass the required status
check.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Workflow introduced here:
#24366

The same fix has already been applied in the extension repo, here:
MetaMask/metamask-extension#39211

## **Manual testing steps**

N/A

## **Screenshots/Recordings**

N/A

## **Pre-merge author checklist**

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

## **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]
> Updates CI to ensure the stable-main→main block check participates in
merge queues.
> 
> - Adds `merge_group` trigger to
`/.github/workflows/block-stable-main-to-main.yml`
> - Existing job remains gated by `if: startsWith(github.head_ref,
'stable-main-')` and the regex check for `stable-main-X.Y.Z`
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
8f1bae7. 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**
Misc. design changes needed ahead of UAT for the mUSD conversion flow.

### Fixes
1. mUSD Conversion in progress toast:
- Fixed positioning to be uniform with other toasts. We had a custom
bottom offset that rendered the toast higher up.
  - Removed ETA
  - Replaced asset icon spinner with plain spinner
2. "Buy/Get mUSD" CTA above asset list
  - Replaced "Earn daily rewards" text with "Earn a X% bonus"
3. Updated mUSD conversion education screen layout and image
4. Updated copy throughout mUSD conversion flow
5. Added earning-percentage-row to custom-amount-info for
`musdConversion` transactions.

<!--
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: misc mUSD conversion flow design changes ahead of UAT

## **Related issues**

Fixes: [MUSD-187: mUSD conversion design adjustments ahead of
UAT](https://consensyssoftware.atlassian.net/browse/MUSD-187)

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

<!-- [screenshots/recordings] -->
New education screen
<img width="427" height="891" alt="image"
src="https://github.com/user-attachments/assets/57948952-a600-4053-87a4-be7ccab9ab5c"
/>

## **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]
> Modernizes the mUSD conversion experience and copy across the app.
> 
> - Revamps `EarnMusdConversionEducationView` layout: new themed images,
larger heading, full‑width primary and tertiary back buttons, SafeArea
top; route now hides header; updates tests
> - Simplifies conversion toasts in `useEarnToasts` and
`useMusdConversionStatus`: removes ETA and token icon lookups, uses a
plain spinner, smaller icon sizes, and passes only `tokenSymbol`; cleans
up dependencies and tests
> - Updates asset list CTA subtitle to “Earn a {{percentage}}% bonus”
using `MUSD_CONVERSION_APY`; adds `MUSD_CONVERSION_APY = 3` in
`constants/musd.ts` and adjusts tests
> - Adds `PercentageRow` to confirmations for `musdConversion` showing
the APY bonus; updates button label to `earn.musd_conversion.convert`
> - Removes unused `getCloseOnlyNavbar` and its tests; sets
`headerShown: false` for education route
> - Refreshes locales for education copy, CTA labels, and toast text
(delivered, bonus tooltip)
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
06895fd. 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 pull request pins the `cirruslabs/cache` action to a specific
version. This is due to the fact that v4 points to its v4 branch which
[changes periodically](https://github.com/cirruslabs/cache/commits/v4/)
introducing new code into our pipelines. Pinning to a specific hash
allows us to ensure we only use the version of the action at that
commit:
cirruslabs/cache@bba69c6
<!--
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: supply chain risk

## **Manual testing steps**

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

- [ ] 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]
> Pins GitHub Action `cirruslabs/cache` to commit
`bba69c6578b863ad0398ad40567bd2ef70290fe0` (v4) to avoid drifting branch
updates.
> 
> - Android: Update cache action in `build-android-e2e.yml` for APK
restore, Gradle dependencies, and build artifact caching
> - iOS: Update cache action in `build-ios-e2e.yml` for Xcode derived
data, app restore, and build artifact caching
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f56c688. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Mark Stacey <markjstacey@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**

<!--
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]
> Introduces smoke E2E coverage for the Trending feature and
consolidates API mocking for easier reuse.
> 
> - New Trending page object and selectors to drive UI
(`TrendingView.ts`, `TrendingView.selectors.ts`)
> - Two tests: navigating to Browser from Trending and basic search
interactions (`trending-browser.spec.ts`, `trending-search.spec.ts`)
> - Centralized mock set for Trending-related APIs
(`trending-api-mocks.ts`) and new `setupMockEvents` helper to register
grouped mocks
> - Extends `MockApiEndpoint` with optional `priority` and threads it
through mock setup for deterministic rule ordering
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
031706c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Curtis David <Curtis.David7@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**
Currently, running E2E tests locally on development builds requires
manual intervention to bypass several blocking screens (Developer Menu
and Development Server selection). This prevents autonomous AI agents
and automated scripts from executing the test suite without human
supervision.

This task implements automatic handling and dismissal for these screens
during the test setup phase.

Impact:

- Enables Autonomous Agents: AI agents (like Cursor) can now run, debug,
and iterate on E2E tests fully autonomously without getting stuck on
dev-only modals.

- Streamlined Local Testing: Developers no longer need to manually tap
through setup screens for every test run.
<!--
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]
> Enables unattended local E2E runs by bypassing React Native dev-only
screens.
> 
> - Adds `dismissDevScreens` in `viewHelper` and calls it from
`withFixtures` (non-CI) to auto-handle "Development servers" and
"Developer menu"
> - Introduces `METRO_PORT_E2E` and `METRO_HOST_E2E` in
`.e2e.env.example` for selecting the dev server row
> - Updates `.detoxrc.js` to always set Jest `forceExit` and
`detectOpenHandles` in `testRunner.args` (not only on CI)
> - Minor imports/typing adjustments to support the new helper
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
856d65b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Previous work related to claiming end of season reward `METAL_CARD` used
wrong terminology (i.e. CvLAIM should be REDEEM). This PR addresses
that.

## **Changelog**

CHANGELOG entry: null

## **Screenshots/Recordings**

### **After**

<img width="840" height="1814" alt="redem-1"
src="https://github.com/user-attachments/assets/2c5f04db-950c-43fa-98fc-6e128eb88731"
/>

<img width="972" height="1252" alt="redeem-failed"
src="https://github.com/user-attachments/assets/426e9485-d7f4-42dc-8802-48a86564db68"
/>

<img width="926" height="208" alt="redeem-success-1"
src="https://github.com/user-attachments/assets/2bfe7971-4be1-486a-8930-b5f58a762d67"
/>

<img width="936" height="336" alt="redeem-success-2"
src="https://github.com/user-attachments/assets/3304d7b3-2d96-4def-9597-78ded4beb7ab"
/>

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Modernizes the METAL_CARD end-of-season flow to use “Redeem”
terminology and copy across UI, navigation, and toasts.
> 
> - MetalCardClaimBottomSheet: use `route.params.title`; swap button
label and success/error toast/banner strings to
`rewards.claim_reward_redeem.*`; remove dependency on title in toast;
keep email/telegram + validation
> - PreviousSeasonUnlockedRewards: pass `title` to navigation; provide
`endOfSeasonClaimedDescription` and `claimCtaLabel` for METAL_CARD items
only
> - RewardItem: accept `endOfSeasonClaimedDescription` and
`claimCtaLabel`; use them for claimed text and claim button label
> - i18n: update `rewards.metal_card_claim.title` to “Redeem your
reward”; add `rewards.claim_reward_redeem` keys (button, success/failure
titles/descriptions)
> - Tests: adjusted to new labels, error messages, route `title`, and
new props
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
01d6ce7. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
This PR syncs the stable branch to main for version 7.62.0.

*Synchronization Process:*

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

*File Preservation:*

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

  Indicates the next version candidate of main to 7.62.0

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Syncs `stable` into `main` for version `7.62.0`.
> 
> - Preserves `CHANGELOG.md`, `bitrise.yml`, `android/app/build.gradle`,
`ios/MetaMask.xcodeproj/project.pbxproj`, and `package.json` from
`stable`
> - Aligns main with `stable` content for the 7.62.0 release candidate
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
8e49b4d. 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**

Today, there are no codeowner requirements for changes to the `.github`
directory despite it containing some of the most important pieces of
code for our builds and deployments. This CODEOWNER addition ensures
that there is always a mobile platform reviewer before any changes have
been made. This prevents people like myself from opening a PR with a
burner GitHub account, and approving/merging it using this GitHub
account

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


## **Manual testing steps**

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

- [ ] 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]
> Ensures review coverage for repository-level workflows and
configuration.
> 
> - Adds `.github/ @MetaMask/mobile-platform` entry in `CODEOWNERS` to
require Mobile Platform review for any changes under `.github/`
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
10ce63b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Mark Stacey <markjstacey@gmail.com>
## **Description**

Uses custom values for min liquidity and min24hVolume for params used in
trending request to filter out low liquidity tokens

## **Changelog**

CHANGELOG entry: use custom values for liquidity and min14hvalue param
for trending requests

## **Related issues**

Fixes: #24390

## **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]
> Applies stricter default filters for trending tokens to reduce
low-liquidity results.
> 
> - Adds `TRENDING_MIN_LIQUIDITY = 200000` and `TRENDING_MIN_VOLUME_24H
= 1000000`
> - Updates `useTrendingRequest` defaults to use these constants for
`minLiquidity` and `minVolume24hUsd`
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
e8b57fb. 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?
-->

This PR removes code related to the legacy "Reveal Private Key" feature.
This feature was deprecated with the release of BIP-44 and the
implementation of a new "Reveal Private Key" flow.

## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MUL-1375

## **Manual testing steps**

```gherkin
Feature: remove legacy "Reveal Private Key"

  Scenario: user reveal private key for multichain account
    Given the new reveal private key flow

    When user selects the option "Private Key" in the Account Details menu
    Then a list of hidden private keys should be displayed for the user to copy
```

## **Screenshots/Recordings**

Not  applicable, no changes to the UI/UX

## **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]
> Removes the legacy private key reveal flow and consolidates
`RevealPrivateCredential` to SRP-only, while rerouting private key
export to the multichain account details sheet.
> 
> - `RevealPrivateCredential` now handles only SRP: strips private-key
paths/strings/UI, updates analytics, modal copy, warnings, and
navigation handling; large test suite rewritten accordingly
> - "Show private key" action now navigates to
`Routes.SHEET.MULTICHAIN_ACCOUNT_DETAILS.REVEAL_PRIVATE_CREDENTIAL` with
`{ account }`
> - Deletes Settings > "Reveal Private Key" section and related styles,
tests, snapshots, and e2e pages; removes legacy reveal private key tests
under Multichain sheets
> - Updates `SRPQuiz` and `ErrorBoundary` to stop passing
`credentialName`; adds selector `SEED_PHRASE_WARNING_ID`
> - Keeps minimal Multichain `RevealPrivateKey` sheet header; e2e spec
removes private key export case
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0dce40f. 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 reverts the dedicated Token Insights sheet in favor of reusing
the existing Asset details 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: revert: token insights modal 

## **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]
> Reverts the dedicated Token Insights flow in favor of the existing
Asset details screen.
> 
> - BridgeDestTokenSelector: info button now dispatches navigation to
`Asset` with a unique key and token params; event tracking retained
> - Removed `TokenInsightsSheet` component, tests, and snapshots
> - Deleted `Routes.SHEET.TOKEN_INSIGHTS` and its screen registrations
from `App.tsx`
> - Updated tests to assert navigation via dispatch to `Asset` instead
of the Token Insights sheet
> - Cleaned up related i18n strings under `bridge`
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d8cd155. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…fetch or return empty object (#24428)

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

## **Description**

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

This PR fixes an issue where the `selectCardFeatureFlag` selector would
return an empty object `{}` when the remote feature flag returned an
empty object, instead of falling back to the default card feature flag
configuration.

**Problem**: The previous implementation used `cardFeatureFlag ??
defaultCardFeatureFlag` which only handles `null` and `undefined` cases.
When the remote feature flag returns an empty object `{}`, this check
passes and the empty object is used, causing missing chain
configurations and constants.

**Solution**: Updated the selector to check if the `cardFeatureFlag` has
any keys using `Object.keys(cardFeatureFlag ?? {}).length > 0`. If the
object is empty (or null/undefined), it now correctly returns the
default card feature flag configuration.

## **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 fallback for cardFeature flag using local value

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: Card Feature Flag Selector

  Scenario: user receives empty card feature flag from remote
    Given the remote feature flag returns an empty object for cardFeature

    When the selectCardFeatureFlag selector is called
    Then it returns the default card feature flag configuration with chains and constants
```

## **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]
> Ensures `selectCardFeatureFlag` falls back to `defaultCardFeatureFlag`
when the remote `cardFeature` is null/undefined or an empty object.
> 
> - Update selector to return default when `Object.keys(cardFeatureFlag
?? {}).length === 0`
> - Add unit test covering empty-object `cardFeature` scenario
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
cc43824. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@pull pull Bot locked and limited conversation to collaborators Jan 13, 2026
@pull pull Bot added the ⤵️ pull label Jan 13, 2026
@pull pull Bot merged commit 82b6ade into Reality2byte:main Jan 13, 2026
0 of 34 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.