Merged
Conversation
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** This PR removes the "Reset notifications" button which is not needed anymore, and it's currently broken anyway. Translation strings are also removed. <img width="394" height="742" alt="image" src="https://github.com/user-attachments/assets/4b29f6e0-8b84-4896-9757-4393d96d0b0b" /> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: Removed "Reset notifications" button from notifications list ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Primarily removes dead/broken UI and navigation wiring; main risk is missing a remaining reference to the removed route/string, but changes are otherwise non-functional. > > **Overview** > Removes the broken **“Reset notifications”** entry from notification settings by deleting the `ResetNotificationsButton`, the `ResetNotificationsModal` bottom sheet, and their associated tests/snapshots. > > Cleans up navigation by removing `Routes.SHEET.RESET_NOTIFICATIONS` and its route typing, and deletes related i18n strings across supported languages; also stabilizes `useNotifications` hook tests by properly mocking `usePushNotificationsToggle` and clearing mocks between tests. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 3be27b9. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Phase 3 analytics migration (Batch 3-10): migrate Onboarding/Account Import's ImportNewSecretRecoveryPhrase, ExperienceEnhancerModal, and Pna25BottomSheet from useMetrics/MetaMetrics to the new analytics system. **Reason**: Deprecate MetaMetrics in favour of the shared analytics utility and AnalyticsController. **Changes**: ImportNewSecretRecoveryPhrase, ExperienceEnhancerModal, and Pna25BottomSheet now use `useAnalytics` and `AnalyticsEventBuilder` from `app/components/hooks/useAnalytics` and `app/util/analytics`; test mocks updated to mock useAnalytics instead of useMetrics. ImportFromSecretRecoveryPhrase already used useAnalytics — no migration needed. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-302 (Batch 3-10) ## **Manual testing steps** ```gherkin Feature: Onboarding/Account Import analytics Scenario: user triggers an onboarding/account import flow event Given app is open and user is in an onboarding/account import flow When user performs an action that triggers analytics (e.g. import SRP completed, marketing consent modal accept/cancel, PNA25 notice viewed/closed) Then the event is tracked on Mixpanel ``` ## **Screenshots/Recordings** N/A – analytics migration, no UI change. ## **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** > Replaces the legacy `useMetrics` analytics hook with `useAnalytics` in onboarding/consent flows, which could change or break event emission/consent traits if the new builder/hook behavior differs. No functional UI changes, but tracking correctness is compliance- and telemetry-sensitive. > > **Overview** > Migrates analytics instrumentation in **ExperienceEnhancerModal**, **ImportNewSecretRecoveryPhrase**, and **Pna25BottomSheet** from legacy `useMetrics` to `useAnalytics`, updating event/builder usage (e.g., SRP import completion and PNA25 notice events) while keeping existing `MetaMetricsEvents` names. > > Updates Jest tests to mock `useAnalytics` and (for SRP import) swap `MetricsEventBuilder` references to `AnalyticsEventBuilder`, ensuring tracking assertions still validate emitted events/properties. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 09f4586. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Phase 3 analytics migration (Batch 3-11): migrate Hardware Wallet's `LedgerSelectAccount` component from `useMetrics` to the new analytics system. **Reason**: Deprecate MetaMetrics in favour of the shared analytics utility and AnalyticsController. **Changes**: `LedgerSelectAccount/index.tsx` now uses `useAnalytics` from `app/components/hooks/useAnalytics/useAnalytics` instead of `useMetrics`; test mocks updated to mock `useAnalytics` instead of `useMetrics`. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-302 (Batch 3-11) ## **Manual testing steps** ```gherkin Feature: Hardware Wallet analytics Scenario: user triggers a hardware wallet flow event Given app is open and user is in a hardware wallet flow When user performs an action that triggers analytics (e.g. open account selector, unlock account, forget device) Then the event is tracked on Mixpanel ``` ## **Screenshots/Recordings** N/A – analytics migration, no UI change. ## **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** > Swaps the analytics hook used by `LedgerSelectAccount` and updates its unit test mock; behavior should be equivalent but could affect event emission if the new hook differs in runtime wiring. > > **Overview** > Migrates hardware wallet `LedgerSelectAccount` analytics from the deprecated `useMetrics` hook to the new `useAnalytics` hook while keeping the same `trackEvent`/`createEventBuilder` call sites. > > Updates `LedgerSelectAccount` tests to mock `useAnalytics` instead of `useMetrics` so existing analytics-related assertions continue to run against the new hook. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit d71565b. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Phase 3 analytics migration (Batch 3-14): migrate Legal/Onboarding's terms-of-use utilities from `MetaMetrics.getInstance()` to the new analytics system. **Reason**: Deprecate MetaMetrics in favour of the shared analytics utility and AnalyticsController. **Changes**: `termsOfUse.ts` now uses `analytics.trackEvent()` and `AnalyticsEventBuilder` from `app/util/analytics`; test mocks updated to mock the analytics utility instead of `MetaMetrics.getInstance()`. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-302 (Batch 3-14) ## **Manual testing steps** ```gherkin Feature: Legal/Onboarding analytics Scenario: user triggers a terms of use flow event Given app is open and user has not yet accepted terms of use When user performs an action that triggers analytics (e.g. terms of use shown, terms accepted) Then the event is tracked on Mixpanel ``` ## **Screenshots/Recordings** N/A – analytics migration, no UI change. ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk refactor that swaps the event tracking implementation for terms-of-use shown/accepted; behavior should be equivalent but could impact whether/when these two events are emitted if the new analytics queueing differs from `MetaMetrics.getInstance()`. > > **Overview** > Migrates terms-of-use analytics emission from `MetaMetrics.getInstance().trackEvent`/`MetricsEventBuilder` to the shared `analytics.trackEvent` helper with `AnalyticsEventBuilder` for the `USER_TERMS_SHOWN` and `USER_TERMS_ACCEPTED` events. > > Updates `termsOfUse` unit tests to mock `app/util/analytics/analytics` and assert calls to `analytics.trackEvent` instead of mocking `MetaMetrics`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit f7c5c93. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Phase 3 analytics migration (Batch 3-15): migrate the ResetPassword view from `MetaMetrics.getInstance()` / `MetricsEventBuilder` to the new `analytics` utility and `AnalyticsEventBuilder`. **Reason**: Deprecate MetaMetrics in favour of the shared analytics utility and AnalyticsController. **Changes**: `ResetPassword/index.js` now uses `analytics.trackEvent()` and `AnalyticsEventBuilder` from `app/util/analytics`; test mocks updated to mock the analytics utility instead of MetaMetrics. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-302 (Batch 3-15) ## **Manual testing steps** ```gherkin Feature: Settings analytics Scenario: user triggers a password change event Given app is open and user is in Settings > Change Password flow When user performs an action that triggers analytics (e.g. password change confirmation) Then the event is tracked on Mixpanel ``` ## **Screenshots/Recordings** N/A – analytics migration, no UI change. ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk refactor limited to analytics plumbing in the password reset flow; main risk is mis-tracking or missing the `PASSWORD_CHANGED` event due to the API swap. > > **Overview** > Migrates `ResetPassword` analytics from legacy `MetaMetrics.getInstance()`/`MetricsEventBuilder` to the shared `analytics` utility with `AnalyticsEventBuilder`, keeping the `PASSWORD_CHANGED` event and its biometry-related properties. > > Updates the `ResetPassword` tests to mock `util/analytics/analytics` instead of `MetaMetrics`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 22501d0. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Phase 3 analytics migration (Batch 3-16): migrate selectors (`legalNotices`, `bridgeController`) from `MetaMetrics.getInstance()` to the new analytics system. **Reason**: Deprecate MetaMetrics in favour of the shared analytics utility and AnalyticsController. **Changes**: `legalNotices/index.ts` and `bridgeController/index.ts` now use `analytics.isEnabled()` from `app/util/analytics/analytics` instead of `MetaMetrics.getInstance().isEnabled()`; test mocks updated to mock the analytics utility instead of MetaMetrics. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-302 (Batch 3-16) ## **Manual testing steps** ```gherkin Feature: Selectors analytics Scenario: user triggers a selector-dependent flow event Given app is open and user is in a flow that relies on legalNotices or bridgeController selectors When user performs an action that triggers analytics (e.g. PNA25 notice display, bridge quote request) Then the event is tracked on Mixpanel ``` ## **Screenshots/Recordings** N/A – analytics migration, no UI change. ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk refactor that only swaps the opt-in check from `MetaMetrics.getInstance().isEnabled()` to `analytics.isEnabled()` in a couple of selectors and updates unit test mocks accordingly. > > **Overview** > Migrates selector logic in `bridgeController` and `legalNotices` off deprecated `MetaMetrics.getInstance()` and onto the shared `analytics` helper. > > `participateInMetaMetrics` (bridge app state) and the PNA25 notice gating check now call `analytics.isEnabled()`, and the `legalNotices` selector tests were updated to mock the new analytics utility instead of `MetaMetrics`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 97d418a. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…nd bridge transactions (#26701) ## **Description** The "View on block explorer" button on the Bridge/Swap Transaction Details screen was broken for both swaps and bridge transactions — pressing it did nothing. Root causes: - Swap transactions: `navigation.navigate(Routes.BROWSER.VIEW, ...)` was called directly, but `BROWSER.VIEW` is a nested screen inside the `BROWSER.HOME` tab navigator. React Navigation silently ignores navigation calls to nested screens made from outside their parent. Additionally, navigating to a tab navigator replaces the current stack, so the back button would return to the home screen instead of activities. - Bridge transactions: `navigation.navigate(Routes.BRIDGE.MODALS.TRANSACTION_DETAILS_BLOCK_EXPLORER, ...)` was called directly, but this screen is nested inside `BridgeModalStack` (registered as `Routes.BRIDGE.MODALS.ROOT`). Same silent failure. Fix: - Swap path now uses `Routes.WEBVIEW.MAIN` → `Routes.WEBVIEW.SIMPLE`, which pushes a `WebView` on top of the current stack (back button returns to Transaction Details correctly) - Bridge path now navigates to `Routes.BRIDGE.MODALS.ROOT` with screen: `TRANSACTION_DETAILS_BLOCK_EXPLORER` as a nested param - Tightened the condition from a bare else to else if (isBridge) to prevent a swap with an unresolved explorer URL from accidentally opening the bridge modal ## **Changelog** CHANGELOG entry: Fixed "View on block explorer" button not working on Bridge/Swap Transaction Details screen ## **Related issues** Fixes: #26628 ## **Manual testing steps** ```gherkin Feature: View on block explorer from Transaction Details Scenario: user views a completed swap on block explorer Given user has a completed swap transaction (same-chain) When user taps the transaction in Activity to open Transaction Details And user taps "View on block explorer" Then a WebView opens showing the block explorer for that transaction And tapping back returns the user to Transaction Details Scenario: user views a completed bridge on block explorer Given user has a completed bridge transaction (cross-chain) When user taps the transaction in Activity to open Transaction Details And user taps "View on block explorer" Then a bottom sheet appears with source and destination chain explorer options When user taps one of the explorer options Then a WebView opens showing that chain's block explorer for the transaction ``` ## **Screenshots/Recordings** `~` ### **Before** https://github.com/user-attachments/assets/9030e42a-32a5-4661-bc00-d4953ae17850 ### **After** https://github.com/user-attachments/assets/26da74e6-353b-4df9-9be2-7f45f00105fe ## **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** > Changes React Navigation targets for the “View on block explorer” flow and bridge explorer modal buttons, which is user-facing and could regress routing/back-stack behavior if route params or navigator structure differ across entry points. > > **Overview** > Fixes the broken “View on block explorer” actions in Bridge/Swap transaction details by updating navigation to valid parent/nested routes. > > Swaps now open the in-app `WEBVIEW` (`Routes.WEBVIEW.MAIN` → `Routes.WEBVIEW.SIMPLE`) instead of `Routes.BROWSER.VIEW`, while bridges now navigate via `Routes.BRIDGE.MODALS.ROOT` to show the explorer-selection bottom sheet; the fallback logic is tightened to only open the modal for actual bridge transactions. > > Updates/expands unit tests to mock navigation and assert the new webview/modal navigation behavior, including pressing source/destination explorer buttons in `BlockExplorersModal`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 77221e0. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…works in transaction details (#26659) ## **Description** `getBlockExplorerForChain()` in `TransactionDetails` only resolved block explorer URLs for hardcoded built-in networks (Mainnet, Linea, Sepolia) and user-added custom RPC networks. Popular networks (Arbitrum, Polygon, BNB Chain, etc.) are neither — they aren't stored in `networkConfigurations` — so the method fell through to `NO_RPC_BLOCK_EXPLORER`, hiding the "View on X" link entirely. The fix adds a `PopularList` lookup as a fallback, matching the pattern already used correctly in useBlockExplorer.ts. ## **Changelog** CHANGELOG entry: Fixed a bug where transactions on popular networks (Arbitrum, Polygon, BNB Chain, etc.) were missing the block explorer link in transaction details ## **Related issues** Fixes: #26419 ## **Manual testing steps** ```gherkin Feature: Block explorer link in transaction details Scenario: user views a transaction from a Popular network Given the user has transactions on Arbitrum, Polygon, or BNB Chain And the activity feed is filtered by "Popular networks" When user taps a confirmed transaction from one of those networks Then a "View on Arbiscan" / "View on Polygonscan" / "View on Bscscan" link appears And tapping it opens the correct block explorer tx URL in the webview Scenario: user views a transaction on Ethereum Mainnet Given the user has transactions on Ethereum Mainnet When user taps a confirmed transaction Then a "View on Etherscan" link still appears (regression check) ``` ## **Screenshots/Recordings** `~` ### **Before** https://github.com/user-attachments/assets/0b15c664-e62e-4811-94f6-e12687454025 ### **After** https://github.com/user-attachments/assets/8c71420a-f95a-4ebe-ba4c-dedd7cfebc0e ## **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** - [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 fix that only changes how the transaction details screen resolves a block explorer URL, with added test coverage to prevent regressions. > > **Overview** > Fixes missing **“View on …”** links in `TransactionDetails` for *popular networks* that aren’t present in `networkConfigurations` by falling back to `PopularList` to resolve `rpcPrefs.blockExplorerUrl`. > > Adds unit tests ensuring the correct explorer link text/URL is produced for Arbitrum, Polygon, and BNB Chain, alongside existing mainnet/custom-network coverage. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 0e7e142. 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** Extract various logic into separate pure functions and hooks. <!-- 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/SWAPS-4188 ## **Manual testing steps** ```gherkin This PR introduce no change to business logic. Ensure that no regressions got introduced. ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Mostly refactoring with broad surface-area touch in Bridge quoting/fee display and validation filtering; moderate risk of UI regressions around fee formatting and when quote sections render/clear on expiry. > > **Overview** > **Refactors Bridge quote presentation logic into reusable utilities/hooks.** Network-fee formatting is extracted to `formatNetworkFee` + `useFormattedNetworkFee`, and gas-sponsorship logic is moved into `useIsNetworkGasSponsored` + `useShouldRenderGasSponsoredBanner`, with gasless detection centralized in `isGaslessQuote`. > > **Hardens quote-driven UI and data selection.** `BridgeView` now avoids rendering the bottom action section when there’s no `activeQuote` (fixing an expiry/redirect edge case), and `useBridgeQuoteData` adds `validQuotes` by filtering sorted quotes to those matching the selected destination token and non-expired state. > > **Consolidates fiat formatting.** The existing `useFiatFormatter` hook is simplified to delegate to a new shared `util/formatFiat` helper, with extensive new unit tests added across the new hooks/utilities. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 9096d32. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…ity (#26676) <!-- 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** Part "4.5" of the hardware wallet connection & error management overhaul. This does not introduce user facing changes. Will close: - https://consensyssoftware.atlassian.net/browse/MUL-1495 Final implementation will look like this ([Figma designs](https://www.figma.com/design/1F3yNWYLOVPFpTPeJugH20/SWAP?node-id=11110-19571&t=tPMZNNiwCgbDfegd-0)): <img width="1404" height="631" alt="image" src="https://github.com/user-attachments/assets/68850711-f53b-4060-8b47-6faceb67f82f" /> Reference feature branch: #25519 ## **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** no manual testing steps ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [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** > Refactors core hardware-wallet connection flow and transport monitoring into new hooks, which could subtly change state transitions (scanning/connecting/error/ready) or cleanup behavior. No new security surface, but regressions could impact device connectivity and error handling. > > **Overview** > Refactors `HardwareWalletProvider` by extracting adapter lifecycle, transport monitoring, device discovery, and connection/retry/close logic into new hooks (`useAdapterLifecycle`, `useTransportMonitoring`, `useDeviceDiscovery`, `useDeviceConnectionFlow`) and wiring the provider to these hook APIs. > > Simplifies the connecting UI contract by removing adapter-provided `connectionTips`: `getConnectionTips()` is removed from `HardwareWalletAdapter` (and Ledger/NonHardware adapters), `HardwareWalletBottomSheet` no longer accepts `connectionTips`, and `ConnectingContent` now derives tips via `getConnectionTipsForWalletType()` in `helpers.ts`. Also makes bottom-sheet `onClose` required and updates tests accordingly. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit b84edf3. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Add comprehensive analytics events to the Unified Buy v2 flow, covering every user interaction across Token Selection and Amount Input screens. Flow identity uses **`ramp_type` only** (e.g. `'UNIFIED BUY 2'`); for a single dimension in Segment and Data Council. **Reason for change:** Measure UB2 funnel conversion and drop-offs; compare UB2 vs UB1. **Improvement:** 18 new events + enhanced existing events; screen viewed once per visit; Change provider only in Payment Selection modal. ### Changes - **18 new events:** Ramps Screen Viewed, Back Button Clicked, Network Filter Clicked, Token Searched, Settings Clicked, Setting Option Clicked, Payment Method Selector Clicked, Quick Amount Clicked, Change Provider Button Clicked, Provider Selected, Continue Button Clicked (KPI), Terms Consent Clicked, External Link Clicked, Close Button Clicked, Quote Error, Quote Error Tooltip Clicked, Unsupported Token Tooltip Clicked, Toast Button Clicked. - **Existing enhanced:** `RAMPS_TOKEN_SELECTED` and `RAMPS_BUTTON_CLICKED` accept `ramp_type: 'UNIFIED BUY 2'`. - **Screens:** TokenSelection, BuildQuote, PaymentSelectionModal (Change provider only). ### Related PRs - Segment schema: Consensys/segment-schema#471 ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TRAM-3028 ## **Manual testing steps** ```gherkin Feature: Unified Buy v2 analytics events Scenario: user completes token selection and amount input in UB2 flow Given Unified Buy v2 is enabled (MM_RAMPS_UNIFIED_BUY_V2_ENABLED=true) and user is on Buy from home When user opens Token Selection then searches token, filters by network, selects token, opens Amount Input, taps quick amount, opens payment selector, taps Change provider in Payment Selection modal, taps Settings, then taps Continue Then Segment debugger shows Ramps Screen Viewed (once per visit per screen), Ramps Token Searched, Ramps Network Filter Clicked, Ramps Token Selected with ramp_type UNIFIED BUY 2, Ramps Quick Amount Clicked, Ramps Payment Method Selector Clicked, Ramps Change Provider Button Clicked, Ramps Settings Clicked, Ramps Continue Button Clicked with no feature_flag_unified_buy_v2 in payloads ``` ## **Screenshots/Recordings** <div> <a href="https://www.loom.com/share/ac98af2b79cc41c1a37336329fd06cb5"> <p>Ramps Unified Buy V2 Analytics Walkthrough - Watch Video</p> </a> <a href="https://www.loom.com/share/ac98af2b79cc41c1a37336329fd06cb5"> <img style="max-width:300px;" src="https://cdn.loom.com/sessions/thumbnails/ac98af2b79cc41c1a37336329fd06cb5-564c55257a094c01-full-play.gif#t=0.1"> </a> </div> ## **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/changes analytics instrumentation across multiple ramp screens and entry points, which is moderately risky due to potential schema regressions or event-volume changes (but no funds/auth logic is altered). > > **Overview** > Adds **Unified Buy v2 (UB2)** analytics instrumentation across the ramps flow, introducing a new `ramp_type` value (`UNIFIED_BUY_2`) and a set of new MetaMetrics events (screen views, back/close, settings, quick amounts, provider/payment selection, external links, quote errors, tooltips, etc.). > > Updates existing ramps events to match the new schema (notably renaming the `RAMPS_BUTTON_CLICKED` property from `text` to `button_text`) and wires UB2-aware `ramp_type` selection into multiple entry points (e.g., `BalanceEmptyState`, `FundActionMenu`, `AccountsMenu`, Card add-funds deposit). > > Extends navigation header helpers to support an optional `onBackPress` callback so screens can track back navigation, and adjusts unit/smoke tests and snapshots accordingly. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 2fb77db. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Cursor <cursoragent@cursor.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 geolocation mock to return plain text (us-ca) instead of a JSON
object, matching the real API's response format. The app reads this with
response.text(), so a JSON object gets stringified and can produce
malformed URLs when used in path segments.
- Support string responses in the mock server layer — both
MockServerE2E.ts and mockHelpers.ts now return string responses as raw
text instead of JSON-serializing them.
- Add catch-all mock for the legacy /regions/{region}/tokens endpoint to
DEFAULT_RAMPS_API_MOCKS, preventing unmocked live API calls.
- On mUSD convert disables the synchronization only after tapping the
CTA to make sure it is displayed before on a first time user.
This PR addresses a gigantic mocking error on default mocks,
specifically speaking the onramp geolocation. This issue was causing
random flakiness due to a bad formatted url coming from a mock.
Example:
`https://on-ramp-cache.uat-api.cx.metamask.io/regions/%7B%22id%22:%22/regions/us-ca%22,%22name%22:%22california%22,%22emoji%22:%22%F0%9F%87%BA%F0%9F%87%B8%22,%22detected%22:true%7D/tokens?action=deposit&sdk=2.1.5`
(see [run
reference](https://github.com/MetaMask/metamask-mobile/actions/runs/22429213914/job/64944977184))
The reason for this is that the request for
`https://on-ramp.<ENV>-api.cx.metamask.io/geolocation` was returning
```typescript
{
id: region.id,
name: region.name,
emoji: region.emoji,
detected: true,
}
```
when in reality the geolocation endpoint returns plaintext containing
the country code for the user's location. This PR adds the ability to
the mock server to accept plain text instead of json as a response and
fixes the mocking.
It then caused perps tests to fail due to region not available since the
[fallback country (US) is currently being
blacklisted](https://github.com/MetaMask/metamask-mobile/blob/main/builds.yml#L40)
and this was the country used in the onramps default geolocation mock.
## CI changes
`ref` was removed from the shard runner checkout as this was causing
inconsistencies with the way every single workflow uses checkout. Builds
do **not** contain a ref which results in building apps with a merge
commit instead of the branch commit while tests would run with a
different ref resulting in failed tests for changes that were already
fixed on main.
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry:
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Moderate risk: changes test infrastructure by installing a
lifecycle-wide `unhandledRejection` filter and altering mock server
shutdown behavior, which could mask unexpected promise rejections if the
filter is too broad. Functional app code is untouched; impact is limited
to E2E reliability and mocking fidelity.
>
> **Overview**
> Fixes onramp geolocation mocking to return *plain text* region codes
(matching the real API) and updates the mocking layer (`MockServerE2E`,
`setupMockRequest`) to return raw string bodies without
JSON-serializing; adds a catch-all mock for legacy
`/regions/{region}/tokens` to prevent live calls.
>
> Hardens E2E infra by adding `MockServerE2E.startDraining()` (return
503 during cleanup) and installing a lifecycle-wide filter that
suppresses mockttp `Error('Aborted')` unhandled rejections, with cleanup
integrated into `withFixtures`.
>
> Stabilizes flaky Detox flows: waits for elements to stop moving before
taps (wallet token rows, confirm button), relaxes a swap analytics
assertion to *min length*, adjusts unified-buy analytics region
assertions to expect a string, adds perps geolocation mocking
(non-blocked region), and tweaks/simplifies a few smoke tests (mUSD sync
timing, SOL send assertions).
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
27fc622. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…nterface (#26703) ## **Description** Consolidates scattered feature flag resolution in PredictController into a single `resolveFeatureFlags()` method and injects flags into PolymarketProvider via a constructor callback. **Problem**: Feature flags (liveSportsLeagues, feeCollection, marketHighlights) were resolved independently in 3 separate PredictController methods (`getMarkets`, `getMarket`, `previewOrder`), each calling `RemoteFeatureFlagController:getState` and unwrapping flags ad-hoc. These flags were then passed as method parameters to PolymarketProvider. **Solution**: - New `PredictFeatureFlags` type consolidating all predict feature flags - New `resolveFeatureFlags()` private method on PredictController — single resolution point - PolymarketProvider now takes a `getFeatureFlags` callback in constructor and reads flags internally - Cleaned `PredictProvider` interface — removed per-method flag parameters (`liveSportsLeagues`, `feeCollection`) - Removed `liveSportsLeagues` from `GetMarketsParams` (internal concern, not caller-facing) This is a **pure refactor** — zero behavior changes. Foundation for upcoming Permit2 fee authorization support. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/PRED-715 ## **Manual testing steps** ```gherkin Feature: Predict feature flag resolution refactor Scenario: user places prediction market orders as before Given user has Predict feature enabled and is in a supported region When user browses markets, views market details, and previews/places orders Then all functionality works identically to before (no behavior changes) ``` ## **Screenshots/Recordings** N/A — pure refactor, 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 - [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 Predict market fetching and order preview paths by changing how feature flags are resolved and threaded into the Polymarket provider. Risk is mainly around mismatched defaults or missing flag injection impacting live sports overlays, highlights ordering, or fee collection in previews. > > **Overview** > **Refactors Predict feature-flag plumbing** by introducing `PredictFeatureFlags` and a single `PredictController.resolveFeatureFlags()` that reads remote flags (live sports leagues, market highlights, fee collection) and supplies them to `PolymarketProvider` via a `getFeatureFlags` constructor callback. > > `PolymarketProvider` now consumes flags internally (no longer accepts `liveSportsLeagues`/`feeCollection` as method params), and the `PredictProvider`/`GetMarketsParams` types are simplified accordingly. Tests are updated to match the new provider constructor + method signatures and to assert fee collection defaults are applied during `previewOrder` and highlight fetching. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit fdb4a95. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
#26696) ## **Description** This PR adds `@deprecated` JSDoc comments with README links to 20 component library files that have replacements in the MetaMask Design System (MMDS). The deprecation messages provide clear migration paths for developers by: 1. Indicating which MMDS component to use as a replacement 2. Warning that the API may have changed 3. Linking directly to the component's README in the MMDS repository This work improves developer experience by making it easier to migrate from legacy component library components to the standardized MMDS components. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-494 ## **Manual testing steps** ```gherkin Feature: JSDoc deprecation comments Scenario: developer views deprecated component Given a developer opens a component library file When developer hovers over a deprecated component import Then the IDE should display the @deprecated JSDoc comment with migration guidance And the comment should include a link to the MMDS component README ``` ## **Screenshots/Recordings** N/A - Documentation-only changes ### **Before** Components had either no deprecation messages or minimal ones without full context. ### **After** All 20 components now have consistent deprecation messages following this pattern: ```javascript /** * @deprecated Please update your code to use `ComponentName` from `@metamask/design-system-react-native`. * The API may have changed — compare props before migrating. * @see {@link https://github.com/MetaMask/metamask-design-system/blob/main/packages/design-system-react-native/src/components/ComponentName/README.md} */ ``` **Components updated:** - Avatar components: AvatarAccount, AvatarBase, AvatarFavicon, AvatarGroup, AvatarIcon, AvatarNetwork, AvatarToken - Badge components: BadgeBase, BadgeNetwork, BadgeNotifications, BadgeWrapper - Button components: Button, ButtonIcon, ButtonLink, ButtonPrimary, ButtonSecondary - Form components: Checkbox, TextField - Other components: Card, Icon, Text ## **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 (N/A - documentation only) - [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 change: adds/standardizes `@deprecated` JSDoc blocks and external README links without altering component runtime behavior. Main risk is minor lint/formatting or tooling differences in how IDEs surface these comments. > > **Overview** > Adds consistent `@deprecated` JSDoc annotations across legacy component-library UI components (avatars, badges, buttons, checkbox, text field, icon, text), pointing developers to the equivalent `@metamask/design-system-react-native` replacements. > > Each deprecation notice now includes a migration caution about potential API differences and a direct link to the relevant MMDS README for the replacement component. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 167e357. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Update the Xcode stack from osx-xcode-16.3.x to osx-xcode-26.2.x to enable building with iOS SDK 26. This prepares for the April 2026 App Store requirement that apps must be built with Xcode 26 or later. This PR updates the ruby version to 3.2.9 according to the [Bitrise stack availability](https://bitrise.io/stacks/stack_reports/osx-xcode-26.2.x/). It also updates the Ruby Version source for the `ci/docker` step. It also requires an update to the .github-tools repo here: https://github.com/MetaMask/github-tools/pull/220/commits <!-- 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? AI agent: Be specific about what you changed and why. Include context about the fix/feature, not generic descriptions. --> ## **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) AI agent: Use format `CHANGELOG entry: [fix/feat/chore]: [User-facing description in past tense]`. Examples: `fix: resolved token name display issue`, `feat: added dark mode toggle`, `chore: updated dependencies`. For non-user-facing changes, use `CHANGELOG entry: null`. --> CHANGELOG entry: null ## **Related issues** <!-- AI agent: Replace with `Fixes: #[ISSUE_NUMBER]` using the actual issue number you're implementing. --> Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-329 ## **Manual testing steps** <!-- AI agent: Write specific, contextual Gherkin steps based on what you actually implemented. Do NOT use generic placeholders like "my feature name". Be concrete about the feature, scenario, and 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** Successful Bitrise: https://app.bitrise.io/build/d8ffdf86-23f8-4476-afef-1b4dda76a554 Successful CI (note there a some flaky flask tests): https://github.com/MetaMask/metamask-mobile/actions/runs/22237789978?pr=25136 Successful build.yml: https://github.com/MetaMask/metamask-mobile/actions/runs/22241562536 ## **Pre-merge author checklist** <!-- AI agent: Check ALL boxes in this section (mark all as [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). - [ ] 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** <!-- AI agent: Leave ALL boxes unchecked ([ ]) - these are for reviewers to check, not the author. --> - [ ] 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 changes core CI/build infrastructure (Bitrise Xcode stack, Ruby toolchain, and shared `setup-e2e-env` action), which can break iOS/Android build and E2E workflows if the new environment has compatibility issues. > > **Overview** > Updates CI and Bitrise build environments to support iOS SDK 26 by moving Bitrise stacks to `osx-xcode-26.2.x` and aligning the Ruby toolchain to `3.2.9` (including `.ruby-version`, `ios/Gemfile`, `Gemfile.lock`, and GitHub Actions `ruby/setup-ruby`). > > Refreshes GitHub Actions workflows to use `MetaMask/github-tools` `setup-e2e-env@v1.7` across build and E2E pipelines, and updates the Docker CI image’s ruby-build pin used to install the newer Ruby. > > Bumps iOS/Bitrise build numbers from `3607` to `3821` (including `bitrise.yml` envs and `CURRENT_PROJECT_VERSION` in the Xcode project). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 01116b4. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: tommasini <46944231+tommasini@users.noreply.github.com> Co-authored-by: tommasini <tommasini15@gmail.com> Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** This PR adds **HeaderStandardAnimated**, a scroll-driven animated header component to `app/component-library/components-temp/`. The header shows a full title section (e.g. with `TitleStandard`) when at the top of the scroll, and animates to a compact center title when the user scrolls past that section. **Reason for change:** Screens with a large title block (e.g. Perps market detail) need a header that stays visible and collapses to a compact title as the user scrolls. This component provides that pattern with Reanimated-driven animation tied to scroll position. **What changed:** 1. **HeaderStandardAnimated** (`app/component-library/components-temp/HeaderStandardAnimated/`) - New component that extends the header pattern from `HeaderCompactStandard` and requires `scrollY` and `titleSectionHeight` shared values to drive the center-title animation. - Renders a `HeaderBase` with optional back/close buttons, title, subtitle, or custom children. The center content is wrapped in an `Animated.View` whose opacity and translateY are derived from scroll (compact title appears when `scrollY >= titleSectionHeight`). - Props: `scrollY`, `titleSectionHeight` (required), plus title/subtitle/children, `onBack`/`backButtonProps`, `onClose`/`closeButtonProps`, `startButtonIconProps`/`endButtonIconProps`, `testID`, `twClassName`, and other `HeaderBase` props. 2. **useHeaderStandardAnimated** - New hook that returns `scrollY`, `titleSectionHeightSv`, `setTitleSectionHeight`, and `onScroll` for use with `HeaderStandardAnimated` and a `ScrollView`. Consumers call `setTitleSectionHeight` from the title section’s `onLayout` and pass `onScroll` to the `ScrollView`. 3. **Stories** - `HeaderStandardAnimated.stories.tsx`: Default (title + back) and WithSubtitle, both with scrollable content and the hook wiring. 4. **Unit tests** - `HeaderStandardAnimated.test.tsx`: Rendering (title, subtitle, children, testIDs via child prop objects), back/close button behavior and callbacks, and `startButtonIconProps` priority. Uses mocked Reanimated and safe area; shared values use a full `SharedValue<number>`-shaped mock. - `useHeaderStandardAnimated.test.ts`: Return shape, initial values, and that `setTitleSectionHeight` and `onScroll` update the shared values. 5. **Storybook** - `HeaderStandardAnimated` stories registered in `.storybook/storybook.requires.js`. ## **Changelog** This PR is not end-user-facing; it adds a new internal header component for scroll-driven screens. CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-287?atlOrigin=eyJpIjoiZThjYTU4Y2UyODcwNDJlMWJjMWQ0ZTQ1YmI0NjVhMGUiLCJwIjoiaiJ9 ## **Manual testing steps** ```gherkin Feature: HeaderStandardAnimated component Scenario: Default header with scroll shows compact title when scrolled Given the app is open with Storybook or a screen using HeaderStandardAnimated When the user views the header with a scrollable list below a title section Then the full title section is visible at the top When the user scrolls down past the title section Then a compact center title appears in the header and the transition is animated Scenario: Back and close buttons work Given a HeaderStandardAnimated with onBack and onClose When the user taps the back button Then onBack is invoked When the user taps the close button Then onClose is invoked ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> N/A – new component. ### **After** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/85c5f28c-86f4-4efb-89bf-26223de637f3 ## **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 because this is additive and isolated to the component library (`components-temp`) plus Storybook registration, with unit tests covering basic rendering and button-callback behavior. > > **Overview** > Adds `HeaderStandardAnimated`, a new `components-temp` header wrapper around `HeaderCompactStandard` that animates the centered title/subtitle in based on `scrollY` and a measured `titleSectionHeight` shared value. > > Introduces `useHeaderStandardAnimated` to provide the required Reanimated `SharedValue`s and `onScroll` handler, along with Storybook stories demonstrating the scroll behavior and unit tests validating rendering and back/close/start-button callback precedence. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e06f5c5. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Updates the `/create-bug` Claude Code skill command to include a full root cause analysis workflow (Step 6) with three phases: - **6a**: Investigate root cause — trace through the code to identify exact files, lines, and logic - **6b**: Identify regression PRs — check git history against previous releases - **6c**: Scope analysis — search for same pattern across codebase, file separate bugs for other affected features Also updates the comment format to include all required sections. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: [MMQA-1523](https://consensyssoftware.atlassian.net/browse/MMQA-1523) ## **Manual testing steps** ```gherkin Feature: Create Bug Skill Root Cause Analysis Scenario: user runs /create-bug and opts into root cause investigation Given user has Claude Code open in the metamask-mobile repo When user runs /create-bug and files a bug report And user opts into root cause investigation Then Claude performs root cause investigation (6a) And Claude identifies regression PRs by comparing release branches (6b) And Claude performs scope analysis to find same pattern elsewhere (6c) And Claude posts a comment with summary, regression PRs, error flow, scope of impact, key files, suggested fix, and related bug links ``` ## **Screenshots/Recordings** ### **Before** N/A ### **After** Run `/create-bug` in Claude Code terminal and opt into root cause investigation to see the full 3-phase workflow. ## **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. [MMQA-1523]: https://consensyssoftware.atlassian.net/browse/MMQA-1523?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## **Description** Phase 3 analytics migration (Batch 3-17): migrate Sample Feature's components and hooks from `useMetrics`/`MetricsEventBuilder` to the new `useAnalytics`/`AnalyticsEventBuilder` analytics system. **Reason**: Deprecate MetaMetrics in favour of the shared analytics utility and AnalyticsController. **Changes**: `SamplePetNamesForm`, `SampleCounterPane`, and `SampleFeatureDevSettingsEntryPoint` now use `useAnalytics()` from `app/components/hooks/useAnalytics/useAnalytics` and `createEventBuilder` from the hook instead of `useMetrics()` and `MetricsEventBuilder`; test mocks updated to mock the `useAnalytics` hook with a chainable builder instead of `useMetrics`. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-302 (Batch 3-17) ## **Manual testing steps** ```gherkin Feature: Sample Feature analytics Scenario: user triggers a Sample Feature flow event Given app is open and user is in a Sample Feature flow When user performs an action that triggers analytics (e.g. increment counter, add pet name, navigate to sample feature) Then the event is tracked on Mixpanel ``` ## **Screenshots/Recordings** N/A – analytics migration, no UI change. ## **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: this is a refactor of analytics event building/tracking in a non-production sample feature, with corresponding unit test updates. Main risk is mis-tracked or missing events due to the new builder/mocking semantics. > > **Overview** > Updates SampleFeature event tracking to use `useAnalytics()` and its `createEventBuilder` instead of `useMetrics()`/`MetricsEventBuilder` in `SampleCounterPane`, `SamplePetNamesForm`, and the dev-settings entry point. > > Adjusts analytics event definitions (`analytics/events.ts`) and rewrites unit tests to mock/verify the new `useAnalytics` hook and builder chaining, plus updates SampleFeature docs/e2e docs to refer to **Analytics** (not MetaMetrics). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 2dce2e4. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->
## **Description**
Updates the Provider Selection modal UI with improved quote-driven
sorting, provider tags, skeleton loading states, and a redesigned
payment method banner.
### Payment Method Banner
- Replaced the plain "Quotes displayed for {paymentMethod}" text with a
full-width banner component featuring a circular payment method icon on
the left and the descriptive text left-aligned beside it, matching the
latest design spec.
### Quote-Based Provider Sorting
- Providers with quotes are now sorted by the API's `QuoteSortOrder`
reliability ranking (via `quotes.sorted`), placing the most reliable
provider at the top.
- Providers without quotes are pushed to the bottom of the list, sorted
alphabetically, with an "Other options" text separator between the two
groups.
### Skeleton Loading State
- When quotes are loading, the provider list is replaced with a skeleton
placeholder (5 rows) instead of showing unsorted providers with
individual loading spinners. Once quotes resolve, providers render in
their sorted order.
### Provider Tags
- Each provider can display one tag below its name: **Previously used**,
**Most reliable**, or **Best rate**.
- Tags use the quote's `metadata.tags` (`isMostReliable`, `isBestRate`)
from the API response, and `getOrdersProviders` from Redux to identify
previously used providers from completed order history.
- Precedence when a provider qualifies for multiple tags: Previously
used > Most reliable > Best rate.
### Conditional Back Button
- The header back arrow is now only shown when the Payment Selection
modal is in the navigation stack (i.e., the user navigated from payment
selection to provider selection). When the provider modal is opened
directly (e.g., from error recovery or token-not-available flows), the
back button is hidden since there's nothing to go back to.
## Changed Files
- `ProviderSelection.tsx` — Banner, skeleton, sorting, tags, conditional
back button
- `ProviderSelectionModal.tsx` — Passes `ordersProviders` from Redux,
`showBackButton` from navigation state
- `ProviderSelection.test.tsx` — Updated test for skeleton loading
behavior
- `en.json` — Added i18n strings: `other_options`, `previously_used`,
`best_rate`, `most_reliable`
<!--
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: Updates ramp provider selection modal UI
## **Related issues**
Fixes:
https://consensyssoftware.atlassian.net/browse/TRAM-3307
https://consensyssoftware.atlassian.net/browse/TRAM-3187
## **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**

<img width="353" height="355" alt="Screenshot 2026-02-28 at 5 30 22 AM"
src="https://github.com/user-attachments/assets/5b089b35-d302-4c82-8ef5-994e697bac4a"
/>
<img width="360" height="754" alt="Screenshot 2026-02-28 at 5 30 01 AM"
src="https://github.com/user-attachments/assets/cc720ccf-02d6-4681-ac88-303b59775d51"
/>
<img width="353" height="747" alt="Screenshot 2026-02-28 at 5 29 14 AM"
src="https://github.com/user-attachments/assets/04cbedf4-d233-4576-8bd8-c79c6ce0115d"
/>
<img width="341" height="742" alt="Screenshot 2026-02-28 at 5 29 00 AM"
src="https://github.com/user-attachments/assets/ec1e2031-0c01-4c59-85ad-e9fdccaddabc"
/>
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Changes provider ordering/visibility and quote presentation logic in
the provider selection flow (sorting, skeleton states, tags, and
back-button behavior), which could affect user selection and navigation
in edge cases. No security- or data-sensitive logic is introduced.
>
> **Overview**
> Updates `ProviderSelection` to be *quote-driven*: providers with
successful quotes are sorted by the API reliability order and shown
above an **“Other options”** separator, while providers without quotes
are pushed below and alphabetized.
>
> Replaces the prior “show providers while loading” behavior with a
dedicated skeleton list, updates the payment-method header to a banner
with an icon, and adds per-provider tags (**Previously used**, **Most
reliable**, **Best rate**) derived from order history and quote
metadata.
>
> `ProviderSelectionModal` now conditionally shows the back button only
when the payment selection modal exists in the navigation stack and
passes `ordersProviders` from Redux; tests/snapshots and i18n strings
were updated accordingly.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
790f8c3. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description** Phase 3 analytics migration (Batch 3-13): migrate Network Management's components and hooks from `useMetrics` to the new analytics system (`useAnalytics`). **Reason**: Deprecate MetaMetrics in favour of the shared analytics utility and AnalyticsController. **Changes**: `ManageNetworks`, `NetworkMultiSelector`, `NetworkManager`, and `MultiRpcModal` now use `useAnalytics` from `app/components/hooks/useAnalytics/useAnalytics` and import `MetaMetricsEvents` from `app/core/Analytics`; test mocks updated to mock `useAnalytics` instead of `useMetrics`. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-302 (Batch 3-13) ## **Manual testing steps** ```gherkin Feature: Network Management analytics Scenario: user triggers a network management flow event Given app is open and user is in a network management flow When user performs an action that triggers analytics (e.g. switch network, open network manager, accept multi-RPC modal) Then the event is tracked on Mixpanel ``` ## **Screenshots/Recordings** N/A – analytics migration, no UI change. ## **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 refactor that only swaps analytics plumbing; primary risk is missing/misnamed events if the new `useAnalytics` hook or `MetaMetricsEvents` import differs from the old `useMetrics` behavior. > > **Overview** > Switches Network Management UI surfaces (e.g., `ManageNetworks`, `NetworkManager`, `NetworkMultiSelector`, and `MultiRpcModal`) from `useMetrics` to the shared `useAnalytics` hook while keeping existing event tracking calls (`trackEvent`/`createEventBuilder`). > > Updates unit tests to mock `useAnalytics` instead of `useMetrics`, and adjusts event constant imports/expectations to use `MetaMetricsEvents` from `core/Analytics/MetaMetrics.events` where applicable. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 3c6fb53. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
#26484) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** **Reason for the change:** The `SwitchAccountTypeModal` component was using the `useRoute()` hook internally to access route parameters. This approach has several drawbacks: - Tightly couples the component to the navigation context - Makes type derivation less explicit (required unsafe type assertion: `(route?.params as { address: Hex })?.address`) - Reduces testability as tests needed to mock the `useRoute` hook globally - No graceful handling when address parameter is missing **Improvement/Solution:** - Refactored `SwitchAccountTypeModal` to receive `route` as a prop instead of calling `useRoute()` internally - Added proper TypeScript interfaces: `SwitchAccountTypeModalRouteParams`, `SwitchAccountTypeModalParamList`, and `SwitchAccountTypeModalProps` - Added fallback UI with "No account selected" message when no address is available from route params - Added missing `key` prop to `AccountNetworkRow` component in the map function (fixes React key warning) - Significantly expanded test coverage: - Organized tests into logical describe blocks (`rendering`, `route params handling`, `navigation`, `hook integration`) - Added tests for empty network list, multiple networks, loading state - Added tests for address matching/non-matching scenarios - Added test for hook integration to verify correct address is passed ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: N/A (internal refactoring) ## **Manual testing steps** ```gherkin Feature: Switch Account Type Modal (EIP-7702) Scenario: User opens switch account type modal with valid address Given the user has an account upgraded to a smart account on a supported network And the user is viewing account details When user taps on "Switch account type" Then user should see the Switch Account Type modal And user should see their account name And user should see the list of networks where the account is upgraded And each network row should show "Smart account" status Scenario: User switches back to regular account Given the user is viewing the Switch Account Type modal And the account is currently a smart account on Sepolia When user taps "Switch back" on the Sepolia row Then the account should be downgraded to a regular account on Sepolia Scenario: User navigates back from modal Given the user is viewing the Switch Account Type modal When user taps the back button Then the modal should close And user should return to the previous screen Scenario: Modal shows loading state while fetching network data Given the network data is still being fetched When user opens the Switch Account Type modal Then user should see a loading spinner And the network list should not be visible ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** N/A - No visual changes (except for new fallback state) ### **After** N/A - No visual changes (except for new fallback state when no address is available) ## **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.
…d assertions (#26710) ## **Description** Updates `amount-keyboard.test.tsx` to use `mockTheme` design token references instead of hardcoded hex values in test assertions, unblocking the design tokens upgrade to v8.2.1 (#26639). **What this PR does:** - Replaces hardcoded color hex values (`#b7bbc8`, `#121314`, `#ca3542`) with `mockTheme.colors.*` references in test assertions for `getBackgroundColor` and the disabled Next button **Why this is an improvement:** - Makes tests resilient to design token value changes - Ensures tests validate correct token usage rather than specific hex values - Aligns with design system best practices - Follows the same pattern established in #26657 ## **Changelog** CHANGELOG entry: null ## **Related issues** Dependency of: #26639 Related: #26657 ## **Manual testing steps** ```gherkin Scenario: Verify updated tests pass Given the repository with design tokens v8.2.1 When I run app/components/Views/confirmations/components/send/amount/amount-keyboard/amount-keyboard.test.tsx Then all 6 tests should pass ``` ## **Screenshots/Recordings** N/A - Test-only changes ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Test-only updates that swap fixed hex assertions for `mockTheme` token references, reducing brittleness during design token upgrades. No production logic changes; risk limited to potential mismatches with token names/structure. > > **Overview** > Updates `amount-keyboard.test.tsx` to stop asserting on hardcoded hex colors for the disabled Next/Continue button and `getBackgroundColor` output. > > Assertions now reference `mockTheme.colors.text.*` and `mockTheme.colors.error.*`, making the tests resilient to design token value changes while still verifying the correct token is used. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 95e250e. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description**
Fixes mobile CI build failures caused by invalid action tag references
in workflow files.
Several workflows were using
`MetaMask/github-tools/.github/actions/setup-e2e-env@v1.7`, but `v1.7`
does not exist in `MetaMask/github-tools` (valid refs include `v1` and
`v1.7.0`).
This PR updates those references to `@v1` to restore build job setup
resolution.
## **Changelog**
CHANGELOG entry: null
## **Related issues**
Fixes: N/A
## **Manual testing steps**
```gherkin
Feature: CI workflow setup action reference
Scenario: Build jobs resolve setup-e2e-env action
Given workflow files reference setup-e2e-env@v1
When CI runs Build Android E2E APKs and Build iOS E2E Apps jobs
Then job setup resolves the action successfully
And CI no longer fails with "unable to find version v1.7"
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: jvbriones <jvbriones@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**
Adds a "View PIN" option to the Card Home manage card section, allowing
users to securely view their card PIN through a PCI-compliant
image-based display.
**Why**: Users need to retrieve their card PIN (e.g. for ATM use or
in-store transactions). The PIN is never transmitted as plain text — it
is rendered as an image via a time-limited, single-use secure token from
the `POST /v1/card/pin/token` endpoint, ensuring PCI compliance.
**What changed**:
- **New SDK method** (`CardSDK.generateCardPinToken`): Calls `POST
/v1/card/pin/token` with optional `customCss` for theming the PIN image.
Mirrors the existing `generateCardDetailsToken` pattern with proper
error handling.
- **React Query integration**: New `cardQueries.pin` key factory and
`pinTokenMutationFn` following the established React Query patterns from
the codebase.
- **`useCardPinToken` hook**: Wraps `useMutation` for PIN token
generation. Automatically applies dark/light theme-aware `customCss`
(background and text colors) so the PIN image matches the app
appearance.
- **`ViewPinBottomSheet` component**: Displays the PIN image in a bottom
sheet with a skeleton loader and `CardScreenshotDeterrent` enabled to
prevent screenshots of sensitive data.
- **`CardHome` integration**: New `ManageCardListItem` for "View PIN"
with biometric authentication gating (matching the "View Card Details"
flow). Falls back to password bottom sheet with a PIN-specific
description when biometrics are not configured. Visible for US users
(all card types) and international users with non-virtual cards.
- **Analytics**: Added `VIEW_PIN_BUTTON` action to `CardActions` enum,
tracked via `CARD_BUTTON_CLICKED` event.
- **Navigation**: Registered `CardViewPinModal` route and added the
`ViewPinBottomSheet` screen to `CardModalsRoutes`.
- **Tests**: Added tests across 5 files — SDK method tests, query layer
tests, hook tests, bottom sheet snapshot/render tests, and 11 new
CardHome integration tests covering visibility conditions, biometric
auth flow, password fallback, and loading guards.
## **Changelog**
CHANGELOG entry: Added "View PIN" option to the Card Home screen,
allowing users to securely view their card PIN via biometric or password
authentication.
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: View card PIN
Scenario: View PIN button is visible for eligible users
Given the user is authenticated with an active card
And the user is a US user OR has a non-virtual (metal) card
When the user navigates to the Card Home screen
Then a "View PIN" option is displayed in the manage card section
Scenario: View PIN button is hidden for international virtual card users
Given the user is an international user with a virtual card
When the user navigates to the Card Home screen
Then the "View PIN" option is NOT displayed
Scenario: View PIN with biometric authentication
Given the user has biometric authentication configured
When the user taps "View PIN"
Then a biometric prompt is displayed
And upon successful authentication, the card PIN is shown as an image in a bottom sheet
And the PIN image matches the current theme (light/dark background)
Scenario: View PIN with password fallback
Given the user does NOT have biometric authentication configured
When the user taps "View PIN"
Then a password bottom sheet appears with the message "Enter your wallet password to view your card PIN."
And upon entering the correct password, the card PIN is shown in a bottom sheet
Scenario: View PIN biometric cancellation
Given the user has biometric authentication configured
When the user taps "View PIN" and cancels the biometric prompt
Then no PIN is displayed and the user returns to Card Home
Scenario: View PIN error handling
Given the user taps "View PIN" and authentication succeeds
When the PIN token request fails
Then an error toast is shown with "Failed to load PIN. Please try again."
Scenario: Screenshot prevention
Given the card PIN bottom sheet is displayed
When the user attempts to take a screenshot
Then the screenshot deterrent is active and prevents capture of the PIN
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots or recordings of the View PIN flow
-->
### **Before**
<!-- Card Home without View PIN option -->
### **After**
<!-- Card Home with View PIN option + View PIN bottom sheet -->
## **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 a new authenticated flow to fetch and display a sensitive card
PIN image via a new SDK endpoint and modal UI, with biometric/password
gating and error handling. Risk is mainly around auth/error-state
handling and the new network call/token lifecycle.
>
> **Overview**
> Adds a new **“View PIN”** manage-card action on `CardHome`, shown only
for eligible users (authenticated, has a card, not loading; US users or
non-virtual cards), gated by `reauthenticate()` with a
password-bottom-sheet fallback when biometrics aren’t configured and
guarded against concurrent loads.
>
> Introduces PIN-token generation plumbing:
`CardSDK.generateCardPinToken` calling `POST /v1/card/pin/token`, React
Query `cardQueries.pin` + `useCardPinToken` (theme-aware `customCss`),
plus a new `ViewPinBottomSheet` modal route
(`Routes.CARD.MODALS.VIEW_PIN`) that renders the PIN image with a
skeleton loader and `CardScreenshotDeterrent` enabled.
>
> Updates analytics (`CardActions.VIEW_PIN_BUTTON`), test IDs, and
English strings, and adds comprehensive tests for the SDK/query/hook,
the new bottom sheet (snapshot/render), and CardHome
visibility/auth/error flows.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
514ae0c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** This PR aims to add the stocks section in the explore page. In order to get this PR to the finish line, I have: - Updated the core package [here](MetaMask/core#8019) to fix an issue with the `limit` param in the search endpoint request and support for a higher limit when calling with the QueryString `Ondo` - Asked the design team to add the corporate icon [here](#26492) - Raised the following issues in api-platform and got a fix - https://consensys.slack.com/archives/C03MLR70YSK/p1771489684959419 - https://consensys.slack.com/archives/C03MLR70YSK/p1771850443811719 - Added Geo-blocking (hardcoded for now but it should live on the API at some point) - Modified order of sections in explore page following @chaoticgoodpanda guidance - Modified predictions section to not be a carousel <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: added stocks section to explore page ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/ASSETS-2635 & https://consensyssoftware.atlassian.net/browse/ASSETS-2632 ## **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** [Here](https://consensys.slack.com/archives/C07NF2K42LE/p1771849520486939) is a full video explaining the e2e functionality. https://github.com/user-attachments/assets/ac8c7c52-30c6-4913-9e69-7b8fe8e0db52 <!-- [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 Explore section and full-screen view backed by a new search hook with geo-restriction logic and new navigation routes, which could affect what data users see and how filtering/refetch behaves. Refactors Trending Tokens full view into shared layout/components, so regressions could impact existing trending-token filtering UI and bottom sheets. > > **Overview** > Adds a new **Stocks** section to Explore, including a new `RWATokensFullView` screen/route and `useRwaTokens` hook that queries Ondo RWA assets (with production geo-blocking) and supports search, network, and sort filters. > > Refactors `TrendingTokensFullView` into the `UI/Trending` area and introduces shared `TokenListPageLayout`, `FilterBar`, and `useTokenListFilters` to unify header/search/filter behavior across token list full views; updates the network bottom sheet to take an explicit `networks` prop and adjusts token sorting to push missing market data to the end. Explore/QuickActions/predictions presentation, navigation, mocks, and smoke tests are updated to include the new Stocks section and new predictions row rendering. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 2be0c5a. 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**
Bump bridge controller
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: null
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Updates a core bridging dependency; while the diff is lockfile-only,
the new `@metamask/bridge-controller` version could change bridge
quoting/execution behavior at runtime.
>
> **Overview**
> Bumps `@metamask/bridge-controller` from `^67.3.0` to `^67.4.0` in
`package.json`.
>
> Updates `yarn.lock` to resolve the new `67.4.0` package (including
updated resolution and checksum).
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b400db1. 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? --> - Redact sensitive data from SDKConnectV2 / MWP debug and error logs - Add `redactUrl` utility to strip query/fragment params from deeplink URLs before logging - Reduce message payload logging to method + id metadata only ## **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: [WAPI-1117](https://consensyssoftware.atlassian.net/browse/WAPI-1117) ## **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. [WAPI-1117]: https://consensyssoftware.atlassian.net/browse/WAPI-1117?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: changes are limited to logging/error messages in SDKConnectV2, with minimal behavioral impact aside from altered log output and one test expectation. > > **Overview** > Prevents sensitive SDKConnectV2/MWP connection parameters from being written to logs by introducing `redactUrl()` and using it when throwing/logging deeplink handling errors. > > Reduces verbosity of connection message logging by logging only JSON-RPC `method` and `id` (instead of full payloads), and adjusts connect-deeplink success logging to avoid dumping full `ConnectionInfo`. Updates the `handleMwpDeeplink` non-string URL test to expect the new redacted/invalid URL message. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit dd3a3d0. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…26773) <!-- 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 DeFi homepage section was returning null (hiding entirely) when the API responded with an error (e.g. 501). This matched the behavior for the empty-data case, but the acceptance criteria requires showing a retry UI on API failure — consistent with how the Predictions and Tokens sections handle errors. **This PR:** - Separates error and empty handling in DeFiSection: errors now render the shared ErrorState component with a retry button, while empty data (200 with 0 positions) still hides the section. - Replaces the no-op refresh function with a real one that calls DeFiPositionsController._executePoll(), so both the retry button and pull-to-refresh actually re-fetch. - Updates tests to assert the new error UI behavior and verify retry triggers _executePoll. ## **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 DeFi homepage section to show retry UI when API request fails instead of hiding the section ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TMCU-496 ## **Manual testing steps** ```gherkin Feature: DeFi section error handling on homepage Scenario: user sees retry UI when DeFi API fails Given the DeFi positions API returns a 501 error And the user navigates to the homepage When the homepage loads Then the DeFi section displays with a "Unable to load" message and a "Retry" button Scenario: user retries after API failure Given the DeFi section is showing the error/retry UI When user taps the "Retry" button Then the DeFi positions are re-fetched from the API Scenario: DeFi section hidden when no positions exist Given the DeFi positions API returns 200 with no positions When the homepage loads Then the DeFi section is not displayed ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <img width="377" height="613" alt="Screenshot 2026-03-02 at 13 21 18" src="https://github.com/user-attachments/assets/55d6b7e4-2187-4824-87c9-fa1161439e70" /> <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes homepage DeFi rendering and refresh behavior to call `DeFiPositionsController._executePoll()`, which could affect polling frequency and error-handling paths. Uses a controller internal method, so regressions are possible if controller APIs change. > > **Overview** > DeFi homepage section no longer disappears on API errors: when `hasError` (and not loading) it now renders the shared `ErrorState` with a Retry button while still hiding the section for the *empty data* case. > > The section’s `refresh` handler (used by pull-to-refresh and Retry) is wired to `Engine.context.DeFiPositionsController._executePoll()` to actively re-fetch positions. > > Tests were updated to validate the new error UI and to assert that both Retry and the exposed `ref.refresh()` call `_executePoll()`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 296c330. 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** Fix recipient list display in send 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: ## **Related issues** Fixes: #26684 ## **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="396" height="847" alt="Screenshot 2026-03-02 at 5 04 59 PM" src="https://github.com/user-attachments/assets/3b4e8f2d-448c-41a2-bf53-55f2ba2d967c" /> ## **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 row wrapper component and tweaks padding/accessibility; main risk is minor touch/spacing regressions in the recipient list. > > **Overview** > Fixes the recipient list row rendering in the send/confirmation flow by replacing the design-system `ButtonBase` wrapper with React Native `Pressable`. > > Updates the row styling to include horizontal padding (`px-4`) and explicitly sets `accessibilityRole="button"` while preserving the existing pressed/selected background behavior. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e5b33b4. 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?
-->
- Skip trending tests to unblock pipeline
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry:
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] 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: this only disables a smoke test, reducing CI coverage but
not affecting production code paths.
>
> **Overview**
> Disables the Trending Feed smoke test that navigates through each
section’s `View All` full views (and back to the feed) by marking the
spec as `it.skip`, to unblock the pipeline.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
5f8dd44. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## stable #27086 +/- ##
==========================================
+ Coverage 81.21% 81.50% +0.28%
==========================================
Files 4462 4621 +159
Lines 116332 121060 +4728
Branches 25096 26604 +1508
==========================================
+ Hits 94482 98671 +4189
- Misses 15250 15451 +201
- Partials 6600 6938 +338 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
chloeYue
previously approved these changes
Mar 13, 2026
Contributor
|
policy-bot: approve |
<!--
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**
Increase JS bundle 1 MB
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry:
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk: workflow-only change that just relaxes the CI bundle-size
gate by 1 unit and doesn’t affect runtime code.
>
> **Overview**
> **CI bundle-size gating has been relaxed slightly.** The
`js-bundle-size-check` step in `.github/workflows/ci.yml` now allows an
iOS `main.jsbundle` size threshold of `53` instead of `52` when running
`./scripts/js-bundle-stats.sh`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3c0f0a4. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Contributor
🔍 Smart E2E Test Selection⏭️ Smart E2E selection skipped - base branch is not main (base: stable) All E2E tests pre-selected. |
|
Contributor
The committed fixture schema is out of date. To update, comment: |
chloeYue
approved these changes
Mar 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



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