[pull] main from MetaMask:main#560
Merged
Merged
Conversation
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** 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>
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.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )