release: 7.71.0#27708
Merged
Merged
Conversation
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** ### Changes: - Adds Segment event tracking for the mUSD Quick Convert flow - Enriches generic `Transaction*` events for `musdConversion` transactions - Adds `confirmation_source` to differentiate between the "Max" convert bottom sheet and custom amount confirmations - Adds `is_max` which is `true` when "Max" conversion flow is used or when custom amount is used and user clicks "Max" button in percentage button row - Adds mUSD quote tracking data ### Events | Event | Type | Location | Description | |---|---|---|---| | `mUSD Quick Convert Screen Viewed` | New standalone event | `MusdQuickConvertView` (on mount) | Fires when the quick convert token list screen is viewed | | `mUSD Bonus Terms of Use Pressed` | New standalone event | `MusdQuickConvertView` (`quick_convert_home_screen`), `EarnMusdConversionEducationView` (`conversion_education_screen`), `useMusdConversionNavbar` (`custom_amount_navbar`), `PercentageRow` (`percentage_row`) | Fires when user presses the bonus terms of use link; `location` property differentiates the source | | `mUSD Quick Convert Token Row Button Clicked` | New standalone event | `MusdQuickConvertView` | Fires on "Max" or "Edit" button tap; includes `button_action`, `redirects_to`, asset details | | `confirmation_source` | New property on `Transaction*` events | `useMusdConversionConfirmationMetrics` | `'quick_convert_max_bottom_sheet_confirmation_screen'` or `'custom_amount_screen'` — only attached to `musdConversion` transactions | | `is_max` | New property on `Transaction*` events | `useMusdConversionConfirmationMetrics` | Derived from `TransactionPayController.isMaxAmount` — only attached to `musdConversion` transactions | | Quote tracking data | New properties on `Transaction*` events | `useMusdConversionConfirmationMetrics` | Standardized quote/pay data via `getMusdConversionQuoteTrackingData` — only attached to `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: Added Segment event tracking for mUSD Quick Convert flow and enrich generic Transaction* events for mUSD conversion transactions ## **Related issues** Fixes: [MUSD-454: Add segment events for Quick Convert flow](https://consensyssoftware.atlassian.net/browse/MUSD-454) ## **Manual testing steps** ```gherkin Feature: mUSD Quick Convert Segment event tracking Scenario: user views the quick convert screen Given user navigates to the mUSD Quick Convert screen When the screen mounts Then "mUSD Quick Convert Screen Viewed" event fires with location "quick_convert_home_screen" Scenario: user taps Max on a token row Given user is on the mUSD Quick Convert screen with convertible tokens When user taps "Max" on a token row Then "mUSD Quick Convert Token Row Button Clicked" event fires with button_action "max" and redirects_to "quick_convert_max_bottom_sheet_confirmation_screen" Scenario: user taps Edit on a token row Given user is on the mUSD Quick Convert screen with convertible tokens When user taps the edit icon on a token row Then "mUSD Quick Convert Token Row Button Clicked" event fires with button_action "custom" and redirects_to "custom_amount_screen" Scenario: user taps "Terms apply" link on the quick convert screen Given user is on a screen displaying the mUSD bonus "Terms apply" link When user taps "Terms apply" Then "mUSD Bonus Terms of Use Pressed" event fires with the location of the current screen Scenario: user confirms a max mUSD conversion Given user is on the max convert bottom sheet confirmation When user taps "Convert" Then "Transaction Approved" event includes confirmation_source "quick_convert_max_bottom_sheet_confirmation_screen", "is_max: true", and quote tracking data Scenario: user confirms a custom amount mUSD conversion Given user is on the custom amount conversion screen When user taps "Convert" Then "Transaction Approved" event includes confirmation_source "custom_amount_screen", "is_max: false" ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adds new MetaMetrics events and confirmation-metric dispatches across mUSD conversion/confirmation screens; while behavior is mostly observational, it touches confirmations flow and transaction status tracking and could affect analytics payloads or introduce unintended side effects if hooks fire unexpectedly. > > **Overview** > Adds **MetaMetrics tracking for the mUSD Quick Convert flow**, including `MUSD_QUICK_CONVERT_SCREEN_VIEWED`, `MUSD_QUICK_CONVERT_TOKEN_ROW_BUTTON_CLICKED` (Max/Edit), and `MUSD_BONUS_TERMS_OF_USE_PRESSED` with location/context properties. > > Introduces a shared analytics utility (`getMusdConversionQuoteTrackingData` + `deepSnakeCaseKeys`) and refactors `useMusdConversionStatus` to use it when emitting `MUSD_CONVERSION_STATUS_UPDATED`, standardizing quote-derived properties. > > Enriches **confirmation metrics for `musdConversion`** by adding a new `useMusdConversionConfirmationMetrics` hook (wired into `MusdConversionInfoRoot`) that dispatches `confirmation_source`, `is_max`, and select quote fields into `confirmationMetrics`. Tests are updated/added accordingly, and `EVENT_LOCATIONS`/`MetaMetricsEvents` are extended to support the new instrumentation. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 6e2e686. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Updated the following dependencies (with required integration work, if any): 1. `@metamask/accounts-controller` - Update `getInternalAccountByAddress` selector. 2. `@metamask/preferences-controller` - Update `PreferencesController` state type. 3. `@metamask/account-tree-controller` 4. `@metamask/delegation-controller` 5. `@metamask/multichain-network-controller` 6. `@metamask/multichain-transactions-controller` ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: N/A ## **Manual testing steps** 1. Build from branch. 2. Create an account 3. Verify nothing breaks ## **Screenshots/Recordings** N/A ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Bumps multiple core controller dependencies and changes account lookup to rely on the new `AccountsController.state.accountIdByAddress` map, which could affect any code paths that resolve accounts by address if the map is missing or stale. > > **Overview** > Updates several MetaMask core dependencies (notably `@metamask/accounts-controller` to `37.0.0` and `@metamask/account-tree-controller` to `5.x`). > > Adopts the new `AccountsController` state field `accountIdByAddress` by adding it to default/fixture state and updating `getInternalAccountByAddress` to resolve accounts via this map (with lowercase fallback) instead of scanning all accounts. > > Adjusts tests, fixtures, and snapshots to include `accountIdByAddress`, and updates migration test typings to reflect that this field is non-persisted. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit bc2a1ab. 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 embed the metal card checkout flow into the Card
onboarding/sign-up 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: embed the metal card checkout flow into the Card
onboarding/sign-up flow.
## **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] -->
https://github.com/user-attachments/assets/776a82dc-b814-4dd1-96da-b902932c31cc
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Changes card onboarding navigation (including new `home` flow params
and StackActions replacement) and adds new UI/animation behavior, which
could affect user progression through card setup if eligibility logic or
routing params are wrong.
>
> **Overview**
> Eligible US users who press **Enable Card** from `CardHome` are now
redirected to `Routes.CARD.CHOOSE_YOUR_CARD` (new `flow: 'home'`)
instead of always starting delegation/spending-limit setup; the route
passes through `shippingAddress` plus token/delegation/external wallet
context.
>
> `ChooseYourCard` is updated to support the new `home` flow, adds a
swipe/peek affordance and an *upgrade-to-metal* link, refreshes
metal/virtual copy, and routes virtual-card selection into
`SPENDING_LIMIT` with `flow: 'manage'` and the forwarded params.
>
> Post-order behavior changes so `OrderCompleted` uses
`StackActions.replace` to take onboarding users directly to
`SPENDING_LIMIT` (while upgrade users still go back to `CARD.HOME`), and
`SpendingLimit` now blocks back navigation during loading using a ref to
avoid stale listener state. Tests and English strings are updated
accordingly.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
c52fcb5. 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? --> Removed unused mocks. ## **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/DSYS-274 ## **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** <img width="230" height="451" alt="image" src="https://github.com/user-attachments/assets/295aa62b-a17e-42e7-ba3b-6fd8e52c5949" /> ### **After** <img width="230" height="451" alt="image" src="https://github.com/user-attachments/assets/0a14d265-7cec-49d0-850f-82c2cfdba501" /> ## **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] > **Low Risk** > Test-only change that removes redundant Jest mocks; low risk aside from potentially reintroducing minor animation/timing differences in affected tests. > > **Overview** > Removes the custom Jest mock for the `Skeleton` component from `BridgeView.test.tsx` and `SwapsConfirmButton.test.tsx`, relying on the real implementation during tests. > > This cleans up unused test scaffolding in the Bridge/Swaps test suite without changing production behavior. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e94e5df. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## Version Bump After Release This PR bumps the main branch version from 7.70.0 to 7.71.0 after cutting the release branch. ### Why this is needed: - **Nightly builds**: Each nightly build needs to be one minor version ahead of the current release candidate - **Version conflicts**: Prevents conflicts between nightlies and release candidates - **Platform alignment**: Maintains version alignment between MetaMask mobile and extension - **Update systems**: Ensures nightlies are accepted by app stores and browser update systems ### What changed: - Version bumped from `7.70.0` to `7.71.0` - Platform: `mobile` - Files updated by `set-semvar-version.sh` script ### Next steps: This PR should be **manually reviewed and merged by the release manager** to maintain proper version flow. ### Related: - Release version: 7.70.0 - Release branch: release/7.70.0 - Platform: mobile - Test mode: false --- *This PR was automatically created by the `create-platform-release-pr.sh` script.* Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->
## **Description**
Refactors the Perps Market Details screen to use the shared
`HeaderStandardAnimated` component instead of the custom
`PerpsMarketHeader` and navbar options, aligning with patterns used
elsewhere (e.g. Perps home, Token Details).
1. **Reason for the change:** Market Details used
`getPerpsMarketDetailsNavbar` (navigation.setOptions) and a custom
`PerpsMarketHeader` component; this was inconsistent with other screens
that use component-library header primitives and scroll-linked header
animation.
2. **Improvement:** Replaced `PerpsMarketHeader` with
`HeaderStandardAnimated`. Title is
`${getPerpsDisplaySymbol(market.symbol)}-USD`; subtitle is
`LivePriceHeader` (symbol, current price, throttle). Back button,
fullscreen (expand) and watchlist (star) actions are passed as
`endButtonIconProps`. Removed the navbar `useEffect`. Scroll content is
now an `Animated.ScrollView` with scroll passed to the header; a
`TitleSubpage` block at the top (token logo, title, leverage badge, and
`LivePriceHeader` as bottom accessory) drives the title section height
via `onLayout` and `useHeaderStandardAnimated`. `LivePriceHeader` text
variants were updated to `BodySM` and price color to `Alternative` for
the compact header context.
## **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/issues?jql=issueKey%20in%20(DSYS-555%2CDSYS-556%2CDSYS-557%2CDSYS-558)&selectedIssue=DSYS-558
## **Manual testing steps**
```gherkin
Feature: Perps Market Details header
Scenario: Market Details shows animated header and title section
Given the app is open and user has access to Perps
When user opens a market (e.g. ETH-USD) from the Perps list
Then the screen shows HeaderStandardAnimated with market title (e.g. "ETH-USD") and live price as subtitle
And the header shows back button, fullscreen (expand) and watchlist (star) actions
And the scroll area shows TitleSubpage with token logo, title, leverage badge, and live price
When user scrolls the page
Then the header animates (collapses/expands) in sync with scroll
And chart, stats, and rest of content remain usable
```
## **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/eaf0e7ee-766a-4c84-8e48-7b7d9a897621
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Refactors the Perps Market Details header/navigation and scroll
handling, which could introduce UI regressions (collapsed header
behavior, button actions, layout) on a high-traffic trading screen. No
changes to trading/business logic or data handling.
>
> **Overview**
> Refactors the Perps Market Details screen to use the shared
`HeaderStandardAnimated` pattern instead of the bespoke
`PerpsMarketHeader` and `navigation.setOptions` navbar configuration.
>
> The header is now driven by `useHeaderStandardAnimated` and an
`Animated.ScrollView`, with a new top-of-page `TitleSubpage` section
(token logo, title, leverage badge, and live price) providing the
measured height for the collapse/expand animation; fullscreen and
watchlist actions are wired through header icon props.
>
> Updates `HeaderStandardAnimated` to accept non-string
`title`/`subtitle` nodes, adjusts `LivePriceHeader` typography for the
compact header, removes the unused `getPerpsMarketDetailsNavbar`, and
extends Perps test IDs/tests to account for duplicated title rendering
(header + title section) and new price/change selectors.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0f37d84. 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** Refactors multiple e2e page objects and flows to use the new framework-agnostic element/gesture layer (EncapsulatedElementType, UnifiedGestures, encapsulatedAction) so the same objects work under both Detox and Appium/Playwright. Adds/adjusts selector plumbing to support this migration, including new localized selector text in NetworkEducationModal/WalletActionsBottomSheet test IDs, swipe option passthrough (speed, percentage) in UnifiedGestureOptions, and new swap/bridge performance-test helpers in QuoteView (token testId derivation, quote-visible assertion text, and network→chainId mapping). ## **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: https://consensyssoftware.atlassian.net/browse/MMQA-1563 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Refactors a wide set of e2e page objects and selectors to a new cross-framework abstraction, which can cause broad test failures if any locator mapping is wrong. App runtime behavior is largely unchanged aside from adding a few `testID`s used by automation. > > **Overview** > Updates e2e automation to use the framework-agnostic `EncapsulatedElementType`/`UnifiedGestures`/`encapsulatedAction` APIs across login, wallet, perps, networks, and swap/bridge page objects, including replacing direct Detox elements with dual Detox+Appium/Playwright locators. > > Extends selector plumbing to support the migration: adds new localized selector text constants, passes through swipe options (`speed`, `percentage`) in unified gesture options, and adds swap/bridge helpers (fee-disclaimer `testID`, token testId derivation, network→chainId mapping, and quote-visibility assertions) to stabilize performance and deeplink tests. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e474ab6. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…ons (#27436) <!-- 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 migrates the page objects used by `mm-connect` in the performance tests to the new unified framework. <!-- 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: https://consensyssoftware.atlassian.net/browse/MMQA-1564 ## **Manual testing steps** N/A ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** N/A <!-- [screenshots/recordings] --> ### **After** N/A <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Moderate risk because it refactors shared E2E/performance test infrastructure (driver utilities, visibility/wait options, and context switching), which can cause widespread test flakiness if selector semantics or WebView switching behavior differs. > > **Overview** > Migrates MM-Connect performance test coverage off the legacy `wdio/screen-objects` page objects into new TypeScript page objects under `tests/page-objects/MMConnect`, built on the unified `EncapsulatedElement` + `UnifiedGestures` APIs. > > Refactors Playwright/WebdriverIO test utilities by extracting `boxedStep`/`getDriver` into `PlaywrightUtilities`, expanding `PlaywrightElement.isVisible`/`waitForDisplayed` to accept WebdriverIO `isDisplayed` options, and adding a custom `expect.toBeVisible` matcher in the performance fixture. > > Adds `PlaywrightContextHelpers` to make WebView context switching more robust (URL matching with a LavaMoat-scuttling fallback) and introduces shared `MMConnectDappTestIds` plus updated Snap footer selector IDs; `@wdio/protocols` is added to support typed context APIs. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 804fc1e. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
Add PredictBuyWithAnyToken view, components, and hooks for the pay-with-any-token order flow. Includes PredictController, payment token selection, fee summary, order tracking, navigation, active order management, feature flag selectors, and full test coverage. <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** Adds the "Buy With Any Token" flow to prediction markets, enabling users to place bets using any token in their wallet (not just their predict balance). When a user doesn't have sufficient USDC.e balance on Polygon, this flow handles the deposit + order as a single transaction batch through the confirmations framework. This is **PR 1 of 2** — contains only `@MetaMask/predict`-owned code. A follow-up PR will add the confirmations integration (registering the new `predictDepositAndOrder` transaction type, pay-with-modal changes, and navigation support). ### What's included **New view — `PredictBuyWithAnyToken`** Full buy preview screen with amount input, fee summary, action button, and payment token selection. Renders both standalone (predict routes) and within confirmations (as info-root content). **PredictController state extensions** - `activeOrder` — tracks order lifecycle (preview → confirming → success/error) - `selectedPaymentToken` — stores the user's chosen payment token **New hooks (13)** | Hook | Purpose | |------|---------| | `usePredictActiveOrder` | Manages active order state in controller | | `usePredictNavigation` | Navigation helpers with replace support | | `usePredictPayWithAnyToken` | Triggers deposit+order confirmation flow | | `usePredictPaymentToken` | Handles payment token selection changes | | `usePredictBalanceTokenFilter` | Filters available tokens for predict context | | `usePredictBuyPreviewActions` | Orchestrates confirm/back/error handlers | | `usePredictBuyConditions` | Derives UI state (canPlaceBet, isBelowMinimum) | | `usePredictBuyInfo` | Computes fees, total, toWin from preview | | `usePredictBuyInputState` | Manages amount input + focus state | | `usePredictBuyAvailableBalance` | Calculates available balance | | `usePredictBuyBackSwipe` | Back gesture handler | | `usePredictOrderTracking` | Tracks order result (success/error) | | `usePredictPayWithAnyTokenTracking` | Tracks deposit confirmation lifecycle | **New components (8)**: PredictBuyActionButton, PredictBuyAmountSection, PredictBuyBottomContent, PredictBuyMinimumError, PredictBuyPreviewHeader, PredictFeeSummary, PredictPayWithRow, PredictPayWithAnyTokenInfo **Feature flag selectors**: `selectPredictFakOrdersEnabledFlag`, `selectPredictWithAnyTokenEnabledFlag` — gated behind remote `predictWithAnyToken` flag. **Other changes**: - Routes updated with new navigation stack entries - Analytics helpers for parsing order event properties - Transaction constants (chain ID, placeholder address, minimum bet) <!-- 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] > **High Risk** > Adds a new deposit+order transaction-batching path (`payWithAnyTokenConfirmation`) and new controller state for active orders/payment-token selection, which affects confirmation routing and transaction submission. Although gated by a remote flag, mistakes could break Predict order placement/deposit flows or create incorrect confirmation behavior. > > **Overview** > Introduces a new *Buy With Any Token* Predict buy-preview flow, gated by the remote `predictWithAnyToken` flag, and wires Predict routing to swap `BUY_PREVIEW` between the legacy screen and the new `PredictBuyWithAnyToken` view. > > Extends `PredictController` with ephemeral `activeOrder` and `selectedPaymentToken` state plus setters, and adds `payWithAnyTokenConfirmation()` to submit a deposit transaction batch that re-tags `predictDeposit` txs as `predictDepositAndOrder` to drive a new confirmation/info experience. > > Adds supporting hooks/utilities for navigation (`usePredictNavigation`), active order and token selection (`usePredictActiveOrder`, `usePredictPaymentToken`, `usePredictBalanceTokenFilter`), order preview initialization (`initialPreview`), and shared error/toast + analytics helpers; updates buy UI components to reflect the new fee summary/deposit-fee row and improved deposit-in-progress handling. Test coverage is expanded broadly across the new hooks, selectors, navigation, and controller behavior. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 7f6706f. 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** In the current workflow, the OTA PR needs to point to a base that is the same as the branch that we are applying the OTA to. However, this does not work because when we have a release branch, since the base is always `stable` so we will need to change the base branch whenever we run OTA update. In this PR: - Get rid of hash commit input. We don't really need it because we will remove the approval if a new commit is pushed and we will always use the latest commit - We get the latest commit hash in the OTA PR and output it in the workflow - Remove the restriction on the OTA base branch. In the OTA PR, it shouldn't matter which base branch it's pointing to. We will compare the fingerprint to the actual release tag that the OTA is applying (which is one of the inputs when triggering the workflow) workflow run: https://github.com/MetaMask/metamask-mobile/actions/runs/23026234415 ## **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 OTA workflow commit hash input ## **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** - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Medium risk because it changes the OTA release workflow’s source-of-truth for what gets built/published and removes prior base-branch/commit validation, which could result in publishing an unintended revision if PR context is wrong. > > **Overview** > Updates the OTA `push-eas-update` workflow to publish from a PR’s **current HEAD commit** rather than a user-supplied commit SHA. > > Reworks `.github/scripts/validate-pr-commit.sh` to *resolve* and output `commit_sha` for a given `PR_NUMBER` (no longer validates `COMMIT_HASH` or `BASE_BRANCH`), and wires this new output through checkout, dependency setup, fingerprint comparison, and the final push step; the manual `commit_hash` input and the old “validate PR contains commit” job are removed. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 2d9dcd1. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…n rows (TMCU-569) (#27449) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** This PR adds a dot separator (•) between the price and variation text in token rows on the homepage, aligning with the `price • variation` format used in `TokenListItemV2`. **1. What is the reason for the change?** - Token rows in the Cash section and Popular Tokens section did not follow the same layout as token list items - `TokenListItemV2` displays price and variation as `$1.00 • +5.25%` (or similar) - The MUSD row in Cash and the Popular Token rows were missing this separator **2. What is the improvement/solution?** - Insert the Unicode bullet (`\u2022`) between the price and variation - Update `PopularTokenRow` so price and percentage display as `price • variation` - Update `CashGetMusdEmptyState` for the MUSD empty state - Adjust test assertions in `PopularTokenRow.test.tsx` to match the new format ## **Changelog** CHANGELOG entry: Fixed token row display on homepage to show price and variation separated by a dot for consistency with token list items ## **Related issues** Fixes: [TMCU-569](https://consensyssoftware.atlassian.net/browse/TMCU-569) ## **Manual testing steps** ```gherkin Feature: Homepage token row display consistency Scenario: user views token rows with price and variation Given the user is on the Homepage And the Cash section shows MUSD or Popular Tokens shows tokens with price/variation When the user views the token row Then price and variation are separated by a dot (•) And the layout matches TokenListItemV2 (e.g. "$1.00 • 3% bonus" or "$1,234.56 • +5.25%") ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <img width="300" src="https://github.com/user-attachments/assets/b81022c5-6d85-4f86-9b74-f246503b8475" /> ### **After** <img width="300" src="https://github.com/user-attachments/assets/03c27fe4-07d0-49fa-947f-3fa1ca12efaa" /> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk UI-only change to text/layout formatting plus corresponding test updates; no data, auth, or navigation logic changes. > > **Overview** > Aligns homepage token rows with the `price • variation` display by inserting a Unicode bullet separator between the price and percentage/bonus text. > > Updates `PopularTokenRow` to render the separator *only when* a percentage value is present (and simplifies the layout), and tweaks `CashGetMusdEmptyState` to show the same separator for the mUSD row. Tests are updated to assert the new formatting and ensure no trailing bullet appears when variation is absent/invalid. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit dcda7cd. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
… with Tailwind CSS (#26737) ## **Description** Replace StyleSheet.create() and useStyles() with useTailwind() and Box/twClassName in the OnboardingSuccess settings sub-screens: DefaultSettings, OnboardingAssetsSettings, OnboardingGeneralSettings, and OnboardingSecuritySettings. Delete the now-unused .styles.ts files. ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: [TO-558 - Migrate OnboardingSuccess/DefaultSettings to Design System (Box/Text + Tailwind)](https://consensyssoftware.atlassian.net/browse/TO-558) Refs: [TO-559 - Migrate OnboardingSuccess/OnboardingAssetsSettings to Design System (Box/Text + Tailwind)](https://consensyssoftware.atlassian.net/browse/TO-559) Refs: [TO-560 - Migrate OnboardingSuccess/OnboardingGeneralSettings to Design System (Box/Text + Tailwind)](https://consensyssoftware.atlassian.net/browse/TO-560) Refs: [TO-561 - Migrate OnboardingSuccess/OnboardingSecuritySettings to Design System (Box/Text + Tailwind)](https://consensyssoftware.atlassian.net/browse/TO-561) ## **Manual testing steps** No functional changes. Visual regression only — verify onboarding settings screens render correctly. ```gherkin Feature: Onboarding success settings styling Scenario: user navigates through default settings Given user has completed wallet creation When user taps through DefaultSettings, GeneralSettings, AssetsSettings, SecuritySettings Then all settings screens render identically to before ``` ## **Screenshots/Recordings** ### **Before left, After right** <img width="500" height="1052" alt="Screenshot 2026-03-02 at 11 22 05 AM" src="https://github.com/user-attachments/assets/cac80a22-357f-4b61-8a48-3b554e107088" /> <img width="500" height="1052" alt="Screenshot 2026-03-02 at 11 22 14 AM" src="https://github.com/user-attachments/assets/8e207cfb-b6b6-46df-a74d-0eb78d2e0eaa" /> <img width="500" height="1052" alt="Screenshot 2026-03-02 at 11 22 21 AM" src="https://github.com/user-attachments/assets/af0b44a4-e2b5-4b4d-9880-b46893845a09" /> <img width="500" height="1097" alt="Screenshot 2026-03-02 at 11 22 32 AM" src="https://github.com/user-attachments/assets/e5076dc4-cfdc-4326-a9c1-ff09be60ec12" /> ## **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. Made with [Cursor](https://cursor.com) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Primarily a styling refactor (StyleSheet/useStyles -> Tailwind + design-system `Box`/`Text`) with no intended logic changes; main risk is minor visual/layout regressions on the onboarding settings screens. > > **Overview** > **Migrates the OnboardingSuccess settings sub-screens to the new design system styling approach.** `DefaultSettings`, `OnboardingAssetsSettings`, `OnboardingGeneralSettings`, and `OnboardingSecuritySettings` now use `useTailwind()` styles (and `Box`/design-system `Text` where applicable) instead of `StyleSheet.create()` + `useStyles()`. > > Removes the now-unused local `*.styles.ts` files and updates Jest snapshots to reflect the new computed style objects (e.g., flex/padding and text style differences). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit c0ea7f9. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->
## **Description**
Updates the Referral Rewards view, Rewards Settings view, and End of
Season Claim bottom sheet to use the shared `HeaderCompactStandard`
component and consistent safe-area handling, aligning with patterns used
elsewhere in Rewards (e.g. Rewards Dashboard).
1. **Reason for the change:** Referral view used
`getNavigationOptionsTitle` and stack header; Settings and End of Season
Claim used different header primitives (`BottomSheetHeader` in the claim
sheet). This was inconsistent and made safe-area behavior harder to
reason about.
2. **Improvement:** Referral view now uses inline
`HeaderCompactStandard` with `SafeAreaView` and `headerShown: false` for
its stack screen. Settings view SafeAreaView uses `edges={{ top:
'additive' }}` and `HeaderCompactStandard` no longer uses
`includesTopInset`. End of Season Claim bottom sheet uses
`HeaderCompactStandard` instead of `BottomSheetHeader`, with the sheet
title passed as the header `title` prop (custom header title render
removed).
## **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/issues?jql=issueKey%20in%20(DSYS-555%2CDSYS-556)&selectedIssue=DSYS-556
## **Manual testing steps**
```gherkin
Feature: Rewards headers and safe area
Scenario: Referral Rewards view shows inline header
Given the app is open and user has access to Rewards
When user navigates to Referral Rewards
Then the screen shows HeaderCompactStandard with "Referral" title and back button
And content is wrapped in SafeAreaView and scrolls correctly
Scenario: Rewards Settings view header and safe area
When user navigates to Rewards Settings
Then the header and content respect safe areas (top additive)
And the back button and title display correctly
Scenario: End of Season Claim bottom sheet header
When user opens the End of Season Claim bottom sheet (when applicable)
Then the sheet shows HeaderCompactStandard with the reward title and close button
And the sheet content and keyboard behavior are unchanged
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<img width="1290" height="2796" alt="Simulator Screenshot - iPhone 15
Pro Max - 2026-03-10 at 16 32 06"
src="https://github.com/user-attachments/assets/ec4e8d4a-044e-4752-8a66-26c6d3b06b8b"
/>
<img width="1290" height="2796" alt="Simulator Screenshot - iPhone 15
Pro Max - 2026-03-10 at 16 35 28"
src="https://github.com/user-attachments/assets/3d84c6af-0f6f-477c-b648-86651ebd692b"
/>
<img width="1290" height="2796" alt="Simulator Screenshot - iPhone 15
Pro Max - 2026-03-10 at 16 42 41"
src="https://github.com/user-attachments/assets/2d0c0294-3696-4016-a6c2-63411fa24200"
/>
<!-- [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]
> **Low Risk**
> Low risk UI refactor affecting header rendering and safe-area insets
on a few Rewards screens; main regression risk is incorrect insets or
back/close behavior.
>
> **Overview**
> Unifies Rewards header behavior by moving the Referral screen off the
stack header (`headerShown: false`) and rendering an inline
`HeaderCompactStandard` inside a `SafeAreaView`.
>
> Adjusts Rewards Settings safe-area handling to use `edges={{ top:
'additive' }}` (and removes `includesTopInset` from the header) for more
consistent inset behavior.
>
> Replaces the End-of-Season claim sheet’s `BottomSheetHeader` with
`HeaderCompactStandard`, using the reward `title` directly (and removing
the previous non-LINEA custom title renderer), and updates/streamlines
associated tests accordingly.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
1affda9. 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? --> Migrate Skeleton to use DSRN. ## **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/DSYS-274 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/045473e8-541f-4e7f-ad34-03527a59e92b ### **After** https://github.com/user-attachments/assets/179f2212-5fe8-415b-954f-c19243c79627 ## **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] > **Low Risk** > Mostly mechanical import/mocking changes to swap Rewards screens and tests over to the new `components-temp` `Skeleton`; functional risk is limited to loading placeholders rendering/autoPlay behavior. > > **Overview** > Migrates the Rewards UI (onboarding, season status, previous season, referral details, settings, and tabs) to use the new design-system-backed `Skeleton` from `component-library/components-temp/Skeleton` instead of the legacy component. > > Updates associated unit tests to mock the new `Skeleton` module paths and types so loading-state coverage continues to pass. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit b310d00. 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** migrate renderBottomContent into independent component <!-- 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: N/A ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/SWAPS-4101 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk refactor that moves existing footer rendering logic into a new component and adds targeted tests; main risk is minor UI regression in when the confirm button/banners/disclaimer render. > > **Overview** > Extracts `BridgeView`’s inline `renderBottomContent` into a new `BridgeViewFooter` component and wires it into `BridgeView`, removing the duplicated footer logic and related imports. > > Adds a dedicated `BridgeViewFooter.test.tsx` covering render gating (loading/no quote/missing amount), hardware-wallet Solana banner, Blockaid alert banner, fee/no-fee disclaimer, and approval disclaimer/tooltip, while deleting the corresponding footer-specific tests from `BridgeView.test.tsx`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 8721336. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…27416) <!-- 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** Allow user to send to contract address, but add warning for that on both send and confirmation page. ## **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: MetaMask/MetaMask-planning#6962 ## **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** https://github.com/user-attachments/assets/3cd4e562-5f4f-40fd-a498-805a495d7d19 ## **Pre-merge author checklist** - [X] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [X] I've completed the PR template to the best of my ability - [X] I've included tests if applicable - [X] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [X] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes recipient validation and submission gating so some address errors become acknowledgeable, which can affect when transactions are allowed to proceed. Also adds a new confirmation alert source and metrics mapping; incorrect classification could lead to missed warnings or unintended sends. > > **Overview** > Users can now proceed when the recipient is detected as a token/smart-contract address by acknowledging a new `SendAlertModal`, instead of being hard-blocked at the recipient step. > > This introduces an *acknowledgeable* validation state (`toAddressErrorAllowAcknowledge`) from `useToAddressValidation`/`validateHexAddress`, adds a new confirmation-page warning via `useTokenContractAlert` (`AlertKeys.TokenContractAddress`), and wires the new alert key into confirmation alert metrics/name resolution. Tests and i18n strings were updated/added to cover the modal flow and the new alert behavior. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit fa22e95. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…26353) <!-- 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** Removes legacy cancel/speed-up code and consolidates on the single `CancelSpeedupModal` flow. This includes dropping unused EIP-1559 modal state and deleting legacy confirmation components that are no longer used. ## Motivation - The cancel/speed-up flow now uses only `CancelSpeedupModal` (with `useCancelSpeedupGas`). The previous EIP-1559–specific modal state (`speedUp1559IsOpen`, `cancel1559IsOpen`) was never set to `true` and only reset to `false`, so it was dead code. - Legacy confirmation components (`EditGasFee1559Update`, `EditGasFeeLegacyUpdate`, `UpdateEIP1559Tx`) have been superseded by the unified cancel/speed-up flow and are no longer referenced. ## Changes ### Legacy state cleanup - **`useUnifiedTxActions`**: Removed `speedUp1559IsOpen` and `cancel1559IsOpen` state, their setters in open/close/error paths, and from the hook’s return value. Only `speedUpIsOpen` and `cancelIsOpen` are used with `CancelSpeedupModal`. - **`Transactions/index.js`**: Removed `speedUp1559IsOpen` and `cancel1559IsOpen` from component state and from all `setState` calls in `onSpeedUpCompleted`, `onCancelCompleted`, and the speed-up/cancel failure handlers. - **Tests**: Updated `useUnifiedTxActions.test.ts`, `UnifiedTransactionsView.test.tsx`, and `Transactions/index.test.tsx` to drop assertions and mocks for the removed 1559 modal state. ### Legacy component removal - **Deleted** `app/components/Views/confirmations/legacy/components/EditGasFee1559Update/` (index, styles, types). - **Deleted** `app/components/Views/confirmations/legacy/components/EditGasFeeLegacyUpdate/` (component, styles, types, test, snapshot). - **Deleted** `app/components/Views/confirmations/legacy/components/UpdateEIP1559Tx/` (index, types). Cancel/speed-up is now handled solely by `CancelSpeedupModal` in both `UnifiedTransactionsView` and the legacy `Transactions` list. Manual: open Activity, trigger Speed up or Cancel on a pending transaction and confirm the modal and flow behave as before. <!-- 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: MetaMask/mobile-planning#2411 ## **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** [test speed up.webm](https://github.com/user-attachments/assets/446714f1-5a00-4610-bfda-7daa8d935c12) [test-cancel.webm](https://github.com/user-attachments/assets/12b1e62a-cc56-4f15-997c-eadee620f771) <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches the speed-up/cancel transaction flow by removing legacy UI/components and slightly refactoring param handling; regressions would affect replacing pending transactions if any removed paths were still reachable. > > **Overview** > Removes the deprecated legacy gas-edit components and snapshots for speed-up/cancel flows (including `EditGasFee1559`, `EditGasFeeLegacy`, `EditGasFee*Update`, and `UpdateEIP1559Tx`), consolidating on the single `CancelSpeedupModal`-based path. > > Cleans up related code and tests by dropping now-unused mocks/state and minor refactoring in `useUnifiedTxActions` to compute gas params once before dispatching speed-up/cancel actions. Also fixes formatting in `docs/readme/deeplinking.md` by converting an admonition block into plain blockquoted lines. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit c46bdd8. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…SS (Part 1) (#26673) ## **Description** Replace StyleSheet.create() and raw View/Text components with design-system-react-native Box/Text and useTailwind() in Onboarding, OnboardingSheet, OnboardingSuccess, and OnboardingSuccessEndAnimation. Delete the now-unused .styles.ts files. Part 1 of 2. Part 2 will cover ImportFromSecretRecoveryPhrase and ImportNewSecretRecoveryPhrase. ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: [TO-555 - Migrate Onboarding screen to Design System (Box/Text + Tailwind)](https://consensyssoftware.atlassian.net/browse/TO-555) Refs: [TO-556 - Migrate OnboardingSuccess screen to Design System (Box/Text + Tailwind)](https://consensyssoftware.atlassian.net/browse/TO-556) Refs: [TO-557 - Migrate OnboardingSuccessEndAnimation to Design System (Box/Text + Tailwind)](https://consensyssoftware.atlassian.net/browse/TO-557) ## **Manual testing steps** No functional changes. Visual regression only — verify onboarding screens render correctly. ```gherkin Feature: Onboarding screens styling Scenario: user views onboarding screens Given app is freshly installed When user launches the app and reaches onboarding Then all onboarding screens render identically to before ``` ## **Screenshots/Recordings** Before (left) vs After (right) <img width="500" height="1053" alt="Screenshot 2026-03-04 at 7 02 57 PM" src="https://github.com/user-attachments/assets/9da681a1-75c9-428e-b0d7-830d43bb6797" /> <img width="500" height="1041" alt="Screenshot 2026-03-04 at 7 06 40 PM" src="https://github.com/user-attachments/assets/7c74f068-0fb2-4d75-bde9-e731229703c8" /> <img width="500" height="1007" alt="Screenshot 2026-03-04 at 7 40 13 PM" src="https://github.com/user-attachments/assets/ff427500-8f99-459d-8a24-7ab9b5becd4b" /> ## **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. Made with [Cursor](https://cursor.com) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Mostly a UI refactor, but it touches the onboarding entry flow (CTA buttons, loading overlay, and success notification padding/animation), so layout/interaction regressions are possible across device sizes. > > **Overview** > Migrates `Onboarding`, `OnboardingSheet`, and `OnboardingSuccessEndAnimation` from `StyleSheet`/raw `View`/custom component-library buttons to `@metamask/design-system-react-native` (`Box`, `Button`, `Text`, `TextButton`) styled via `useTailwind()`, and deletes the now-unused styles files. > > Updates onboarding UI behavior/styling to be device-aware in Tailwind (medium-device CTA spacing/button size, iPhoneX vs non-iPhoneX notification padding) and adds a cleanup for the notification hide timer on unmount. > > Expands unit tests and snapshots to cover the new responsive styling, the loading overlay message, iPhoneX notification padding variants, and safe handling when `OnboardingSheet` route params are `undefined`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 792bfdf. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
#26783) ## **Description** On iOS, the Ledger connect illustration was cut off when opening the Ledger flow after the keyboard had been shown (e.g. search in Explore, then back). Removed `overflow: 'visible'` from the cover image style so the layout no longer gets clipped. Also fixed a typo in LedgerSelectAccount: `style-=` → `style=` so the selector container gets its styles. ## **Changelog** CHANGELOG entry: Fixed Ledger connect screen image being cut off on iOS after using the keyboard. ## **Related issues** Fixes: #25760 ## **Manual testing steps** Feature: Ledger connect screen Scenario: user opens Ledger connect after using keyboard Given the app is open and user has been to Explore and opened the search keyboard then navigated back When user starts connecting a Ledger device Then the Ledger connect illustration is fully visible (not cut off) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk, UI-only style tweaks plus a snapshot update; potential impact is limited to Ledger connect/select-account screen layout across devices. > > **Overview** > Prevents the Ledger connect illustration from being clipped (notably on iOS after keyboard interactions) by removing `overflow: 'visible'` from the `LedgerConnect` cover image styling, and updates the Jest snapshot accordingly. > > Adjusts `LedgerSelectAccount` layout by removing `flex: 1` from `selectorContainer` to ensure the selector section sizes/positions correctly. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit d6b0203. 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>
…7478) <!-- 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 a GitHub Actions workflow to accept an optional dispatch input and pass it through with a safe default <!-- 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 - [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] > **Low Risk** > Low risk: only updates a GitHub Actions workflow to accept an optional dispatch input and pass it through with a safe default, without touching application code. > > **Overview** > Adds a `workflow_dispatch` input (`lookback-days`, default `1`) to the Post Merge Validation GitHub Actions workflow. > > Passes this value through to the `MetaMask/github-tools` `post-merge-validation@v1` action (falling back to `1` when not provided) to control how far back the workflow searches for PRs. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit a214512. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…ests (#27473) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** **Reason for change:** In the Cash section (homepage), the "Claim bonus" CTA was shown even when the claimable mUSD bonus was less than $0.01 (e.g. dust after claiming). Small amounts like 0.007401 were also displayed as "0.01" because the formatting logic rounded to 2 decimals instead of showing "< 0.01". **Improvement / solution:** 1. **MusdAggregatedRow (Cash section):** Only show the "Claim bonus" button when the claimable reward is at least $0.01. Introduced `MIN_CLAIMABLE_BONUS_USD` and `isClaimableBonusAboveThreshold(reward)`; below that threshold the row shows the static "3% bonus" text instead of the CTA. 2. **useMerklRewards:** Removed use of `renderFromTokenMinimalUnit`, which only treated values below 0.00001 as "< 0.00001" and rounded everything else (e.g. 0.007401 → "0.01"). The hook now computes the decimal value as `unclaimedBaseUnits / 10^tokenDecimals` and formats it as `"< 0.01"` when < 0.01, otherwise `toFixed(2)`. This ensures amounts like 0.007401 display as "< 0.01" and the Cash section threshold logic works correctly. 3. **Tests:** MusdAggregatedRow tests for the claimable-bonus threshold (hide CTA for "< 0.01", "0.01", "0.005"; show for "0.02"). useMerklRewards tests updated to assert outcomes instead of mocking `renderFromTokenMinimalUnit`; added case for 7401 with 6 decimals → "< 0.01". ## **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 Cash section showing "Claim bonus" for amounts under $0.01 and corrected display of small claimable amounts as "< 0.01" ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MUSD-513 ## **Manual testing steps** ```gherkin Feature: Cash section claim bonus threshold and small-amount display Scenario: Claim bonus CTA hidden when claimable amount is below $0.01 Given I am on the Wallet home screen with the Cash section visible And my claimable mUSD bonus is less than $0.01 (e.g. dust after claiming) When I view the mUSD row in the Cash section Then I should see "3% bonus" (green text) instead of "Claim bonus" And I should not see a tappable "Claim bonus" link Scenario: Claim bonus CTA shown when claimable amount is at least $0.01 Given I am on the Wallet home screen with the Cash section visible And my claimable mUSD bonus is at least $0.01 When I view the mUSD row in the Cash section Then I should see the "Claim bonus" link And tapping it should start the claim flow ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** https://github.com/user-attachments/assets/ec20c986-1694-4f45-9e8b-4bb9eaed36d0 <!-- [screenshots/recordings] --> ### **After** <img width="391" height="845" alt="Screenshot 2026-03-16 at 09 07 21" src="https://github.com/user-attachments/assets/797d36f7-bf62-47e6-a544-299becef83b0" /> <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes reward amount formatting and CTA gating logic in the Cash section; incorrect numeric conversion/rounding (notably `BigInt`→`Number`) could mis-display large rewards or edge-case decimals. > > **Overview** > **Fixes dust claim UX in the Cash section.** `MusdAggregatedRow` now only shows the **"Claim bonus"** CTA when the claimable bonus is at least `$0.01`; otherwise it shows the static **"3% bonus"** label (including when the hook returns `"< 0.01"`). > > **Simplifies Merkl claimable reward formatting.** `useMerklRewards` drops `renderFromTokenMinimalUnit` and instead computes the decimal amount directly from base units, returning `"< 0.01"` for anything below `$0.01` and `toFixed(2)` otherwise. > > **Tests updated/added.** Merkl reward tests no longer mock the formatter and add coverage for sub-$0.01 amounts (including cases that previously rounded up), and Cash row tests cover the new $0.01 CTA threshold behavior. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 1054f6f. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
… view support and update event tracking locations (#27415) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** The `mUSD Conversion CTA Clicked` event in `CashGetMusdEmptyState` always sent `location: 'home_cash_section'`, even when the CTA was tapped from the full Cash token list page. This PR adds a new `MOBILE_TOKEN_LIST_PAGE` event location and an `isFullView` prop to `CashGetMusdEmptyState` so the full-page context is reported correctly, while the homepage default (`home_cash_section`) remains unchanged: - **`CashGetMusdEmptyState`** — accepts `isFullView`; sends `mobile-token-list-page` when true, keeps `home_cash_section` otherwise. - **`CashTokensFullView`** — passes `isFullView` to `CashGetMusdEmptyState`. ## **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/TMCU-560 ## **Manual testing steps** ```gherkin Feature: mUSD Conversion CTA location tracking in Cash section Scenario: CTA clicked on homepage Cash section keeps home_cash_section location Given the user is on the wallet homepage with mUSD conversion enabled And the user has no mUSD balance (Cash empty state is shown) When user taps the "Get mUSD" button in the Cash section Then the mUSD Conversion CTA Clicked event fires with location "home_cash_section" Scenario: CTA clicked on full Cash token list page sends mobile-token-list-page location Given the user navigates to the full Cash token list page (via ">" from homepage Cash section) And the user has no mUSD balance (Cash empty state is shown) When user taps the "Get mUSD" button Then the mUSD Conversion CTA Clicked event fires with location "mobile-token-list-page" ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: limited to analytics metadata and a new optional prop wiring for `CashGetMusdEmptyState`, with updated unit coverage. > > **Overview** > Updates mUSD conversion CTA analytics so the `MUSD_CONVERSION_CTA_CLICKED` event reports the correct `location` when triggered from the full Cash token list page. > > Adds `EVENT_LOCATIONS.MOBILE_TOKEN_LIST_PAGE` and an `isFullView` prop to `CashGetMusdEmptyState`, passes it from `CashTokensFullView`, and extends tests to cover both homepage (`home_cash_section`) and full-view tracking. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 720ef20. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…27475) <!-- 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? --> Removes background on the "+" icon in the new Network management view. ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: Remove background from Additional Networks in Network Management ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TMCU-521 ## **Manual testing steps** ```gherkin Feature: Network management Scenario: user can access network management and sees updated additional network icons Given the app is opened and the user is logged in When the user goes to Account Menu and opens Networks Then the Networks management screen is shown And each additional network item shows its icon without a rounded muted background ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <img width="384" height="833" alt="Screenshot 2026-03-16 at 11 27 32" src="https://github.com/user-attachments/assets/cfb05217-da81-4434-9d42-31c4f5fc395a" /> <!-- [screenshots/recordings] --> ### **After** <img width="388" height="837" alt="Screenshot 2026-03-16 at 11 27 41" src="https://github.com/user-attachments/assets/7818cb86-088c-4cb4-af68-a2eb7302192c" /> <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk UI-only change that adjusts styling for the add (+) button with no logic or data flow changes. > > **Overview** > Updates `AdditionalNetworkItem` so the add (+) `Pressable` no longer renders with a muted rounded background, leaving only sizing/alignment and pressed opacity styling. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit c27272c. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** We have a few areas in the app that perform fetch requests outside of the engine, by using `core` services. Some examples: - Perps - Predict - Explore This PR adds the `nock` mock API requests library that we use for unit tests in `MetaMask/core` and `MetaMask/metamask-extension`. - It allows us to strictly mock API calls and not the whole core service, for more realistic integration tests. ## **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: test: CV - add `nock` and cleanup Trending CV services mocks ## **Related issues** Fixes: #26270 https://consensyssoftware.atlassian.net/browse/ASSETS-2734 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Test-only changes that swap service-function mocking for HTTP interception; risk is limited to potential flakiness/over-blocking of network calls in view tests if nock isn’t cleaned up correctly. > > **Overview** > Switches Trending component-view tests from mocking `@metamask/assets-controllers` (`getTrendingTokens`) to mocking the actual trending HTTP endpoint via **`nock`**, making the tests exercise the real fetch path. > > Updates `tests/component-view/mocks/trendingApiMocks.ts` to define nock-based helpers (including optional per-request reply logic for chain filtering), adds `nock` to `devDependencies`, and simplifies the Trending view tests accordingly (removing `itForPlatforms`/controller mocks and using request-URL-based responses for the BNB filter case). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit fc3106d. 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.71.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.71.0
<!--
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**
NFT images in the grid had no loading indicator — the cell would appear
empty until the image finished loading. This PR adds a skeleton overlay
that shows immediately when an NFT item has an image URL, then
disappears once the image loads or fails.
**Changes:**
- `NftGridItem`: Tracks a local `isImageLoading` state (true when
`item.image` or `item.imageOriginal` is set). Renders a `Skeleton`
overlay on the image cell until `onLoad` fires. Resets correctly when
the item changes.
- `CollectibleMedia` + `CollectibleMedia.types`: Adds an `onLoad` prop
wired through to `RemoteImage`. Also calls it in the error fallback so
the skeleton always clears even when an image fails to load.
- `RemoteImage`: Adds an `onLoad` prop called from the internal
`onImageLoad` handler. Adds `recyclingKey={uri}` to expo-image `Image`
components so cached images are reused correctly when URIs change.
- `NftGrid`: Improves `keyExtractor` from an array-index key to a stable
`${chainId}-${address}-${tokenId}` key, preventing unnecessary
re-renders when the list updates.
## **Changelog**
CHANGELOG entry: Added skeleton loading indicator to NFT grid items
while images are loading
## **Related issues**
Fixes: https://consensyssoftware.atlassian.net/browse/ASSETS-2903
## **Manual testing steps**
```gherkin
Feature: NFT grid skeleton loading
Scenario: user views the NFT grid while images load
Given the user has NFTs in their wallet
When the user navigates to the NFT grid
Then a skeleton placeholder is visible on each NFT cell while the image loads
And the skeleton disappears once the image finishes loading
Scenario: user views an NFT whose image fails to load
Given the user has an NFT with an unreachable image URL
When the NFT grid renders that item
Then the skeleton disappears even though no image is shown
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
https://github.com/user-attachments/assets/00107c9f-5d61-4a2c-89fb-5e46bf442756
<!-- [screenshots/recordings] -->
### **After**
https://github.com/user-attachments/assets/9d690211-1ebd-40a8-b7a8-4b8782bbeb93
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Touches NFT grid rendering by adding loading state/skeleton overlays
and changing list keys, which can affect perceived UI behavior and item
reuse. Also propagates new `onLoad` callbacks through image components,
so regressions would mainly be around image lifecycle events and
re-rendering.
>
> **Overview**
> Adds a **skeleton loading overlay** to `NftGridItem` that shows when
an NFT has an image (and media display is enabled) and hides when the
underlying media reports `onLoad`.
>
> Threads a new `onLoad` callback through `CollectibleMedia` →
`RemoteImage`, and ensures the callback also fires on image error
fallback so the skeleton clears even when an image fails. `RemoteImage`
now sets `recyclingKey={uri}` on `expo-image` instances and invokes the
new `onLoad` prop from its internal load handler.
>
> Updates `NftGrid` to use a stable `keyExtractor`
(`chainId-address-tokenId`) instead of index keys, and adds/updates unit
tests covering the new `onLoad` behavior and skeleton visibility.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
e382cc8. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
….70.0 (#27459) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** Updates the Explore (Trending) tab icon in the main tab bar from the filled variant to the outline variant. ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: Updated Explore tab icon in the main tab bar to use the outline style. ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-578 ## **Manual testing steps** ```gherkin Feature: Explore tab icon in tab bar Scenario: Explore tab shows outline search icon Given the app is open and the user is on any main tab When the user views the tab bar Then the Explore (Trending) tab shows the outline search icon (not the filled variant) And the icon is visible and correctly aligned with other tab icons ``` ## **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/e9d96e13-1420-4db6-8353-3de9fd0b06a9 <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk visual-only change that swaps the selected-state icon for the Explore/Trending tab; no navigation, analytics, or data flows are affected. > > **Overview** > Updates the TabBar selected-state icon mapping for the Explore/Trending tab to use the outline `IconName.Search` instead of the filled `IconName.SearchFilled`, reverting its “active” appearance to match the outline style. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 829d018. 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 refines the main action buttons to match the design specs.
Update the vertical padding from `16px` > `12px` to improve the spacing.
## **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**
### **After**
<img width="1442" height="562" alt="Screenshot 2026-03-11 at 7 43 58 PM"
src="https://github.com/user-attachments/assets/9adf2473-7c9d-4d2d-acca-b65df3284398"
/>
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk visual-only spacing change that updates styles and
corresponding Jest snapshots without altering behavior or data flow.
>
> **Overview**
> Polishes `MainActionButton` spacing by reducing `paddingVertical` from
`16` to `12` in `MainActionButton.styles.ts` to better match design
specs.
>
> Updates Jest snapshots for `MainActionButton` and screens that render
it (e.g., `AccountsMenu` scan button and `AssetDetailsActions` buttons)
to reflect the new padding.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0950cef. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
….1 cp-7.70.0 (#27446) <!-- 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** Standardizes safe area and header inset behavior across the main tab views (Wallet, Explore, Activity, Rewards). 1. **Reason for the change:** These views used `edges={{ bottom: 'additive' }}` on `SafeAreaView` and `includesTopInset` on headers, which was inconsistent with the desired layout and could cause double insets or incorrect safe area handling. 2. **Improvement:** Switched to `edges={{ top: 'additive' }}` on `SafeAreaView` and removed `includesTopInset` from header components so the top safe area is handled by the screen container and headers align consistently. ## **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: #27443 ## **Manual testing steps** ```gherkin Feature: Safe area and header insets on main tabs Scenario: Wallet, Explore, Activity, and Rewards use consistent safe area Given the app is open on a device or simulator with a notch/safe area When the user switches to each main tab (Wallet, Explore, Activity, Rewards) Then the top safe area is applied by the screen (no double inset) And the header (title + accessories) aligns correctly below the safe area And the bottom of each view respects the tab bar / device safe area as before ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** https://github.com/user-attachments/assets/0eda5978-7bd5-4428-86ea-f62637fb06ed <!-- [screenshots/recordings] --> ### **After** https://github.com/user-attachments/assets/a8ff8e19-a49e-41f4-9056-7c2271da8c66 <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Layout-only changes to core tab screens (Wallet/Explore/Activity/Rewards) that can affect safe-area padding and scroll behavior across devices, plus removal of Wallet’s bottom fade/scroll tracking logic which could subtly change UX on the homepage. > > **Overview** > Standardizes safe-area handling across the main tab views by switching root `SafeAreaView` usage from `edges={{ bottom: 'additive' }}` to `edges={{ top: 'additive' }}` and removing header `includesTopInset` so the top inset is applied consistently by the screen container. > > In `Wallet`, removes the bottom fade `LinearGradient` overlay and its associated scroll/size tracking state, simplifying scroll handling to just notify homepage section subscribers via `handleHomepageScroll`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit c4b0e41. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
chloeYue
previously approved these changes
Mar 27, 2026
…27708) Made-with: Cursor
…27708) (#28016) ## Description Merges `stable` into `release/7.71.0` and resolves `CHANGELOG.md` conflicts so [PR #27708](#27708) (`release/7.71.0` → `stable`) can merge cleanly. ### CHANGELOG resolution (per local release changelog guidelines) - Kept **`## [7.71.0]`** (cleaned release notes) **above** **`## [7.70.1]`** / **`## [7.70.0]`** from stable. - **Compare links:** `[Unreleased]` → `v7.71.0...HEAD`; `[7.71.0]` → `v7.70.1...v7.71.0`; left `[7.70.1]` / `[7.70.0]` lines unchanged below. ### After this PR 1. Merge this PR into `release/7.71.0` using **Create a merge commit** (not squash), per release process. 2. Re-try / update [PR #27708](#27708). ## Changelog CHANGELOG entry: null --- Made with [Cursor](https://cursor.com) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: merge-conflict resolution focused on `CHANGELOG.md` ordering/compare links with no runtime code changes. > > **Overview** > Merges `stable` into `release/7.71.0` and resolves the `CHANGELOG.md` conflict by keeping the cleaned `7.71.0` notes above `7.70.1`/`7.70.0` and updating the compare links (`[Unreleased]` → `v7.71.0...HEAD`, `[7.71.0]` → `v7.70.1...v7.71.0`). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 424324a. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
Contributor
🔍 Smart E2E Test Selection⏭️ Smart E2E selection skipped - base branch is not main or a release branch (base: stable) All E2E tests pre-selected. |
|
Contributor
|
✅ E2E Fixture Validation — Schema is up to date |
chloeYue
approved these changes
Mar 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



🚀 v7.71.0 Testing & Release Quality Process
Hi Team,
As part of our new MetaMask Release Quality Process, here’s a quick overview of the key processes, testing strategies, and milestones to ensure a smooth and high-quality deployment.
📋 Key Processes
Testing Strategy
Conduct regression and exploratory testing for your functional areas, including automated and manual tests for critical workflows.
Focus on exploratory testing across the wallet, prioritize high-impact areas, and triage any Sentry errors found during testing.
Validate new functionalities and provide feedback to support release monitoring.
GitHub Signoff
Issue Resolution
Cherry-Picking Criteria
🗓️ Timeline and Milestones
✅ Signoff Checklist
Each team is responsible for signing off via GitHub. Use the checkbox below to track signoff completion:
Team sign-off checklist
This process is a major step forward in ensuring release stability and quality. Let’s stay aligned and make this release a success! 🚀
Feel free to reach out if you have questions or need clarification.
Many thanks in advance
Reference