release: 7.79.00 (OTA)#28758
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**
Navigation screens were using the default (unthemed) card background
color, which could cause a visible flash of incorrect color during
screen transitions — particularly noticeable when switching between dark
and light themes.
This PR applies `cardStyle: { backgroundColor: colors.background.default
}` to multiple navigators and individual screens across the app,
ensuring that the background color used during transitions always
matches the current theme.
Several arrow-function navigator components were converted from implicit
returns to explicit function bodies so they can call the `useTheme()`
hook and access `colors`.
## **Changelog**
CHANGELOG entry: Fixed navigation screens flashing incorrect background
color during transitions
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: Navigation background color matches theme
Scenario: user navigates between screens in dark mode
Given the app is in dark mode
When user navigates to Settings or Onboarding Default Settings
Then the screen transition background matches the dark theme background
And no white flash is visible during the transition
Scenario: user navigates between screens in light mode
Given the app is in light mode
When user navigates to Settings or Onboarding Default Settings
Then the screen transition background matches the light theme background
And no dark flash is visible during the transition
Scenario: user opens multichain address list
Given the user is on the accounts screen
When user taps to open the multichain address list
Then the screen slides in from the right with the correct themed background
```
## **Screenshots/Recordings**
### **Before**
https://github.com/user-attachments/assets/7bf229d2-9b9c-4320-88b4-f2672193b804
### **After**
https://github.com/user-attachments/assets/b29c42e3-8f74-4741-8d85-5226f630fa38
https://github.com/user-attachments/assets/20a48c50-6f21-4c5d-ac63-547a793db9d1
## **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.
<!-- Generated with the help of the pr-description AI skill -->
Made with [Cursor](https://cursor.com)
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Touches multiple React Navigation stacks and screen options, which can
subtly affect transition behavior and modal presentation across the app,
though changes are mostly cosmetic (themed background only).
Added/updated tests reduce risk but they are extensive and may be
brittle.
>
> **Overview**
> Fixes navigation transition flashes by applying themed
`cardStyle`/`headerStyle` background colors (via `useTheme()`) across
several navigators and key screens (onboarding success/default settings,
hardware wallet flows, settings/main stacks, and multichain address list
slide-in).
>
> Refactors several navigator components from implicit returns to
function bodies to access theme colors, and updates/expands navigation
tests and snapshots to cover version-handling branches, tracing calls,
conditional routing, and rendering of many nested navigators/modals.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
56fc9f9. 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 isolates the websocket follow-up from `#28176`. The root issue is that Perps always-on moved HyperLiquid websocket initialization into wallet lifecycle paths, and foreground return was still forcing full reconnects even when the socket was already healthy. That inflated non-interactive websocket handshakes and turned some startup/foreground failures into hard Perps errors. This change keeps always-on enabled, but makes wallet-root and tutorial preloads best-effort. Foreground resume now validates the existing socket before reconnecting, full-screen Perps entry still forces an interactive reconnect when needed, and suppressed startup attempts stop logging hard initialization errors to Sentry. ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: Fixed a bug that caused Perps to reconnect too aggressively and surface intermittent websocket connection errors. ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TAT-2759 ## **Manual testing steps** ```gherkin Feature: perps always-on websocket lifecycle Scenario: wallet lifecycle keeps a healthy websocket alive Given Perps is enabled for the current wallet When the user backgrounds the app briefly and returns to the wallet Then the always-on connection should reuse a healthy websocket instead of forcing a full reconnect Scenario: entering Perps recovers after a silent startup failure Given a non-interactive always-on websocket initialization fails during wallet startup When the user opens the full-screen Perps experience Then the app should attempt an interactive reconnect and load Perps without showing a stale startup error ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- Generated with the help of the pr-description AI skill --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches Perps WebSocket lifecycle and error-suppression behavior; mistakes could cause missed reconnects or hidden connection failures, but changes are localized and covered by expanded unit tests. > > **Overview** > Reduces aggressive Perps WebSocket reconnections by introducing `PERPS_CONNECTION_SOURCE` + `suppressError` options and a new `PerpsConnectionManager.resumeFromForeground()` that pings a healthy socket before forcing a full reconnect. > > Wallet-root always-on and tutorial preload connections are now *best-effort* (silent on failure with delayed retry), while full-screen Perps entry proactively calls `ensureConnected()` when disconnected and not showing an error view. > > Adds a per-attempt context (`perpsConnectionAttemptContext`) to thread `source`/`suppressError` into provider initialization and downgrades suppressed startup failures (e.g., HyperLiquid init) from Sentry errors to debug logs; also dedupes Sentry breadcrumbs for repeated error codes. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit c647313. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…lLoginIosUser (#28333) ## **Description** Fixes the `SocialLoginIosUser` screen to properly use the theme background color and center-align the title text. Current dark mode it appears white and hardly legible ### Key changes - Added `backgroundColor: colors.background.default` to `SafeAreaView` wrapper and root `View` so the screen respects the current theme - Added `textAlign: 'center'` to the title `Text` via a stylesheet constant (avoids inline style lint violation) ## **Changelog** CHANGELOG entry: null ## **Related issues** N/A ## **Manual testing steps** ```gherkin Feature: SocialLoginIosUser screen theming Scenario: New social login user sees themed background Given user completes social login on iOS as a new user When the success screen is shown Then the background matches the current theme color And the title text is centered Scenario: Existing social login user sees themed background Given user completes social login on iOS as an existing user When the success screen is shown Then the background matches the current theme color And the title text is centered ``` ## **Screenshots/Recordings** ### **Before** <img width="300" height="2622" alt="image" src="https://github.com/user-attachments/assets/4d359463-be0c-45d7-aae7-c925c386d44e" /> ### **After** <img width="300" height="2622" alt="Simulator Screenshot - iPhone 17 - 2026-04-02 at 18 09 45" src="https://github.com/user-attachments/assets/b8428bbc-985e-494f-a1b7-1c960eeabb5c" /> ## **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** > Low risk UI-only changes limited to styling and theming on a single onboarding screen, plus snapshot updates. > > **Overview** > Ensures the `SocialLoginIosUser` success screen respects the active theme by applying `colors.background.default` to the `SafeAreaView` wrapper and root container. > > Centers the title text via a new `styles.title` rule, and updates Jest snapshots to reflect the new background style arrays and `textAlign: 'center'`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 479288b. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…28267) ## **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? --> The Ramp BUY and SELL screens in `MainNavigator.js` were missing `cardStyle` with `backgroundColor`, causing the navigation card to use React Navigation's default white background. This made the header (top safe area) and footer (bottom safe area) appear white in dark mode. Other screens in the same navigator (Send, Bridge, Browser, etc.) already set `cardStyle: { backgroundColor: colors.background.default }`. This PR applies the same pattern to the Ramp screens for consistency. ## **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 white header and footer on Ramp buy/sell screens in dark mode ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: Ramp buy screen dark mode theming Scenario: user opens Buy crypto from Perps with dark mode enabled Given the app is set to dark mode And the user is on the Perps home screen with zero balance When user taps "Add funds" And user taps "Buy crypto" Then the Ramp buy screen header and footer use the dark theme background color And there are no white areas at the top or bottom of the screen ``` ## **Screenshots/Recordings** ### **Before** <img width="1179" height="2556" alt="Simulator Screenshot - iPhone 15 Pro - 2026-04-01 at 09 26 16" src="https://github.com/user-attachments/assets/83c59cdb-c2b7-48e7-b982-15ac10db8cdf" /> ### **After** <img width="1179" height="2556" alt="Simulator Screenshot - iPhone 15 Pro - 2026-04-01 at 09 23 38" src="https://github.com/user-attachments/assets/6467aa48-8c1e-4157-aabd-9950ec3a015e" /> ## **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. <!-- Generated with the help of the pr-description AI skill --> Made with [Cursor](https://cursor.com) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk UI-only navigation styling change that should not affect Ramp flow logic; primary risk is unintended background color differences on the Ramp screens across themes. > > **Overview** > Fixes Ramp `BUY`/`SELL` screens in `MainNavigator` to use the app theme background by adding `options.cardStyle.backgroundColor = colors.background.default` on those stack screens, preventing white safe-area/header/footer regions in dark mode. > > Updates the `MainNavigator` Jest snapshots to reflect the new per-screen `options` for `RampBuy` and `RampSell`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 11ad411. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…/misc (#28185) ## **Description** Migrate 5 RootModalFlow security/misc components from prop-based route access to `useRoute()` hook (PR 9 of 13). **Components:** SRPQuiz, OriginSpamModal, ChangeInSimulationModal, LearnMoreBottomSheet, ReturnToAppNotification ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** N/A — pure refactoring. All existing tests pass. ## **Screenshots/Recordings** ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. Made with [Cursor](https://cursor.com) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk refactor limited to navigation param plumbing and test updates; behavior should be unchanged aside from stricter typing and slightly different test rendering expectations. > > **Overview** > Refactors several RootModalFlow security/misc screens (`SRPQuiz`, `OriginSpamModal`, `ChangeInSimulationModal`, `ReturnToAppNotification`) to read navigation params via `useRoute()` instead of prop-injected `route`, and removes the `as ScreenComponent` casts for these routes in `App.tsx`. > > Makes `LearnMoreBottomSheet`’s `onClose` prop optional and updates affected unit tests to mock `useRoute()` rather than passing `route` props; `ReturnToAppNotification` tests were expanded from a snapshot to detailed assertions around toast display, delays (`wait`), and one-time execution. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit fc3d334. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…28335) <!-- 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 sets the Carousel mocks to false on the network manager spec in order to improve token visibility. Some urls were also removed from the allow list since they have been mocked previously <!-- 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://consensys.slack.com/archives/C02U025CVU4/p1775117808791299 ## **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] > **Low Risk** > Low risk: changes are limited to E2E/smoke test setup and allowlist cleanup, with no production runtime logic touched. > > **Overview** > Stabilizes smoke tests by forcing remote feature flags to disable `carouselBanners` in `network-manager2.spec.ts`, ensuring banner UI doesn’t obscure token visibility during network filtering checks. > > Cleans up E2E request allowlisting by removing now-mocked endpoints from `mock-e2e-allowlist.ts`, and adds a small workaround in the gasless swap 7702 smoke test to dismiss a sticky keyboard via a tap on `QuoteView.networkFeeLabel`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit f1d0068. 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** > **Migrates performance testing from `appwright` to `playwright` and modernizes the Playwright/Appium test harness.** The GitHub workflow and `package.json` scripts are switched to `run-playwright:*`, and several performance specs are rewritten from legacy WDIO screen-objects to new page-objects/flows. > > **Adds new Playwright fixtures and utilities for performance runs.** A `currentDeviceDetails` fixture is introduced, plus a `performanceTracker` fixture that auto-attaches metrics post-test, validates quality gates (skipping retries after threshold-only failures), publishes scenarios to Sentry, and stores session metadata. > > **Improves Appium interaction reliability and provider integration.** Playwright matchers/gestures gain stability-aware `waitAndTap`, better text/XPath handling, app lifecycle helpers (terminate/activate/background/hide keyboard), standardized default timeouts, and BrowserStack/emulator capability updates including per-platform app identifiers and a provider `getRecordingUrl` for video links. > > **Updates test IDs and selectors used by E2E.** Predict market details testIDs are normalized (tab vs tab-content), and confirmations add a `KEYBOARD_CONTAINER` id with corresponding page-object updates. > ## **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-1454 ## **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** > Broad changes across the E2E/performance harness (fixtures, matchers/gestures, BrowserStack capabilities, and multiple rewritten specs) could introduce new test flakiness or CI/run-time regressions despite being non-production code. > > **Overview** > Migrates BrowserStack performance test execution from `appwright` to `playwright` by switching the GitHub workflow and `package.json` scripts to `run-playwright:*` commands. > > Refactors the Playwright/Appium test harness with **new fixtures** (including `currentDeviceDetails` and an auto-managed `performanceTracker` that attaches metrics, enforces quality gates, and publishes to Sentry), plus reliability improvements to matchers/gestures (stability-aware `waitAndTap`, richer XPath/text handling, app lifecycle helpers, and standardized default timeouts). > > Rewrites several performance specs and page objects to the unified page-object/flow style (wallet/login, swaps, perps), adds a new `perps.flow` helper, and updates/normalizes test IDs used by E2E (Predict market details tab/content IDs and a new confirmations `KEYBOARD_CONTAINER` selector). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 7a072f2. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Christopher Ferreira <christopher.ferreira@consensys.net> Co-authored-by: Christopher Ferreira <104831203+christopherferreira9@users.noreply.github.com> Co-authored-by: Javier Garcia Vera <javier.vera@consensys.net>
## **Description** Mirrors [MetaMask/core#8352](MetaMask/core#8352) for the mobile PerpsController. - Expand `MESSENGER_EXPOSED_METHODS` from 35 to 84 methods (alphabetized) - Auto-generate `PerpsController-method-action-types.ts` using `messenger-generate-action-types` CLI - Export `PerpsControllerGetStateAction` and all individual action types - Add `generate-method-action-types` check/fix scripts to `lint`/`lint:fix` ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: N/A ## **Manual testing steps** N/A — type-only changes, no user-facing behavior ## **Screenshots/Recordings** ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Expands the messenger-exposed surface area of `PerpsController`, which could affect callers and permissions if any method was not intended to be remotely invokable. Also adds a new lint-time codegen check that may introduce CI failures if generation drifts across environments. > > **Overview** > **Exposes the full `PerpsController` API through the messenger** by expanding and alphabetizing `MESSENGER_EXPOSED_METHODS`, and introduces a named `PerpsControllerGetStateAction` type. > > **Switches Perps messenger action typing to generated output**: `PerpsController-method-action-types.ts` is regenerated to include JSDoc’d action types for all controller methods and `index.ts` now re-exports these individual action types. > > **Build/CI enforcement changes**: bumps `@metamask/messenger` to `^1.1.0` (for the codegen CLI) and wires `messenger-generate-action-types` into `lint`/`lint:fix` via new `generate-method-action-types` scripts to keep generated types in sync. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 0fe513d. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…[GE-168] (#28345) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> Adds Braze Android resource in braze.xml to specify the small and large push notification icons ## **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/GE-168 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: resource-only configuration change that just points Braze to existing mipmap icons; main risk is misconfigured/missing icon resources affecting push rendering. > > **Overview** > Adds Braze Android resource overrides in `braze.xml` to specify the small and large push notification icons (`com_braze_push_small_notification_icon` and `com_braze_push_large_notification_icon`), pointing to `@mipmap/ic_notification_small` and `@mipmap/ic_notification`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 64eef30. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…ated APIs (#28115) ## **Description** Upgraded `@metamask/design-system-react-native` from `^0.11.0` to `^0.12.0` and migrated affected mobile screens to the latest API. This removes deprecated `TextFieldSize` and `TextButtonSize` usage, removes deprecated `TextButton isInverse`, and replaces one icon/disabled `TextButton` usage with a tertiary `Button` per migration guidance. https://github.com/MetaMask/metamask-design-system/releases/tag/v26.0.0 ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: N/A ## **Manual testing steps** ```gherkin Feature: Design system 0.12.0 migration compatibility Scenario: user can authenticate and reset password using migrated text fields Given the app is running on a branch with this PR When user opens Login, Onboarding, Choose Password, and Reset Password flows Then password input fields render correctly and accept input without runtime errors Scenario: user can copy seed phrase only when reveal state allows it Given the user is on the Reveal Secret Recovery Phrase screen When the seed phrase is hidden Then the copy action is disabled When the seed phrase is revealed and user taps copy Then the copy action triggers successfully ``` ## **Screenshots/Recordings** ### **Before** Main fix was alignment of TextField for password type https://github.com/user-attachments/assets/31218d04-876b-4b53-87b3-7349e59416ec ### **After** https://github.com/user-attachments/assets/1623c271-cee3-4d66-aa8c-2c5430ac4990 ## **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 - [ ] 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** > Moderate risk because it upgrades the shared design-system dependency and changes `TextField`/button props in login, password creation/reset, and seed phrase screens, which could cause subtle styling/accessibility regressions in critical authentication flows. > > **Overview** > Upgrades `@metamask/design-system-react-native` to `^0.12.0` (and `design-system-shared` to `^0.5.0`) and updates affected screens to match the new component APIs. > > Removes deprecated `TextFieldSize` usage across `Login`, `ChoosePassword`, `ResetPassword`, `ManualBackupStep1`, and `RevealPrivateCredential` components, and adjusts button APIs by dropping `TextButton` sizing/`isInverse` props and switching the seed-phrase copy action to a tertiary `Button`. > > Updates Jest snapshots to reflect the new `TextField` rendering/styling and accessory layout from the design-system upgrade. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 1780297. 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? --> Migrated `Skeleton` to DSRN usage (confirmations scope). ## **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** https://github.com/user-attachments/assets/33b4a13d-8b50-45e1-95db-5be88e3d50b6 ### **After** https://github.com/user-attachments/assets/26fe026f-9a9b-4cd6-8690-c604bcfd869f ## **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 swaps the `Skeleton` placeholder component import paths in confirmations-related screens and one test mock. Main risk is visual/regression differences if the temp Skeleton behaves differently, but no business logic is altered. > > **Overview** > Migrates confirmations-scope loading placeholders to use the new DSRN `Skeleton` implementation by switching imports from `component-library/components/Skeleton` to `component-library/components-temp/Skeleton` across confirmation rows, footers, keyboards, and related components. > > Updates the send `Recipient` test to mock the new `Skeleton` module path accordingly. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 0922bf9. 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**
The Swaps and Bridge screens were navigating without a slide animation,
creating an abrupt transition that felt inconsistent with the rest of
the app. This PR applies `slideFromRightAnimation` to both screens so
they slide in from the right, matching the smooth navigation pattern
already used by Settings, Asset, Stake, Earn, Perps, and other screens
in `MainNavigator`.
## **Changelog**
CHANGELOG entry: Fixed abrupt navigation transition to Swaps and Bridge
screens by adding smooth slide-from-right animation
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: Smooth navigation transitions
Scenario: user navigates to the Swaps screen
Given the user is on the wallet home screen
When user taps the Swap action button
Then the Swaps screen slides in smoothly from the right
Scenario: user navigates to the Bridge screen
Given the user is on the wallet home screen
When user initiates a Bridge action
Then the Bridge screen slides in smoothly from the right
```
## **Screenshots/Recordings**
### **Before**
https://github.com/user-attachments/assets/4d023c14-1f59-4fec-8a81-01a527e85e42
### **After**
https://github.com/user-attachments/assets/f45809a4-e175-4741-80ef-d496803f31f2
## **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.
<!-- Generated with the help of the pr-description AI skill -->
Made with [Cursor](https://cursor.com)
https://github.com/user-attachments/assets/fcb30371-1684-4cc6-873d-c7c01ea380d5
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk UI-only navigation change that adjusts stack screen
transition options; main risk is unintended animation/gesture behavior
differences on these routes.
>
> **Overview**
> Applies the shared `slideFromRightAnimation` stack transition to the
`Send` and `Bridge` routes in `MainNavigator`, so these screens slide in
consistently with other flows.
>
> Updates the `MainNavigator` Jest snapshot to reflect the new
`animationEnabled` and `cardStyleInterpolator` options on those screens.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
fc1507d. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…n-production builds. (#28311) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** Currently the branch name is only displayed for QA builds (isQa check), leaving RC, beta, and dev builds indistinguishable from production. This PR: - replaces isQa check with !isProduction() to show build info for all non-production builds (RC, beta, dev, etc.) - prepends uppercased METAMASK_ENVIRONMENT as build type label (e.g., RC | Branch: release/7.69.0) - production builds remain unchanged (no branch info displayed) Before: Branch: release/7.69.0 (QA only) After: RC | Branch: release/7.69.0 (all non-production builds) <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MMQA-1559 ## **Manual testing steps** - Verify non-production builds show {ENV} | Branch: {branch} on About screen - Verify production builds do not show branch info - Run unit tests: yarn jest app/components/Views/Settings/AppInformation/index.test.tsx ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk UI-only change that tweaks when/what build metadata is displayed and updates associated Jest tests/snapshots; no runtime behavior changes for production builds beyond hiding this label. > > **Overview** > Updates the About MetaMask (`AppInformation`) screen to show a **build-type label + git branch** (`${METAMASK_ENVIRONMENT.toUpperCase()} | Branch: ...`) for *all non-production builds* by replacing the old `isQa` gate with `!isProduction()`. > > Refreshes tests to mock `isProduction`, adds explicit coverage that production builds do not render branch info, and updates the snapshot accordingly. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 6e63822. 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?
-->
When `BridgeView` stayed in zero-state, tapping into the amount input
and then tapping outside without entering an amount could leave the
keypad open.
This change centralizes keypad dismissal into a shared helper and
restores keypad dismissal for zero-state taps and scroll starts so the
keypad closes correctly even when no amount has been entered.
## **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 the bridge keypad staying open when no amount was
entered
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: Bridge zero-state keypad dismissal
Scenario: user dismisses the keypad with no amount entered
Given I am on the Bridge screen with swaps trending tokens enabled
And I have tapped the source amount input so the keypad is visible
And I have not entered an amount
When user taps or starts scrolling in the content area above the keypad
Then the source input should blur
And the keypad should close
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
N/A
### **After**
N/A
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- Generated with the help of the pr-description AI skill -->
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk UI interaction change limited to blur/close behavior for the
amount input and `SwapsKeypad` in `BridgeView`; potential risk is only
unintended extra dismissals on touch/scroll in zero-state.
>
> **Overview**
> Fixes a zero-state interaction bug in `BridgeView` where the
`SwapsKeypad` could remain open after tapping outside the amount input
when *trending tokens* are shown.
>
> This centralizes input/keypad dismissal into `dismissInputAndKeypad`
and wires it to zero-state touch and scroll gestures
(`onResponderRelease`, `onScrollBeginDrag`, and `onTouchEnd`) using a
shared `shouldShowTrendingTokens` guard.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
32a9d3e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…oute files (#28093) <!-- # PR Title refactor(navigation): deduplicate clearStackNavigatorOptions across route files --> ## **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? --> The `clearStackNavigatorOptions` object was duplicated across 7 route files (Bridge, Card, Ramp, Ramp/Aggregator, Ramp/Deposit, Earn, Stake) with identical definitions. Some used `colors.transparent` while others used the string `'transparent'`, creating an inconsistency. This PR removes all 7 local definitions and replaces them with a single import from `constants/navigation/clearStackNavigatorOptions`, which was introduced earlier in the migration branch. This reduces duplication and ensures consistent navigator options across all feature route stacks. ## **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** N/A — internal refactor with no behavior change. ## **Screenshots/Recordings** ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- Generated with the help of the pr-description AI skill --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches shared React Navigation `screenOptions` used by multiple modal/stack flows; small changes to animation/overlay configuration could subtly affect transition behavior across several screens. > > **Overview** > Deduplicates repeated `clearStackNavigatorOptions` definitions across Bridge/Card/Ramp (incl. Aggregator + Deposit)/Earn/Stake route stacks by importing the shared constant from `constants/navigation/clearStackNavigatorOptions`. > > Updates `MainNavigator` and several modal stacks to use a new exported variant, `clearStackNavigatorOptionsWithTransitionAnimation`, and adds that variant in `clearStackNavigatorOptions.ts` (restoring the overlay `cardStyleInterpolator` while keeping transparent background and animations disabled). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 0a94894. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Nicholas Smith <nick.smith@consensys.net>
…ettings (#28184) ## **Description** Migrate 4 RootModalFlow assets/settings components from prop-based route access to `useRoute()` hook (PR 8 of 13). **Components:** BasicFunctionalityModal, AssetHideConfirmation, AssetOptions, NftOptions ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** N/A — pure refactoring. All 22 existing tests pass. ## **Screenshots/Recordings** ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. Made with [Cursor](https://cursor.com) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk refactor that standardizes React Navigation param access and removes `any`/`ScreenComponent` casts; primary risk is runtime crashes if a modal is opened without expected `route.params`. > > **Overview** > Migrates `BasicFunctionalityModal`, `AssetHideConfirmation`, `AssetOptions`, and `NftOptions` from prop-based `route` access to typed `useRoute()` hooks, allowing `RootModalFlow` to stop casting these screens to `ScreenComponent`. > > Updates and adds tests to mock `useRoute()` params accordingly (including new coverage for `AssetHideConfirmation` and `NftOptions`), without changing the underlying user-facing behavior. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit df5b2b8. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Prithpal Sooriya <prithpal.sooriya@consensys.net>
## **Description** WalletConnect reported 7,818 anomalous relay sessions from MetaMask Mobile. A relay complexity limit takes effect April 15, 2026. Chain change amplification is a major contributor — a single chain switch with 20 sessions generates ~80 relay messages instead of the expected ~40. The root cause is two independent notification paths for chain changes: 1. **Store subscription path**: each `WalletConnect2Session` subscribes to Redux and calls `handleChainChange()` → sends `updateSession` + `emitSessionEvent` (2 messages) 2. **WalletConnectPort path**: `BackgroundBridge` emits `chainChanged` → `WalletConnectPort.postMessage` intercepts and calls `updateSession()` → sends another `updateSession` + `emitSessionEvent` (2 more messages) This PR: - Removes the duplicate WalletConnectPort `chainChanged` forwarding (path 2 above) - Adds a `lastEmittedChainId` dedup guard in `handleChainChange` to prevent sequential duplicates from the `approveRequest` + store subscription race - Captures the `store.subscribe()` unsubscribe function and calls it in `removeListeners()` to prevent leaked subscriptions **Result**: 1 chain switch × 20 sessions = ~40 relay messages (2 per session), down from ~80. ## **Changelog** CHANGELOG entry: Fixed duplicate WalletConnect relay messages when switching chains ## **Related issues** Fixes: [WAPI-1358](https://consensyssoftware.atlassian.net/browse/WAPI-1358) ## **Manual testing steps** ```gherkin Feature: WalletConnect chain change notifications Scenario: dapp requests chain switch Given the user has a dapp connected via WalletConnect on Mainnet When user approves a wallet_switchEthereumChain request from the dapp Then the dapp shows the new chain once (no duplicate notification) Scenario: chain round-trip A to B to A Given the user has a dapp connected via WalletConnect on Mainnet When user switches to Polygon then back to Mainnet Then the dapp reflects Polygon, then Mainnet (both transitions work) Scenario: account change still works Given the user has a dapp connected via WalletConnect When user switches the active account in MetaMask Then the connected dapp receives the account change notification ``` ## **Screenshots/Recordings** ### **Before** <!-- N/A - relay-level change, not visual --> ### **After** <!-- N/A - relay-level change, not visual --> ## **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 - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes the WalletConnect v2 chain-change notification flow by removing Redux store subscription and manual `chainChanged` emissions in `WalletConnect2Session`, which could affect dapp network sync if the remaining BackgroundBridge/Port path misbehaves. Scope is limited to WalletConnect session lifecycle and related tests. > > **Overview** > Reduces WalletConnect v2 chain-change relay noise by removing `WalletConnect2Session`'s Redux `store.subscribe` chain tracking, the internal `handleChainChange`/request caching logic, and the extra `chainChanged` event emission after `switchToChain`. > > Updates tests to drop expectations around store unsubscription and manual chain-change handling, and adds coverage for `WalletConnectPort` reacting to `metamask_chainChanged` notifications (via mocked `AppConstants.NOTIFICATION_NAMES`) by calling `updateSession` with the selected account + parsed chainId. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit a028535. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: jiexi <jiexiluan@gmail.com>
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->
## **Description**
Removes unused code
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: null
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk refactor that removes an unused navbar helper and its tests;
main risk is any remaining external call sites that expected this export
at runtime.
>
> **Overview**
> Removes the legacy `getTransactionsNavbarOptions` helper (and its
`AccountRightButton` dependency) from `Navbar/index.js`.
>
> Cleans up the unit/integration tests in `Navbar/index.test.js` and
`Navbar/index.test.jsx` by deleting the corresponding
`getTransactionsNavbarOptions` test coverage.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
155917c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…ions store (#28290) ## Summary - **Fixes a bug** where `useOriginSource` misclassified all SDKConnectV2 (MWP) connections as `in-app browser`, causing the `source` property on `CONNECT_REQUEST_STARTED`, `CONNECT_REQUEST_COMPLETED`, and `CONNECT_REQUEST_CANCELLED` analytics events to be incorrect for V2 connections. - The hook's existing check for the `MMSDKCONNECTV2::` prefix was dead code — the prefix is stripped by `RPCMethodMiddleware` before it reaches the permission system. V2 connections arrive with a bare UUID as their origin. - Adds a lookup against the `v2Connections` Redux store (already populated by `HostApplicationAdapter.syncConnectionList`) to correctly identify V2/MWP connections and return `SourceType.SDK_CONNECT_V2`. ## Root cause The `RPCBridgeAdapter` constructs `middlewareHostname = MMSDKCONNECTV2::<connId>`, but: 1. `RPCMethodMiddleware.ts` immediately strips the prefix (`hostname.replace(SDK_CONNECT_V2_ORIGIN, '')`) 2. For the CAIP path (`wallet_createSession`), `BackgroundBridge.channelIdOrOrigin` returns the bare `channelId` (UUID) when `isMMSDK=true` 3. The `PermissionController` approval request therefore carries a bare UUID as `metadata.origin` 4. `useOriginSource` couldn't match this UUID to V2 — it only checked the V1 `SDKConnect` store CHANGELOG entry: `null` ## Test plan - [x] Unit tests: 7 passing (2 new V2-specific tests added) - [ ] Manual: Open an MWP deeplink, verify `CONNECT_REQUEST_STARTED` event has `source: 'sdk_connect_v2'` instead of `source: 'in-app browser'` - [ ] Verify no regression for V1 SDK connections (`source: 'sdk'`) - [ ] Verify no regression for WalletConnect connections (`source: 'walletconnect'`) - [ ] Verify no regression for in-app browser connections (`source: 'in-app browser'`) ## Related - Fixes: [WAPI-1380](https://consensyssoftware.atlassian.net/browse/WAPI-1380) - Related PR: #27864 (wallet-side analytics for SDKConnectV2/MWP — this fix reduces the scope of new events needed there) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes the source-classification logic used for connection-request analytics by introducing a new SDK v2 detection path and reordering precedence, which could shift event attribution if the v2Connections store is incomplete or stale. > > **Overview** > Fixes `useOriginSource` to correctly detect **SDK Connect v2 (MWP)** permission origins by treating a *bare UUID* as v2 when it exists in the Redux `sdk.v2Connections` map (instead of relying on a removed/stripped v2 prefix). > > Refactors the hook to use an explicit priority order (**v2 → v1 → WalletConnect → in-app browser**) and adds unit coverage for v2 detection (including the case where the same UUID exists in both v1 and v2, with v2 winning). Tests that build mock Redux `sdk` state were updated to include an empty `v2Connections` field. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 5a7473e. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…con/BannerAlert/Button (#28298) ## **Description** Updates deprecated component docblocks to consistently include links to both the component README and the component-specific migration section in the design-system-react-native migration guide. This aligns `Icon`, `BannerAlert`, and `Button` with the same deprecation guidance format used by `Text`. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: Deprecated component doc links are consistent Scenario: engineer checks deprecation notices Given the component wrapper files for Text, Icon, BannerAlert, and Button When viewing each component JSDoc deprecation block Then each includes a README link and a migration docs link with the component anchor ``` ## **Screenshots/Recordings** ### **Before** N/A (documentation-only JSDoc updates) ### **After** N/A (documentation-only JSDoc updates) ## **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 - [ ] 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: documentation-only JSDoc link updates with no runtime or behavior changes. > > **Overview** > Standardizes the `@deprecated` JSDoc blocks for `Text`, `Icon`, `BannerAlert`, and `Button` to consistently include a component-specific anchor link into the design-system React Native `MIGRATION.md`. > > This replaces generic migration guide references with `#text-component`, `#icon-component`, `#banneralert-component`, and `#button-component` links alongside the existing README links. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit d933095. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…unt sheets (#28182) ## **Description** Migrate 3 RootModalFlow SDK/account sheet components from prop-based route access to `useRoute()` hook, removing their `as ScreenComponent` casts in App.tsx. Part of the effort to remove `no-explicit-any` violations from route files (PR 6 of 13). **Components migrated:** - `AddNewAccountBottomSheet` - reads optional scope/clientType params for non-EVM account creation - `SDKSessionModal` - reads channelId, icon, urlOrTitle, version, platform, isV2 for SDK session management - `SDKDisconnectModal` - reads channelId, account, accountName, dapp, accountsLength, isV2 for SDK disconnect flows **Changes:** - Switch each component to `useRoute()` with typed `RouteProp` generic - Remove dead Props interfaces (`SDKSEssionMoodalProps`, `SDKDisconnectModalProps`) - Simplify `AddNewAccountBottomSheet` types to export only `RouteParams` - Remove 3 `as ScreenComponent` casts from `App.tsx` - Update all 3 test files to mock `useRoute()` ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** N/A — pure refactoring with no user-facing behavior change. All 26 existing tests pass. ## **Screenshots/Recordings** ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. Made with [Cursor](https://cursor.com) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk refactor that only changes how route params are accessed for three modal sheets and updates tests accordingly; behavior should be unchanged but regressions could occur if route params are missing/mistyped at runtime. > > **Overview** > Refactors three RootModalFlow sheet components (`AddNewAccountBottomSheet`, `SDKSessionModal`, `SDKDisconnectModal`) to stop receiving `route` as a prop and instead read typed params via React Navigation’s `useRoute()`. > > Removes the corresponding `as ScreenComponent` casts in `App.tsx`, deletes the old prop interfaces in favor of route-param types, and updates the associated tests to mock `useRoute()` rather than passing `route` props. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit bdc9a64. 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**
- Use push EAS update in the Runway workflow directly
- Fix PR number null issue
## **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]
> **Medium Risk**
> Changes the release/OTA GitHub Actions orchestration by switching from
API dispatch to a reusable workflow and tweaking PR-number resolution;
mistakes here could block OTA publishing or target the wrong ref.
>
> **Overview**
> Updates the OTA publishing pipeline to call `push-eas-update.yml` as a
*reusable workflow* (`workflow_call`) instead of dispatching it via
`actions/github-script`, simplifying `runway-ota-build-core.yml`.
>
> Also fixes PR-number discovery to treat `gh pr list` returning `null`
as empty (avoiding false positives), and updates `CODEOWNERS` to include
the new `build-and-upload-to-testflight.yml` workflow under
`@MetaMask/mobile-admins`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
633c2ac. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Cal-L <cal.leung@consensys.net>
## **Description** Integrating the new `money-account-controller`. If you wish to see the logs of this new controller, make sure to add this to your `.env.js`: ``` export DEBUG=metamask:money-account-controller ``` To enable with a local feature flag (`.js.env`): ``` export OVERRIDE_REMOTE_FEATURE_FLAGS="true" export MM_MONEY_ENABLE_MONEY_ACCOUNT="true" ``` You should see logs like this (the first time the Money account gets created): ``` (NOBRIDGE) DEBUG metamask:money-account-controller Money keyring (entropy:01KN6N42H46T44X2XMFNNGSJBR) not found, creating one... +0ms (NOBRIDGE) DEBUG metamask:money-account-controller Money keyring (entropy:01KN6N42H46T44X2XMFNNGSJBR) has no accounts, creating one... +4ms (NOBRIDGE) DEBUG metamask:money-account-controller Money keyring (entropy:01KN6N42H46T44X2XMFNNGSJBR) account created: 0x7fd31648732ad5d5e60d724652d3517184647b2b (d50016b8-6db3-422a-8d74-31514d276073) +34ms (NOBRIDGE) DEBUG metamask:money-account-controller Money keyring (entropy:01KN6N42H46T44X2XMFNNGSJBR - primary) account is: 0x7fd31648732ad5d5e60d724652d3517184647b2b (d50016b8-6db3-422a-8d74-31514d276073) +1ms ``` And logs like this afterward (e.g after an unlock): ``` (NOBRIDGE) DEBUG metamask:money-account-controller Money keyring (entropy:01KN6N42H46T44X2XMFNNGSJBR - primary) account is: 0x7fd31648732ad5d5e60d724652d3517184647b2b (d50016b8-6db3-422a-8d74-31514d276073) +8m ``` You can also, visually see the Money account address by applying this patch: ```diff diff --git a/app/components/UI/Money/components/MoneyHeader/MoneyHeader.tsx b/app/components/UI/Money/components/MoneyHeader/MoneyHeader.tsx index 0bd441d..d1348a4cd3 100644 --- a/app/components/UI/Money/components/MoneyHeader/MoneyHeader.tsx +++ b/app/components/UI/Money/components/MoneyHeader/MoneyHeader.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { useSelector } from 'react-redux'; import { Box, BoxAlignItems, @@ -7,8 +8,11 @@ import { ButtonIcon, ButtonIconSize, IconName, + Text, + TextVariant, } from '@metamask/design-system-react-native'; import { MoneyHeaderTestIds } from './MoneyHeader.testIds'; +import { selectPrimaryMoneyAccount } from '../../../../../selectors/moneyAccountController'; interface MoneyHeaderProps { /** @@ -21,29 +25,40 @@ interface MoneyHeaderProps { onMenuPress: () => void; } -const MoneyHeader = ({ onBackPress, onMenuPress }: MoneyHeaderProps) => ( - <Box - flexDirection={BoxFlexDirection.Row} - alignItems={BoxAlignItems.Center} - justifyContent={BoxJustifyContent.Between} - twClassName="px-1 pt-2 pb-5" - testID={MoneyHeaderTestIds.CONTAINER} - > - <ButtonIcon - iconName={IconName.ArrowLeft} - size={ButtonIconSize.Md} - onPress={onBackPress} - accessibilityLabel="Back" - testID={MoneyHeaderTestIds.BACK_BUTTON} - /> - <ButtonIcon - iconName={IconName.MoreVertical} - size={ButtonIconSize.Md} - onPress={onMenuPress} - accessibilityLabel="Menu" - testID={MoneyHeaderTestIds.MENU_BUTTON} - /> - </Box> -); +const MoneyHeader = ({ onBackPress, onMenuPress }: MoneyHeaderProps) => { + const primaryMoneyAccount = useSelector(selectPrimaryMoneyAccount); + + return ( + <Box + flexDirection={BoxFlexDirection.Row} + alignItems={BoxAlignItems.Center} + justifyContent={BoxJustifyContent.Between} + twClassName="px-1 pt-2 pb-5" + testID={MoneyHeaderTestIds.CONTAINER} + > + <ButtonIcon + iconName={IconName.ArrowLeft} + size={ButtonIconSize.Md} + onPress={onBackPress} + accessibilityLabel="Back" + testID={MoneyHeaderTestIds.BACK_BUTTON} + /> + { + primaryMoneyAccount ? ( + <Text variant={TextVariant.BodySm}> + {primaryMoneyAccount.address} + </Text> + ) : null + } + <ButtonIcon + iconName={IconName.MoreVertical} + size={ButtonIconSize.Md} + onPress={onMenuPress} + accessibilityLabel="Menu" + testID={MoneyHeaderTestIds.MENU_BUTTON} + /> + </Box> + ); +}; export default MoneyHeader; ``` And you can navigate to the `MoneyHomeView` (by clicking on `Cash >`). ## **Changelog** CHANGELOG entry: null ## **Related issues** N/A ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **High Risk** > High risk because it adds a new background controller into `Engine` initialization/state and conditionally introduces a `MoneyKeyring` that pulls and encodes HD keyring mnemonics, impacting key management and startup behavior. > > **Overview** > Integrates `@metamask/money-account-controller` into the background `Engine` (init wiring, messenger delegation, stateChange subscriptions, persisted initial state/log snapshots) so its state is available via `Engine.context`/`Engine.state`. > > Adds a new remote+env gated flag (`moneyEnableMoneyAccount` / `MM_MONEY_ENABLE_MONEY_ACCOUNT`) and uses it to (a) conditionally initialize/clear `MoneyAccountController` during account-tree startup and (b) conditionally register a `MoneyKeyring` builder in `keyringControllerInit`, including a `getMnemonic` callback that locates the matching HD keyring and encodes its mnemonic for Money keyring initialization. > > Introduces selectors for Money accounts (`selectMoneyAccounts`, `selectPrimaryMoneyAccount`) plus a `selectPrimaryHDKeyring` helper, and updates/extends unit tests and feature-flag registry accordingly. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit fda78f6. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Gustavo Antunes <17601467+gantunesr@users.noreply.github.com>
…nified swaps context cp-7.73.0 (#28361) <!-- 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? --> When a destination token has a security warning (e.g. a Blockaid malicious/suspicious flag), the unified swaps bridge view was entering an infinite quote request loop. **Root cause:** `tokenWarning` was included as a dependency of the `useMemo` that builds the analytics `context` object in `useUnifiedSwapBridgeContext`. `tokenWarning` is itself derived from quote results (blockaid data returned by the bridge controller). This created a feedback cycle: ``` Quote fetched → tokenWarning updates → context object recreates → updateQuoteParams identity changes → useEffect fires → new quote request → repeat ∞ ``` **Fix:** Remove `tokenWarning` from the `useMemo` dependency array and clear `security_warnings` to `[]` for now. The `security_warnings` field will be populated properly in the bridge controller instead, removing the React dependency cycle entirely. ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: Fixed a bug that caused repeated quote requests when swapping to a token with a security warning. ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: Unified Swaps/Bridge quote fetching with token warnings Scenario: user swaps to a token with a Blockaid security warning Given the user has opened the Swap/Bridge screen And the user has selected a source token with sufficient balance When the user selects a destination token that has a Blockaid security warning And the user enters a valid source amount Then the app fetches a quote once And does not repeatedly fire additional quote requests And the security warning banner is displayed on screen Scenario: user swaps to a normal token (no warning) Given the user has opened the Swap/Bridge screen And the user has selected a source token with sufficient balance When the user selects a destination token with no security warning And the user enters a valid source amount Then the app fetches a quote once And quote results are displayed normally ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** N/A ### **After** Uploading Screen Recording 2026-04-02 at 4.24.51 PM.mov… ## **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. <!-- Generated with the help of the pr-description AI skill --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: small change limited to analytics context memoization, but it temporarily drops `security_warnings` data which could affect warning-related telemetry until re-populated elsewhere. > > **Overview** > Prevents an infinite bridge quote re-fetch loop by removing destination token warning state from `useUnifiedSwapBridgeContext`’s memoized context object. > > `security_warnings` is now always an empty array (*TODO*) and the `useMemo` dependency list no longer includes the warning selector, stabilizing the `context` identity passed into `BridgeController.updateBridgeQuoteRequestParams`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 21dec81. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…28285) ## **Description** Fixes a bug where the network selector icon in the In-App Browser was stuck displaying the global selected network due to incorrect dapp origin information being used ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: Fixed a bug where the network selector icon in the In-App Browser would not correctly reflect the currently selected network for the dapp ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/WAPI-1031 ## **Manual testing steps** 1. Open Explore 2. Click the top right In-App Browser tab icon 3. Tap the top right network selector icon 4. Select a network that differs from the current icon 5. The icon should change to match ## **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/d68fc3a2-4145-4189-ae97-bc2ece8a018a ### **After** https://github.com/user-attachments/assets/2cd0a33a-7885-402c-b537-ebbd1448aae1 ## **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: scoped UI/navigation parameter plumbing to ensure per-dapp network context is used; main risk is callers missing the new required `dappOrigin` prop or origin parsing yielding empty origin in edge URLs. > > **Overview** > Fixes the In-App Browser network picker/avatar to reflect the *dapp-selected* network by threading an explicit `dappOrigin` through `BrowserUrlBar` into `AccountRightButton`. > > `AccountRightButton` no longer derives origin from navigation route params; it now uses `dappOrigin` for `useNetworkInfo` and includes it as `hostInfo.metadata.origin` when opening the `NetworkSelector` sheet, so the selector can resolve the per-origin network. Tests were updated accordingly to supply a non-empty `dappOrigin` and remove the `useRoute` mock. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 9c4cbaa. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Alex Donesky <adonesky@gmail.com>
…28111) ## **Description** Uses the self reported dapp url when available for the `CONNECT_REQUEST_COMPLETED` event when the connection is a SDKv1, SDKv2, or WC connection. It uses the trusted origin otherwise. ## **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/WAPI-1338 ## **Manual testing steps** 1. Establish a WC or SDKv1 or SDKv2 connection 2. Check analytics events for a property value `referrer` that should be the dapp's url, not a UUID It may be easier to use an expo build and the js debugger to view analytic network events. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk analytics-only change that alters the `referrer` value emitted for `CONNECT_REQUEST_COMPLETED`, potentially affecting downstream dashboards but not user-facing behavior. > > **Overview** > Updates analytics for connection approvals so `MetaMetricsEvents.CONNECT_REQUEST_COMPLETED` now reports a computed `referrer` (SDK/WC self-reported dapp URL when available, otherwise the trusted hostname/origin) instead of always using `request.metadata.origin`. > > Applies the same `referrer` logic in both `AccountConnect` and `MultichainAccountConnect`, and wires it into the `handleConnect` tracking dependencies. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit ad3bb42. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Alex Donesky <adonesky@gmail.com>
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** The `trigger-ota` job mixed shell steps with a reusable workflow (`uses: ./.github/workflows/push-eas-update.yml`). In GitHub Actions, a job must either define `steps:` or call another workflow with job-level `uses:`, not both. This splits that into: 1. **`validate-ota-pr`** — Validates a PR number exists before OTA (same guard as before). 2. **`trigger-ota`** — Only calls `push-eas-update.yml`, with `secrets: inherit` for caller secrets. **`create-ota-production-tag`** now sets `tag_name` from `needs.decide.outputs.ota_version` (same value the old `release_tag` step echoed). It still `needs: trigger-ota` so tagging runs only after the OTA workflow finishes. successful workflow run: https://github.com/MetaMask/metamask-mobile/actions/runs/23923283109 ## **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** - [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 job graph for Runway OTA publishing/tagging; misconfigured `needs`/`uses`/secrets inheritance could block OTA releases or trigger the wrong follow-up jobs. > > **Overview** > Fixes `runway-ota-build-core.yml` to correctly invoke the reusable `push-eas-update.yml` workflow as a **job-level** `uses:` instead of mixing it with `steps:`. > > Adds a separate `validate-ota-pr` job to guard OTA runs when no PR number is resolvable, updates `trigger-ota` to inherit secrets, and adjusts production tagging to use `needs.decide.outputs.ota_version` directly (removing the intermediate `release_tag` output). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 92b5c4c. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…p-7.73.0 (#28302) <!-- 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** Addresses several UAT issues in the Predict buy-with-any-token flow: - **Auto-select best payment token**: New `usePredictDefaultPaymentToken` hook auto-selects the token with the highest fiat balance when Predict balance is below MINIMUM_BET ($1), instead of requiring manual selection. Resets to Predict balance when sufficient. - **Optimistic positions on deposit**: Creates optimistic positions from the order preview at deposit time so the position appears immediately in the portfolio while the deposit confirms. Clears optimistic positions on failure (both direct order failures and failed deposit-and-order transactions). - **Navigate back on deposit**: Navigate back when the deposit-and-order flow begins, so the user isn't stuck on the buy form. - **Keep token selection always enabled**: Removes the `canSelectToken` gate — the pay-with-token row is now always interactive (disabled only while placing an order). - **"Predict balance first" hint**: Shows "Your Predict balance will be used first" below the pay-with row when an external token is selected, so users understand the payment order. - **Deposit amount guards**: `depositAmount` now returns 0 when the preview is unavailable or the bet is below minimum, preventing premature deposit calculations and stale values from triggering the deposit flow. - **Updated insufficient funds messaging**: Error messages now suggest trying a different token when funds are insufficient. - **Fix text overflow on Polymarket terms**: Nests the "learn more" link inside the disclaimer text and adds horizontal padding to prevent overflow. - **Fix premature payment token reset**: Adds a `totalPayForPredictBalance > 0` guard so the auto-reset effect only fires when there is an actual bet amount, preventing the selected token from being cleared immediately after selection. - **Depositing toast notification**: Shows a "Prediction in progress" toast with spinner when the deposit phase begins and invalidates position queries to reflect the optimistic position. <!-- 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** https://www.loom.com/share/c25681fd77a444e496f999a23a55b0e6 <!-- 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** > Updates buy-with-any-token order state transitions, optimistic position caching, and navigation/toast behavior; mistakes could cause incorrect UI state or stale/phantom positions during deposit/order failures. > > **Overview** > Improves the *buy-with-any-token* flow by introducing a new `order` event status `depositing` and publishing it when the flow transitions into the deposit phase, with a matching “Prediction in progress” toast and positions query invalidation. > > Adds preview-based **optimistic positions** during deposit via `PolymarketProvider.createOptimisticPositionFromPreview`, and ensures cleanup via `clearOptimisticPosition` when `placeOrder` fails or when a `depositAndOrder` transaction fails. > > Refines buy screen UX: auto-selects a default payment token when Predict balance is below `MINIMUM_BET` (new `usePredictDefaultPaymentToken`), removes the `canSelectToken` gate (row only disabled while placing), navigates back when entering `DEPOSITING`, adds a “Predict balance will be used first” hint, guards deposit amount calculation until fees/minimum bet are available, and updates insufficient-funds copy to suggest trying another token; also adjusts the Polymarket TOS disclaimer layout to prevent overflow. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 7f97218. 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? --> Migrated `Button` to DSRN package usage. ## **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-445 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** https://github.com/user-attachments/assets/26db059b-4937-4e94-827c-7ca7b9624596 ### **After** https://github.com/user-attachments/assets/56fbddab-9c75-40fc-bbb5-6ee3560f3ecc ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Medium risk because it swaps button implementations across multiple settings/network/account screens, which can subtly change press/disabled/accessibility behavior and snapshot structure. > > **Overview** > Migrates multiple screens (e.g., `EditAccountName`, network connect/selector flows, and several Settings sections) from the internal `component-library` `Button` to `@metamask/design-system-react-native` `Button`, updating props (`label` -> children, `disabled` -> `isDisabled`, `width` -> `isFullWidth`, and new `ButtonVariant` enums). > > Updates tests and snapshots to match the new rendered structure/accessibility output, including tightening the `NetworkConnectMultiSelector` loading test to assert the update CTA is disabled and that “select all” is a no-op while loading, and removing the now-unneeded `disabledOpacity` styling. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 136d88e. 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? --> Migrated `Skeleton` to DSRN usage (card scope). ## **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** https://github.com/user-attachments/assets/7e2c714e-7ada-4a25-9073-437b9e4dbe32 ### **After** https://github.com/user-attachments/assets/8a310ad6-e1cd-40f4-b266-3e1bfb979b57 ## **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-only change that swaps the `Skeleton` implementation and updates the associated snapshot; no business logic or data flow changes. > > **Overview** > Migrates `ViewPinBottomSheet` to use `Skeleton` from `component-library/components-temp/Skeleton` instead of the deprecated `components/Skeleton`. > > Updates the Jest snapshot to reflect the new skeleton’s rendered style structure (notably how border radius/positioning styles are applied). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 95dd583. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…et test (#28708) ## **Description** Fix Prettier formatting violations and eslint errors in `SafeAreaViewWithHookTopInset.test.tsx` introduced by #28622. These break lint checks on any unrelated PR that touches this file. **Changes:** - Reformat JSX to match Prettier config - Extract inline styles to `StyleSheet.create` to fix `react-native/no-inline-styles` - Replace `require()` with `jest.requireActual()` in `jest.mock` factory to fix `@typescript-eslint/no-require-imports` ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes lint/formatting regressions from #28622 ## **Manual testing steps** ```gherkin Feature: SafeAreaViewWithHookTopInset test lint compliance Scenario: lint and tests pass on the test file Given the file app/shims/SafeAreaViewWithHookTopInset.test.tsx When running eslint on the file Then zero errors are reported When running jest on the file Then all 20 tests pass ``` ## **Screenshots/Recordings** N/A — no visual changes, formatting and lint fixes only. ### **Before** 6 eslint errors on `main`: - 2x `@typescript-eslint/no-require-imports` — `require()` inside `jest.mock` factory - 4x `react-native/no-inline-styles` — inline style objects in test assertions ### **After** 0 eslint errors, 0 eslint-disable comments, all 20 tests passing. ## **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: changes are confined to a Jest test file and only adjust mocks/style declarations to satisfy linting/formatting, without touching runtime code paths. > > **Overview** > Cleans up `SafeAreaViewWithHookTopInset.test.tsx` to pass lint/format checks by switching `jest.mock` factories from `require()` to typed `jest.requireActual()` and tightening ref typings in the mock `SafeAreaView`. > > Replaces inline style objects used in tests with a shared `StyleSheet.create` (`testStyles`) and applies minor Prettier-driven JSX/line-wrap formatting changes, leaving test coverage/behavior unchanged. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 00a20c7. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description**
Add app lifecycle actions (`app_background`, `app_foreground`,
`app_restart`) to the agentic tooling with platform-aware
implementations (iOS `simctl` + Android `adb`). Enable multi-device CDP
target discovery so `status` probes all targets across both platforms.
Fix preflight to reuse a healthy Metro instance (curl /status check) and
warn on platform mismatch instead of failing. Add `--input key=value`
flag to `validate-recipe.js`.
Also fixes switch/end nodes bypassing `when` guards (caused TypeError on
default config), and adds automatic `run.log` capture for every recipe
execution.
## **Changelog**
CHANGELOG entry: null
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: Agentic lifecycle actions and multi-device support
Scenario: run app-lifecycle recipe in dry-run mode
Given the agentic tooling is available
When user runs validate-recipe with app-lifecycle.json --dry-run
Then recipe parses and validates without errors
Scenario: CDP bridge status shows multiple targets
Given both iOS simulator and Android emulator are running
When user runs cdp-bridge.js status
Then both platform targets are listed
Scenario: lifecycle actions execute per platform
Given the app is running on iOS simulator
When user triggers app_background action
Then the app moves to background via simctl
```
## **Screenshots/Recordings**
### **Before**
N/A — new tooling feature
### **After**
- `node validate-recipe.js recipes/app-lifecycle.json --dry-run` —
parses OK
- Lifecycle actions validated on both iOS simulator and Android emulator
- Multi-device target discovery working across platforms
## **Validation Recipe**
<details><summary>app-lifecycle.json (20 nodes — short background, long
background, restart)</summary>
```json
{
"title": "App Lifecycle — validate data survives background, long background, and restart",
"description": "Reference recipe demonstrating three lifecycle stress levels: short background (within WS grace period), long background (exceeds grace period, forces full WS reconnection), and full app restart. Use as a template for PR recipes that need lifecycle validation.",
"inputs": {
"symbol": { "type": "string", "default": "BTC" },
"short_background_ms": { "type": "number", "default": 5000 },
"long_background_ms": { "type": "number", "default": 30000 },
"test_short_background": { "type": "boolean", "default": true },
"test_long_background": { "type": "boolean", "default": true },
"test_restart": { "type": "boolean", "default": false }
},
"validate": {
"workflow": {
"pre_conditions": ["wallet.unlocked", "perps.feature_enabled"],
"entry": "nav-market-list",
"nodes": {
"nav-market-list": { "action": "navigate", "target": "PerpsTrendingView", "next": "wait-markets" },
"wait-markets": { "action": "wait_for", "assert": { "operator": "gt", "field": "count", "value": 0 }, "next": "baseline-price" },
"baseline-price": { "action": "eval_async", "description": "Baseline — confirm markets and price data loaded", "next": "short-background" },
"short-background": { "action": "app_background", "when": "test_short_background", "duration_ms": "{{short_background_ms}}", "next": "short-foreground" },
"short-foreground": { "action": "app_foreground", "next": "wait-post-short" },
"wait-post-short": { "action": "wait_for", "next": "verify-post-short" },
"verify-post-short": { "action": "eval_async", "description": "Confirm markets + price survive short background", "next": "long-background" },
"long-background": { "action": "app_background", "description": "Exceeds WS grace period", "duration_ms": 30000, "next": "long-foreground" },
"long-foreground": { "action": "app_foreground", "next": "wait-post-long" },
"wait-post-long": { "action": "wait_for", "next": "verify-post-long" },
"verify-post-long": { "action": "eval_async", "description": "Confirm markets + DEXs recover after WS reconnection", "next": "restart-app" },
"restart-app": { "action": "app_restart", "when": "test_restart", "next": "detect-post-restart" },
"...": "remaining restart/unlock/verify nodes",
"done": { "action": "end", "status": "pass" }
}
}
}
}
```
</details>
## **Validation Logs**
Command:
```bash
node scripts/perps/agentic/validate-recipe.js \
scripts/perps/agentic/teams/perps/recipes/app-lifecycle.json
```
<details><summary>Full output (11/17 passed, 6 skipped — iOS)</summary>
```
Running recipe: App Lifecycle — validate data survives background, long background, and restart
Team: perps
Pre-conditions: wallet.unlocked, perps.feature_enabled
Workflow nodes: 20
Pre-conditions: PASS
[nav-market-list] navigate to PerpsTrendingView
result: {"navigated":"PerpsTrendingView",...}
PASS
[wait-markets] wait for condition
result: {"count":291}
PASS
[baseline-price] Baseline — confirm markets and price data loaded
result: {"found":true,"price":"$71,046"}
PASS
[short-background] Short background — within WS grace period, cache should be preserved
backgrounded for 5000ms
PASS
[short-foreground] foreground app
foregrounded (io.metamask.MetaMask)
PASS
[wait-post-short] wait for condition
result: {"count":291}
PASS
[verify-post-short] Confirm markets + price survive short background
result: {"found":true,"price":"$71,058"}
PASS
[long-background] Long background — exceeds WS grace period, forces full reconnection
backgrounded for 30000ms
PASS
[long-foreground] foreground app
foregrounded (io.metamask.MetaMask)
PASS
[wait-post-long] wait for condition
result: {"count":291}
PASS
[verify-post-long] Confirm markets + DEXs recover after full WS reconnection
result: {"markets":291,"dexs":9,"price":"$71,039"}
PASS
[restart-app] restart app
[SKIPPED - when condition did not match]
[detect-post-restart] Detect login vs wallet after restart
[SKIPPED - when condition did not match]
[check-needs-unlock] evaluate branch
[SKIPPED - when condition did not match]
[nav-after-restart] navigate to PerpsTrendingView
[SKIPPED - when condition did not match]
[wait-post-restart] wait for condition
[SKIPPED - when condition did not match]
[verify-post-restart] Confirm markets reload cleanly after full restart
[SKIPPED - when condition did not match]
----------------------------------------
Results: 11/17 passed, 6 skipped
Recipe: PASS
```
</details>
## **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 workflow actions that spawn `xcrun`/`adb` processes and
changes CDP target selection/reporting, which can affect automation
reliability across devices. Also introduces automatic log
capture/redaction and new CLI flags that alter runner behavior.
>
> **Overview**
> **Agentic workflows can now exercise app lifecycle events.** The
recipe runner adds new actions (`app_background`, `app_foreground`,
`app_restart`) implemented via a new `lib/app-lifecycle.js` that uses
`simctl`/AppleScript on iOS and `adb` on Android, and documents these
actions plus a new `teams/perps/recipes/app-lifecycle.json` reference
recipe.
>
> **CDP and preflight scripts now better support multi-device setups.**
`cdp-bridge.js status` probes *all* discovered Hermes targets (via new
`discoverAllTargets`) and returns either a single object or an array;
`preflight.sh` reuses an already-healthy Metro instance by probing
`/status` and loosens the platform check to a warning when the expected
platform target isn’t found.
>
> **Recipe execution UX improved.** `validate-recipe.js` adds `--input
key=value` for overriding recipe inputs, `--no-log` to disable logging,
captures console output to `run.log` with basic redaction, and fixes
`when` guards to apply to `switch`/`end` nodes (skipping them safely
instead of executing).
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
b3948ed. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!-- CURSOR_AGENT_PR_BODY_BEGIN -->
## **Description**
Removed the scheduled cron trigger from
`.github/workflows/run-e2e-regression-tests-android.yml` so this
workflow no longer runs every 3 hours.
The workflow can still be run manually via `workflow_dispatch`.
## **Changelog**
CHANGELOG entry: null
## **Related issues**
Fixes: N/A
## **Manual testing steps**
```gherkin
Feature: Android regression workflow trigger behavior
Scenario: workflow can be manually triggered only
Given the GitHub Actions workflow file `run-e2e-regression-tests-android.yml`
When I inspect the `on` section
Then it contains `workflow_dispatch` inputs
And it does not contain a `schedule` cron trigger
```
## **Screenshots/Recordings**
Not applicable (CI workflow configuration change only).
### **Before**
N/A
### **After**
N/A
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] 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_AGENT_PR_BODY_END -->
<div><a
href="https://cursor.com/agents/bc-6074cff0-b322-43a4-898b-b8b12af5bb28"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a
href="https://cursor.com/background-agent?bcId=bc-6074cff0-b322-43a4-898b-b8b12af5bb28"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img
alt="Open in Cursor" width="131" height="28"
src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </div>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: cmd-ob <cmd-ob@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** Fix design of mush deposit 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: https://consensyssoftware.atlassian.net/browse/CONF-1173 ## **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** <img width="395" height="853" alt="Screenshot 2026-04-10 at 4 22 11 PM" src="https://github.com/user-attachments/assets/584fab12-a80f-4092-a57e-6ec0e662dabd" /> ## **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/prop change limited to the confirmations custom amount view and mUSD conversion flow; main risk is unintended layout/row visibility regressions when `hidePayTokenAmount` is enabled. > > **Overview** > Updates `CustomAmountInfo` to **remove `overrideContent`** and introduce `hidePayTokenAmount`, which hides the default `PayTokenAmount` (and the associated extra content block) while keeping `PayWithRow` rendering logic consistent. > > Simplifies `MusdConversionInfo` by deleting the bespoke override UI (output tag + embedded `PayWithRow`) and instead passing `hidePayTokenAmount` to `CustomAmountInfo`; tests are updated accordingly. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 3c829f9. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/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** Speed up and cancel failures no longer open a blocking **Retry** modal. Users see a **toast** with a clear title and, when available, a short error description—including a friendlier message when the failure is due to **“nonce too low”** (already confirmed). **Changes** - Removed `RetryModal` and related state (`retryIsOpen`, `errorMsg`, `toggleRetry`, `retry`) from the legacy **Transactions** screen and **UnifiedTransactionsView**. - On failure, **legacy** `Transactions` uses `ToastService.showToast` with shared options from `getTransactionUpdateErrorToastOptions`. - **Unified** flow uses `ToastContext` in `useUnifiedTxActions` to show the same toast shape. - Centralized toast config in `app/util/confirmation/transactions.ts` (variant, icon, colors, transparent background, copy) so both entry points stay in sync. - Added `resolveTransactionUpdateErrorMessage` to map raw errors to user-facing strings where we special-case known cases. <!-- 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: Redesigned speed-up/cancel retry modal with error toasts ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/CONF-1076 ## **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** [toast failed.webm](https://github.com/user-attachments/assets/3baec8fe-8513-4e99-ad14-f36c16a72043) <!-- 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 UX refactor that changes how speed-up/cancel failures are surfaced (toast instead of a blocking modal) without altering transaction update logic; main risk is missing toast context/service wiring in some views. > > **Overview** > Speed-up/cancel failures no longer open a blocking **Retry** modal; they now show an **error toast** in both the legacy `Transactions` list (via `ToastService`) and the unified flow (via `ToastContext`). > > Adds shared helpers `resolveTransactionUpdateErrorMessage` and `getTransactionUpdateErrorToastOptions` in `util/confirmation/transactions.ts`, including a friendlier message for *“nonce too low”* (already confirmed), and updates tests/mocks accordingly. Locale strings are migrated from `transaction_update_retry_modal` to `transaction_update_toast` across supported languages. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit d49b050. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/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 updates the A/B testing documentation to make the implementation path much easier for a new engineer to follow. The guide now starts with a quickstart and definition of done, consolidates the implementation guidance into one end-to-end example, and moves agent-specific workflow details to an appendix so they do not interrupt the main onboarding flow. ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: ## **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 ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- Generated with the help of the pr-description AI skill -->
…8724) <!-- 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** Using alert system for money account related errors. ## **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/CONF-1182 ## **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** NA ## **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 how `moneyAccountDeposit` “no funds” is surfaced by introducing a new blocking alert and wiring it into the shared pending-amount alert pipeline, which can affect confirm-button enablement and user flow. Risk is limited to confirmations/UX and is covered by added unit tests. > > **Overview** > Moves the `moneyAccountDeposit` “no funds” state into the confirmations *alert system* by introducing a new blocking `AccountNoFunds` alert (with metrics mapping) and feeding it through `usePendingAmountAlerts`. > > Removes the old inline “no funds” red text from `CustomAmountInfo`, updates tests to assert alert-driven rendering, and adds new i18n under `alert_system.account_no_funds` while deleting the legacy `confirm.no_funds_use_different_account` string. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit c92ce45. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This PR syncs the stable branch to main for version 7.74.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.74.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**
Wires up the Social Leaderboard to live data from the Social API.
Integrate the social-controllers (SocialService + SocialController) into
the Engine, adds useTopTraders hook using useQuery from
@metamask/react-data-query to fetch leaderboard data through the Data
Services pattern.
Also adds the homepage TopTradersSection (horizontal card carousel) and
the full TopTradersView (ranked list) with skeleton loading states.
## **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]
> **Medium Risk**
> Adds a new Social data service/controller to the Engine and wires UI
screens to fetch live leaderboard data from a new `SOCIAL_API_URL`,
which could impact app startup/state persistence and introduce new
network failure modes.
>
> **Overview**
> Adds live Social Leaderboard integration by introducing Engine-managed
`SocialService` and `SocialController` (new messengers, init wiring,
persisted state, and data-service registration) and configuring a new
`SOCIAL_API_URL` build/env constant.
>
> Updates the homepage `TopTradersSection` to fetch and render the top 3
traders (cards + skeleton loading, refresh via ref, hide when empty/flag
off) and upgrades `TopTradersView` to display the full ranked list with
a network filter entry point and follow toggles.
>
> Includes new UI components (`TopTraderCard`, `TraderRow`, skeletons,
`NetworkFilterButton`), a `formatPnl` formatter, the `useTopTraders`
hook built on `@metamask/react-data-query`, plus expanded unit tests and
updated mocks/strings.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
5881e59. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/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** https://consensyssoftware.atlassian.net/browse/RWDS-1163 ### Leaderboard tier selector - Replaced TabsBar with a Pressable trigger that opens a RewardsSelectSheet bottom sheet for tier selection - Created RewardsSelectSheet -- a generic, reusable select bottom sheet registered as a transparentModal in MainNavigator.js at Routes.MODAL.REWARDS_SELECT_SHEET. Accepts title, options, selectedValue, and onSelect callback - Default tier is the user's projected tier (from leaderboard position) when available, otherwise the top tier (last in list) ### Stats summary - Added CampaignStatsSummary component displaying Return, Market Value, Rank, and Tier in a 2x2 grid with loading skeletons and error banners ### Leaderboard neighbor display (preview mode) - When maxEntries is set and the user's tier matches the selected tier: - If user rank is within visible range: highlights their row with bg-background-muted - If user rank is outside visible range: shows top 3 entries + dot separator + neighbor entries (rank-1, user, rank+1) - Handles edge cases: first/last in tier (1-2 neighbors), tier mismatch, no position data ### Pending tag / Qualified tag - Add `qualified` and `qualifiedDays` to CampaignLeaderboardEntry and CampaignLeaderboardPositionDto - Display `Pending` Tag if qualified: false, `Qualified` tag if true ### Activity view - Group activity rows by date ### Prize pool - Add prize pool progress bar according to hardcoded breakpoints given by PRD - Fetch total deposit volume from new endpoint Get(':campaignId/stats/deposits') <!-- 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* ### Pending <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-09 at 17 59 47" src="https://github.com/user-attachments/assets/bfdcec83-6f2b-4c29-b416-35b1c3275be9" /> <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-10 at 15 15 05" src="https://github.com/user-attachments/assets/500d7428-f0bc-40f1-ace7-c7048b38e23f" /> <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-10 at 15 15 41" src="https://github.com/user-attachments/assets/a0af5d73-a265-4c0b-b8c7-d9f928cc10e3" /> <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-10 at 15 18 33" src="https://github.com/user-attachments/assets/c695d664-4465-4f07-9027-668ae1d2fd7d" /> <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-10 at 15 18 40" src="https://github.com/user-attachments/assets/a1a0da1a-31ed-4207-bf4f-379485655cb5" /> ### Qualified <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-10 at 15 20 27" src="https://github.com/user-attachments/assets/29b8def5-4d08-4cf0-9e2f-3272ecdf93c2" /> <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-10 at 15 20 31" src="https://github.com/user-attachments/assets/9e0c3c85-7a10-4f50-8418-8d40b5f29afb" /> <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-10 at 15 23 10" src="https://github.com/user-attachments/assets/19f2ab07-f255-4767-b90a-e07dc8265c08" /> ### Activity view <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-10 at 15 28 48" src="https://github.com/user-attachments/assets/e8b42158-b6ff-47e9-b44d-ab23ba87ecc1" /> ### Prize pool <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-10 at 17 24 02" src="https://github.com/user-attachments/assets/ac0b1219-2252-41ed-bd26-656f188076eb" /> <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-10 at 17 29 36" src="https://github.com/user-attachments/assets/6f47ff55-db28-4318-919d-ce50319d0010" /> <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-10 at 17 29 58" src="https://github.com/user-attachments/assets/c4d64e3a-aa0d-44bf-bd50-8f9703986acf" /> * <!-- [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** > Moderate UI/behavior changes in Rewards campaign flows plus a new data fetch (`getOndoCampaignDeposits`) and updated leaderboard rendering, which could affect navigation and correctness of displayed stats/tier selection. > > **Overview** > Updates Ondo campaign rewards UI to support **tier-based leaderboards** via a new reusable `RewardsSelectSheet` modal (registered in `MainNavigator`) and localized tier display names. > > Reworks campaign details/leaderboard presentation by replacing `OndoLeaderboardPosition` with a new `CampaignStatsSummary` (return/market value/rank/tier, pending/qualified tags, SWR-style loading/error handling), adding a `OndoPrizePool` progress section backed by a new `useGetOndoCampaignDeposits` hook, and enhancing `OndoLeaderboard` with preview mode (`maxEntries`), current-user highlighting, and neighbor/split-view rendering. > > Refactors the portfolio activity view to be **activity-only**, grouped by date headers, and updates activity rows to support `timeOnly`, signed USD formatting, and external outflow address shortening; tests are updated/added accordingly. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit ecd1e4b. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…-3331] (#28337) ## **Description** When selecting a token in the UB2 Buy flow, a quick error ("We've encountered an error") flashes on the amount input screen before the correct "Powered by [provider]" text appears. The root cause is a provider ID mismatch: the quotes API can return provider IDs in a prefixed format (`/providers/transak`) while the controller state stores them without the prefix (`transak`). This caused `selectedQuote` to resolve to `null`, briefly rendering the error banner. The fix normalizes provider IDs on both sides of the comparison using `normalizeProviderCode()` and switches from array destructuring to `.find()` so all returned quotes are searched. ## **Changelog** CHANGELOG entry: Fixed Buy amount screen sometimes showing a generic error when quotes returned for the selected provider but provider id strings differed in format. ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TRAM-3331 Based on draft PR #27779 ## **Manual testing steps** ```gherkin Feature: Token selection in Buy flow Scenario: user selects a token and navigates to amount input Given user is on the token selection screen in the Buy flow When user selects a token (e.g. ETH) Then the amount input screen shows "Powered by [provider]" without any error flash ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> N/A. Reason: This is an extremely rare race condition. It doesn't happen often, and after several changes on main, it's even less common. Nevertheless, we still want to solve this logical condition via this PR. ### **After** <!-- [screenshots/recordings] --> N/A. Reason: This is an extremely rare race condition. It doesn't happen often, and after several changes on main, it's even less common. Nevertheless, we still want to solve this logical condition via this PR. ## **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 - [ ] 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 Buy flow quote-selection and payment-method loading state; small logic changes but in a user-critical conversion path and could affect when errors/continue button appear. > > **Overview** > Prevents the Buy amount input screen from briefly showing the generic *no quotes* error by updating `BuildQuote` to **normalize provider IDs** (handling `/providers/...` vs short codes) and to **search all returned quotes** via `.find()` when deriving `selectedQuote`. > > Tightens `useRampsPaymentMethods` loading behavior so `isLoading` stays true while auto-selecting a payment method when the previously selected method is no longer present, avoiding UI flashes of stale selection. Adds targeted tests covering provider-ID matching scenarios, empty/mismatched quote responses, continue-button disabled state, and the stale-selection loading fallback. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 2d4d9d7. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…saction confirmation (#28040) ## Summary - Fixes a race condition in `Toast.showToast` where rapid successive calls (e.g., transaction approved + confirmed in the same tick on Linea) cause the success toast to persist indefinitely - Tracks pending `setTimeout` with a ref so only the latest `showToast` call wins, ensuring the success toast renders with its proper auto-dismiss animation - Adds test coverage for the rapid successive `showToast` scenario https://github.com/user-attachments/assets/12064e1e-3beb-4d36-82e3-3237b2045eb6 ## Test plan - [x] Toast unit tests pass (`yarn jest app/component-library/components/Toast/Toast.test.tsx`) - [x] Manual: trigger a Max DAI→mUSD conversion on Linea and verify the success toast auto-dismisses after ~3s - [x] Verify normal (non-rapid) toast transitions still work correctly <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches toast display timing/animation logic; small but could regress toast sequencing or dismissal behavior if timer clearing interacts with existing transitions. > > **Overview** > Fixes a race in `Toast.showToast` where back-to-back calls could leave multiple queued `setTimeout` updates, causing the wrong toast state/timeout behavior (e.g., a success toast persisting). > > `Toast` now tracks and clears any pending `setTimeout` via a ref so only the latest `showToast` call applies. Adds a unit test asserting rapid successive calls leave a single pending timer and only the latest toast renders. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 111df6d. 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? --> Bringing the following changes to the client: ```markdown ## [1.25.2] ### Fixed - Relax Trongrid `internal_transactions` validation to avoid sync failures on sparse legacy payloads ([#289](MetaMask/snap-tron-wallet#289)) - Handle TRC10 token identifiers correctly in the current Trongrid account-history transaction flow, without mis-parsing endpoint-specific `asset_name` formats ([#289](MetaMask/snap-tron-wallet#289)) - Decouple assets and transactions synchronization so one failure does not prevent the other from completing ([#289](MetaMask/snap-tron-wallet#289)) ``` ## **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** n/a ## **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 ### **After** n/a ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk dependency bump confined to the Tron snap package; behavior changes are limited to Tron sync handling and should not affect unrelated wallet flows. > > **Overview** > Bumps `@metamask/tron-wallet-snap` from `^1.25.1` to `^1.25.2`, updating both `package.json` and `yarn.lock` resolution/checksum. > > This pulls in upstream fixes around Tron sync robustness (more permissive Trongrid `internal_transactions` validation, correct TRC10 token identifier handling, and separating asset vs transaction sync so one failure doesn’t block the other). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 235931c. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…nd update result properties (#28645) ## **Description** Rename `initModularizedControllers` to `initMessengerClients`, drop `existingControllersByName`, rename `controllerInitFunctions` to `initFunctions`, and update return type to `messengerClientsByName`. Update all consumers in `Engine.ts`, `utils.test.ts`, and test utility functions. 80 files changed. **PR 3 of 4** — depends on PR 2 (#28641). - ~~PR 1: Core type renames (`Controller` → `MessengerClient`, etc.) (#28610)~~ - ~~PR 2: `CONTROLLER_MESSENGERS` → `MESSENGER_FACTORIES` (#28641)~~ - **PR 3 (this):** `initModularizedControllers` → `initMessengerClients` + utils/Engine.ts renames - PR 4: Property renames (`controller` → `messengerClient`, `getController` → `getMessengerClient`) in all init files + tests Relates to [WPC-916](https://consensyssoftware.atlassian.net/browse/WPC-916). ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/WPC-916 ## **Manual testing steps** ```gherkin Feature: Messenger client init system Scenario: App builds and runs normally Given the app is built from this branch When user opens the app Then the app behaves identically to main (no runtime behavior change) ``` ## **Screenshots/Recordings** N/A — no UI changes. ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] 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. [WPC-916]: https://consensyssoftware.atlassian.net/browse/WPC-916?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Refactors the Engine’s initialization wiring for all controller/messenger clients, so mistakes could break startup order or dependency resolution despite being a rename-focused change. > > **Overview** > **Renames and reshapes the Engine init helper** by replacing `initModularizedControllers` with `initMessengerClients`, renaming `controllerInitFunctions` to `initFunctions`, and returning `messengerClientsByName`. > > **Simplifies initialization state** by dropping support for `existingControllersByName` and updating the dependency lookup helper/error messaging to `getMessengerClientOrThrow`. > > Updates `Engine.ts` wiring and a large set of controller init tests to use the new request mock helper (`buildMessengerClientInitRequestMock`) and the new result property names. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 80bf6e1. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/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 polishes the Money feature so the patterns for Headers, List,
Sections, Filtering and Spacing are visually cohesive.
## **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: Money account activity and hub layout polish
Scenario: User opens Money activity from the Money hub
Given the user is logged in with a Money account that can show activity
And the user is on the Money hub (home) screen
When the user navigates to Money activity (Activity)
Then the activity screen loads with the expected header and back affordance
And activity is grouped and readable (date sections and list items render without layout overlap)
Scenario: User filters Money activity by type
Given the user is on the Money activity screen
And there is activity data available for more than one filter category
When the user changes the activity filter (e.g. All / Deposits / Transfers as applicable)
Then the list updates to match the selected filter
And section headers and row content remain correctly aligned and legible
Scenario: User reviews Money hub summary and quick actions after layout updates
Given the user is on the Money hub (home) screen
When the user views the balance summary and the primary action buttons row
Then balances and labels use the updated typography and spacing (no clipped text or misaligned controls)
And primary actions remain tappable with expected labels and icons
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<img width="1462" height="680" alt="Screenshot 2026-04-13 at 4 30 22 PM"
src="https://github.com/user-attachments/assets/38255e3a-a6c7-4ada-9a5b-7a0b5406eba0"
/>
### **After**
<img width="1442" height="643" alt="Screenshot 2026-04-13 at 4 30 37 PM"
src="https://github.com/user-attachments/assets/5bf37578-baf5-4b7f-8391-2a9611bb11c1"
/>
## **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 tweaks to layout, spacing, and typography within
Money screens; main risk is minor UI regressions like
truncation/clipping on edge device sizes.
>
> **Overview**
> Improves visual cohesion across Money hub and activity screens by
adjusting padding/spacing, alignment, and typography in headers, section
headers, lists, and filter buttons.
>
> Updates action buttons and activity rows to better handle sizing and
truncation (larger icons/avatars, centered/stretch layouts,
`min-w-0`/`shrink` Tailwind classes), and lightly refines secondary text
weights and button container padding for consistency.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
5ae2126. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## Feature Flag Registry Drift Report Feature flag drift was detected between E2E tests and production. Download the [`drift-report` artifact](https://github.com/MetaMask/metamask-mobile/actions/runs/24060043070) for the full report. --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Priya <priya.narayanaswamy@consensys.net>
## **Description** New: Campaign Stats Screen A dedicated screen showing the user's personal performance in the campaign — their current return (positive in green, negative in red), total portfolio value, rank, tier (Bronze, Silver, Platinum), net deposit amount, days held, and whether they're Qualified or Pending. New: Tier-based Leaderboard The leaderboard now lets users filter by tier (Bronze, Silver, Platinum). Each entry shows rank, referral code, and return percentage. Users see their own position highlighted, plus a count of total participants in that tier. New: "Qualify for this rank" & "You're qualified" cards - If a user is pending, they see a card telling them exactly how much more they need to deposit and how many more days to hold to qualify. - Once they meet the requirements, the card flips to "You're qualified." New: After-Hours Trading popup When a user tries to swap an asset outside market hours, a popup appears explaining that trading is closed, shows a countdown to when markets reopen, and warns about wider price spreads. New: Eligibility warning popup If there aren't enough days left in the campaign to meet the holding requirement, a warning popup tells the user their new position won't count toward the campaign, with options to cancel or proceed anyway. New: "Entries closed" state If the campaign has ended and the user never opted in, the join button is locked and shows "Entries closed." Tapping it shows a message explaining they missed the opt-in window. Updated: Portfolio section Now shows each deposited asset with its current value, shares owned, and profit/loss percentage. Users can tap a position to swap it for a different asset, or tap a link to view their full activity history. Updated: Prize pool display Shows the current prize pool size and how much additional volume is needed to unlock the next reward tier. ## **Changelog** CHANGELOG entry: ondo campaign rewards - stats page ## **Screenshots/Recordings** - Active Campaign - Opted in Negative return but qualified <img width="952" height="1763" alt="negative-qualified" src="https://github.com/user-attachments/assets/0e27784a-f5ce-4033-b338-e2916a259427" /> <img width="952" height="1763" alt="negative-qualified-2" src="https://github.com/user-attachments/assets/d07d0535-b2a1-4603-b4b4-4be694dc33c7" /> Positive return but pending <img width="1025" height="1799" alt="positive-pending-1" src="https://github.com/user-attachments/assets/b4e231a0-a0af-45db-90a8-572551c8322d" /> <img width="1025" height="1799" alt="positive-pendin-2-leaderboard-bottom-20" src="https://github.com/user-attachments/assets/14e37219-9605-466b-b788-507527fce233" /> Leaderboard top 5 (in others its 18th position) <img width="943" height="539" alt="leaderboard-top-5" src="https://github.com/user-attachments/assets/55c98e89-0c94-494d-882b-b02516ef6731" /> Prize pool variants <img width="962" height="324" alt="prize-pool-fully-reached" src="https://github.com/user-attachments/assets/c154f79a-723b-4fa8-ba9b-5885b3fd541b" /> <img width="962" height="324" alt="prize-pool-unlock" src="https://github.com/user-attachments/assets/da6f91f0-d12c-4654-a87d-680412769d4d" /> Leaderboard page (positive return pending) <img width="1025" height="1799" alt="positive-pending" src="https://github.com/user-attachments/assets/636d6806-c6ee-4635-bd07-6e2761919db0" /> Stats page positive but pending <img width="952" height="1763" alt="positive-pending" src="https://github.com/user-attachments/assets/6d5c8d1f-e519-47b6-9b43-e26a4df7c8dc" /> Stats page positive & qualified <img width="951" height="1830" alt="positive-qualified-complete" src="https://github.com/user-attachments/assets/570f8f11-1d4e-415f-ab48-a0e70a747b47" /> Stats page but negative return and cashed out <img width="952" height="1763" alt="negative-qualified-cashed-out" src="https://github.com/user-attachments/assets/9298e079-30ff-4625-8ac1-eec3890df4fb" /> Open position or swap position but outside of market hours <img width="957" height="845" alt="open-position-market-hours" src="https://github.com/user-attachments/assets/52accff5-3d36-4e0b-af50-a2062fb58b78" /> Open position but can't qualify for tier treshold anymore <img width="1156" height="701" alt="not eligible" src="https://github.com/user-attachments/assets/b67d484a-0977-4d63-bec5-f4f414273ca4" /> - Not Opted in <img width="916" height="1813" alt="Screenshot from 2026-04-13 15-32-09" src="https://github.com/user-attachments/assets/afc04260-729d-4867-bdd8-7caad4db9527" /> <img width="916" height="1813" alt="Screenshot from 2026-04-13 15-32-12" src="https://github.com/user-attachments/assets/12cb1a91-c999-4f38-b535-e8aa8a6b6c4a" /> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adds new rewards navigation routes, screens, and bottom sheets with updated Ondo campaign eligibility/pending logic and new `minDeposit` data plumbing; mistakes could impact campaign UX and leaderboard/stats rendering but do not touch security-critical flows. > > **Overview** > Introduces a dedicated **Ondo campaign Stats** screen (`RewardsOndoCampaignStats`) and wires it into the rewards navigator, including navigation from the campaign details stats header. > > Adds new bottom sheets for **Pending** (`RewardsOndoPendingSheet`), **After-hours trading** (`OndoAfterHoursSheet`), and **Not eligible** (`OndoNotEligibleSheet`), and updates campaign details/portfolio/CTA flows to gate swaps/position actions when the user can no longer meet the `ONDO_GM_REQUIRED_QUALIFIED_DAYS` requirement. > > Extends Ondo leaderboard tier data with `minDeposit` and updates `OndoLeaderboard`/`CampaignStatsSummary` to show qualify messaging, open the pending sheet from pending tags/cards, unify stats error handling, and tweak prize pool/max-tier copy and various UI text/icon styles (including ET→EST strings). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit a7be45e. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: sophieqgu <sophieqgu@gmail.com>
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->
## **Description**
This branch finishes the Card Home migration to `CardController` and
fixes the behavior regressions introduced while moving card auth,
cardholder state, wallet data, and spending-limit flows away from the
old SDK/React Query orchestration.
The motivation for the change was to make `CardController` the source of
truth for Card state, instead of splitting responsibility across the
Redux `card` slice, SDK helpers, and deleted React Query hooks like
`useLoadCardData` / `useGetCardExternalWalletDetails`.
Key changes in this branch:
- **Card authentication and session state now come from
`CardController`**
- `CardAuthentication` uses `useCardAuth`.
- UI now reads controller-backed selectors such as
`selectIsCardAuthenticated`, `selectIsCardholder`,
`selectCardholderAccounts`, and `selectCardUserLocation`.
- Logout and session validation are handled through
`Engine.context.CardController`.
- Legacy auth verification helpers and side-effect flows were removed.
- **Card Home was migrated to controller-backed data and split into
smaller hooks/components**
- `CardHome.tsx` was refactored heavily into focused components and
hooks like `useCardHomeActions`, `useCardHomeAnalytics`, and
`useCardProvisioning`.
- Snapshot-based tests touched by this work were removed in favor of
explicit assertions.
- **Push provisioning was aligned with the new controller/provider
architecture**
- Provisioning eligibility was moved into the provider layer.
- The old Galileo-specific adapter path was removed in favor of the
controller adapter.
- US-only provisioning restrictions and provider-specific feature-flag
behavior were preserved.
- **Unauthenticated cardholder UX was added**
- Cardholders who are not authenticated now see teaser actions on Card
Home instead of a blocking login-required warning.
- Teaser actions route to Card authentication.
- Card authentication now shows an informational auth prompt banner for
those entry points.
- Terms and Conditions / Contact support remain visible in that state
while Logout stays hidden.
- **Spending Limit / delegation flows broken by the migration were
restored**
- Card Home now passes the full spending-limit payload again
(`priorityToken`, `allTokens`, `delegationSettings`,
`externalWalletDetailsData`) instead of only `{ flow }`.
- `CardHomeData` now carries `delegationSettings`.
- Supported tokens are enriched with `delegationContract`, which fixes
the `"Missing token configuration"` delegation failure.
- Spending Limit can pre-select the priority asset again and the token
picker no longer stalls on an infinite spinner.
- After successful delegation, `useSpendingLimit` now calls
`CardController.fetchCardHomeData()` so the updated
wallet/priority-token state appears automatically without requiring a
manual refresh.
- **Additional follow-up fixes and test coverage**
- Added/updated controller, provider, Card Home, Spending Limit,
provisioning, authentication, and utility tests.
- Replaced touched card snapshot tests with explicit assertions where
applicable.
## **Changelog**
CHANGELOG entry: Fixed MetaMask Card authentication, unauthenticated
cardholder actions, and spending limit/delegation refresh flows after
the CardController migration.
## **Related issues**
Fixes:
<!-- Add issue links if applicable -->
## **Manual testing steps**
```gherkin
Feature: Card controller migration and follow-up flow fixes
Background:
Given I have a build from this branch
And I have access to a MetaMask Card test account
Scenario: Card authentication uses controller-backed session state
Given I am logged out of Card
When I open Card and log in with a valid account
Then Card Home should load successfully
And authentication state should be preserved by CardController
When I log out from Card
Then CardController should clear the card session
And I should return to the logged-out Card state
Scenario: Unauthenticated cardholder sees teaser actions and auth prompt
Given I am a cardholder but I am not currently authenticated
When I open Card Home
Then I should see teaser actions for card management
And I should see Terms and Conditions and Contact support
And I should not see Logout
When I tap Manage limit
Then the Card authentication screen should open
And I should see the informational auth prompt banner
Scenario: Spending Limit opens with delegation-ready token data
Given I am authenticated on Card Home
And I have supported card assets available
When I tap Manage limit
Then the Spending Limit screen should open
And the priority asset should be pre-selected
When I open the Token selector
Then the asset list should load without an infinite spinner
Scenario: Delegation refreshes Card Home automatically
Given I am authenticated on Card Home
And I open Spending Limit for a token that is not yet enabled
When I complete delegation successfully
Then I should return to Card Home
And the token list and current priority token should refresh automatically
And I should not need to pull to refresh manually
Scenario: Push provisioning still respects provider/controller rules
Given I am authenticated on Card Home with a supported eligible card
When I review add-to-wallet availability
Then provisioning eligibility should reflect the provider response
And provider-specific feature flags should still be respected
```
## **Screenshots/Recordings**
### **Before**
N/A
### **After**
N/A
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Large refactor of `CardHome` data-flow and interaction handlers to
rely on `CardController`/new hooks, plus navigation/auth gating changes;
regressions are possible in card setup, spending-limit, and sensitive
actions (PIN/details/freeze). Mostly UI-layer changes but they touch
session/logout behavior and several user flows.
>
> **Overview**
> **Card Home is migrated to controller-backed state and decomposed into
smaller units.** `CardHome` now renders from `useCardHomeData()` and
`CardController` selectors/capabilities, with UI split into components
like `CardAlertSection`, `CardActionsButtons`, `CardImageSection`,
`CardBalanceDisplay`, `ManageCardOptions`, and `CardHomeFooter`, plus
extracted hooks for actions/analytics/provisioning.
>
> **Unauthenticated cardholder UX is changed from “blocked” to “teaser”
actions.** Manage options (view details/PIN, freeze toggle, cashback,
travel, manage card, etc.) can appear while unauthenticated but now
route to `Routes.CARD.AUTHENTICATION` with `showAuthPrompt: true`;
logout stays hidden.
>
> **Auth + location handling is adjusted in `CardAuthentication`.** The
screen reads `showAuthPrompt` from route params to show a new info
banner (`CardMessageBoxType.AuthPrompt`), and location selection is now
local state (`selectedLocation`) used during login rather than
immediately calling `CardController.setUserLocation`.
>
> **Behavioral/test updates.** Tests are updated to mock `useRoute`,
validate new teaser/navigation behavior, switch `CardHome` tests to
`useCardHomeData`, align freeze with separate `freeze/unfreeze`
mutations, update spending-limit copy expectations, and tighten
analytics expectations (don’t emit without a formatted balance).
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
3baa77b. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/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 change **bumps the build version once** in a dedicated job that calls **`update-latest-build-version.yml`**, then triggers **iOS and Android** through **`runway-ota-build-core`** in **parallel**. Both jobs use **`skip_version_bump: true`** and **`source_branch`** set to the **version-bump commit SHA** so both builds use the same tree. Downstream steps (PR comment + Slack) now require **both** platform jobs to succeed. ## **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/MCWP-521 ## **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.
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
🔍 Smart E2E Test Selection⏭️ Smart E2E selection skipped - draft PR All E2E tests pre-selected. |
|
Caution MetaMask internal reviewing guidelines:
|
OTA hotfix: branch
release/7.79.00.OTA_VERSIONinapp/constants/ota.tsisv7.79.00.7.79.0-ota.0(maps to Runway7.79.00) because auto-changelog validates all headers as strict SemVer.