[pull] main from MetaMask:main#625
Merged
pull[bot] merged 15 commits intoReality2byte:mainfrom Mar 24, 2026
Merged
Conversation
…cp-7.70.1 (#27854) ## **Description** Fix HIP-3 asset ID lookup failure (`"Asset ID not found for xyz:BRENTOIL"`) that blocked trading on HIP-3 markets when navigating via the old Perps tab layout. **Root cause**: Dual-cache desync between `#cachedValidatedDexs` (string DEX names) and `#cachedAllPerpDexs` (raw API objects for `perpDexIndex` computation). The standalone preload path (`#getStandaloneValidatedDexs`) populated one cache but not the other. When `#buildAssetMapping` later ran, it found "xyz" in `dexsToMap` but couldn't compute its `perpDexIndex` because `#cachedAllPerpDexs` was null. **Why old Perps tab vs new Homepage Sections**: Both layouts sit inside `Wallet/index.tsx`, which calls `startMarketDataPreload()` on mount. This fires standalone HTTP calls that populate `#cachedValidatedDexs` but not `#cachedAllPerpDexs`. - **New homepage sections**: `PerpsSectionWithProvider` mounts immediately. Stream hooks fire `ensureReady()` before or concurrently with the standalone preload. Since `#cachedValidatedDexs` is often still null, `fetchValidatedDexsInternal` runs fresh and sets **both** caches correctly. - **Old tab layout**: The Perps tab doesn't mount until the user taps it. By that time, `startMarketDataPreload()` has already completed → `#cachedValidatedDexs` is populated by standalone. When the tab mounts → `getValidatedDexs()` → **cache hit** → `fetchValidatedDexsInternal` is never called → `#cachedAllPerpDexs` stays null → `buildAssetMapping` can't find "xyz". **Changes (1 file, 3 sites)**: 1. **Root cause fix**: `#getStandaloneValidatedDexs` now sets `this.#cachedAllPerpDexs = allDexs` after a successful `perpDexs()` call, keeping both caches in sync. 2. **Cache poisoning fix**: Removed `this.#cachedAllPerpDexs = this.#cachedAllPerpDexs ?? [null]` from the catch block in `#buildAssetMapping`. 3. **Cache poisoning fix**: Replaced persistent `if (!cache) { cache = [null] }` with local `const allPerpDexs = cache ?? [null]` — consumers read the cache, only the owner writes it. ## **Changelog** CHANGELOG entry: Fixed a bug where closing positions on HIP-3 markets (e.g., xyz:BRENTOIL) failed with "Asset ID not found" when navigating via the Perps tab ## **Related issues** Fixes: HIP-3 asset ID lookup failure on old Perps tab layout ## **Manual testing steps** ```gherkin Feature: HIP-3 position management via Perps tab Scenario: user closes a HIP-3 position from the old Perps tab Given user has an open position on a HIP-3 market (e.g., xyz:BRENTOIL) And user is using the old tab layout (homepage redesign v1 disabled) When user navigates to the Perps tab And user taps close on the xyz:BRENTOIL position Then the position closes successfully without "Asset ID not found" error Scenario: user opens a HIP-3 position from the old Perps tab Given user is on the Perps tab (old layout) When user navigates to xyz:BRENTOIL market and places a market order Then the order executes successfully with correct asset ID routing ``` ## **Screenshots/Recordings** ### **Before** Metro logs show the desync: ``` getValidatedDexs CACHE HIT {"cachedAllNull": true, "dexs": [null, "xyz"]} buildAssetMapping state {"allPerpDexsLen": 1, "cachedAllNull": true} Could not find perpDexIndex for DEX xyz Asset ID not found for xyz:BRENTOIL ``` ### **After** Metro logs show both caches in sync: ``` buildAssetMapping state {"allPerpDexsLen": 8, "cachedAllNull": false, "dexsToMap": [null, "xyz"]} Asset map state at order time {"assetExistsInMap": true, "hip3AssetsCount": 54, "totalAssetsInMap": 283} Resolved DEX-specific asset ID {"assetId": 110049, "coin": "xyz:BRENTOIL"} usePerpsClosePosition: Close result {"success": true, "orderId": "359617825254"} ``` ## **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 HIP-3 market routing/asset-ID mapping in `HyperLiquidProvider`, so a mistake could break trading on some perps markets; scope is small and localized to cache population/fallback behavior. > > **Overview** > Fixes a HIP-3 asset mapping failure where `#cachedValidatedDexs` could be populated via the standalone preload path while `#cachedAllPerpDexs` stayed `null`, leading to missing `perpDexIndex` during `#buildAssetMapping`. > > `#getStandaloneValidatedDexs()` now also populates `#cachedAllPerpDexs` after a successful `perpDexs()` call, and `#buildAssetMapping()` no longer “poisons” the shared cache with a persistent `[null]` fallback (it uses a local fallback instead). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit c925609. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…nt -> cp-7.71.0 (#27830) ## **Description** ### Activity — on-ramp orders scoped to the selected account The Activity **Orders** tab merges legacy fiat orders with V2 `RampsController` orders. Legacy rows were already limited to the **selected account group** via `getOrders`. V2 orders were not filtered, so purchase history from other wallets could appear. This change adds `selectRampsOrdersForSelectedAccountGroup`, which keeps only orders whose `walletAddress` matches any formatted address in the selected account group (same semantics as legacy, using `areAddressesEqual` for EVM vs non-EVM). Hook and modal consumers that should reflect “current wallet context” now use this selector instead of the raw controller list. ### Transak — preserve user-entered fiat amount on Build Quote (in-app) After **additional verification**, opening the KYC/payment webview called `navigateToKycWebview` with **`quote.fiatAmount`**, and the stack reset rewrote **RampAmountInput** params with that value. The quote total can differ from what the user typed (e.g. fees), so Build Quote could show **27.37** after the user entered **25**, and that value persisted after closing the sheet or going back. **Change:** `routeAfterAuthentication(..., amount)` already carried the typed fiat; `navigateToAdditionalVerificationCallback` now puts the same `amount` on **both** `RampAmountInput` and `RampAdditionalVerification` route params. **V2 Additional Verification** reads that param and passes **only** it into `navigateToKycWebview` (no `quote.fiatAmount` for this purpose). **Out of scope:** Order detail screens and stored order payloads are unchanged. The **Transak payment webview** URL is unchanged (no `fiatAmount` override in widget params); only in-app Build Quote / stack state matches the user’s input. ## **Changelog** CHANGELOG entry: Fixed Activity on-ramp (Orders) list showing V2 purchases from wallets other than the selected account group; fixed Transak unified buy flow so the fiat amount on Build Quote after additional verification matches the user-entered amount on the amount screen (in-app stack), without changing Transak’s payment widget totals. ### Tests - `selectRampsOrdersForSelectedAccountGroup` and ramp hook consumers (selector + hook unit tests). - `useTransakRouting`: IDPROOF / additional verification navigation with user `amount` set and omitted. - V2 `AdditionalVerification`: continue passes route `amount` into `navigateToKycWebview`. ## **Related issues** Refs: [TRAM-3361](https://consensyssoftware.atlassian.net/browse/TRAM-3361) ## **Manual testing steps** ```gherkin Feature: Activity on-ramp orders and Transak amount (TRAM-3361) Scenario: Orders tab shows only selected account group’s V2 on-ramp orders Given the user has two wallets (or account groups) with separate on-ramp purchase history And unified ramps V2 orders exist for more than one wallet address When the user selects account group A and opens Activity → Orders Then only on-ramp orders whose destination wallet belongs to account group A are listed When the user switches to account group B Then the Orders tab lists only orders for account group B Scenario: Custom fiat amount survives Transak additional verification on Build Quote Given the user is in unified Buy with Transak (native) as provider And the user enters a custom fiat amount (e.g. 25) on the amount screen When the user continues through flows that require additional verification And the user taps Continue on the additional verification screen Then Build Quote under the KYC/payment sheet still shows the entered amount (e.g. 25), not only the quote total When the user closes the webview or goes back from the flow Then the amount screen still shows the same entered amount (e.g. 25) ``` ## **Screenshots/Recordings** ### **Before** <!-- Add video: Activity Orders showing other wallet’s purchases / wrong fiat amount after verification or in widget --> https://github.com/user-attachments/assets/b26bb3cb-8219-48a3-8128-7c79026fdd18 ### **After** <!-- Add video: Activity Orders scoped to selected account / correct custom amount through verification and widget --> https://github.com/user-attachments/assets/3e1929e3-7e1a-42c9-98bd-ea8f7bc9b1eb https://github.com/user-attachments/assets/ef6d14ed-6533-4e04-a5a4-8cbd44477170 ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Moderate UX/data-scoping change: filters which on-ramp orders appear based on multichain account selection and adjusts Transak navigation params, which could hide expected history or affect flow state if account/address resolution is off. > > **Overview** > Fixes unified ramp UI to **scope V2 `RampsController` orders to the selected account group**, preventing purchases from other wallets from showing up in Activity-derived surfaces. This introduces `selectRampsOrdersForSelectedAccountGroup` (address-matched via `areAddressesEqual`) and switches key consumers (`useRampsOrders`, `useRampsProviders`, `useRampsButtonClickData`, `ProviderSelectionModal`) from the unfiltered selector. > > Updates the Transak additional-verification flow to **preserve the user-entered fiat amount** through stack resets: `useTransakRouting` now carries `amount` into `RampAdditionalVerification` params, and `AdditionalVerification` uses that param (not `quote.fiatAmount`) when opening the KYC webview. Selector and routing behavior are covered with expanded unit tests. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 39d5861. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…s Withdraw UI (#27792) ## **Description** <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> Adds the UI scaffolding for the Perps Withdraw confirmation flow. When triggered from Developer Options, the "Perps Withdraw" button navigates to a full-screen `CustomAmountInfo` confirmation page that displays the user's available Perps balance and uses the post-quote "Receive as" token picker pattern (same as Predict Withdraw). This is the UI-only foundation — the end-to-end withdrawal execution (HyperLiquid signatures, Relay integration) will follow in a subsequent PR. **Changes:** - Added "Perps Withdraw" button and `useAddPerpsTransactionBatch` hook in Developer Options - Created `PerpsWithdrawInfo` component that wires `CustomAmountInfo` with Perps balance display - Created `PerpsWithdrawBalance` component showing available Perps balance from live account data - Added `perpsWithdraw` to `FULL_SCREEN_CONFIRMATIONS` and `POST_QUOTE_TRANSACTION_TYPES` - Added `perpsWithdraw` routing in `info-root.tsx` - Updated `useButtonLabel` to show "Withdraw" for `perpsWithdraw` transactions - Added locale strings for Perps Withdraw title and available balance ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: Add Perps Withdraw button into Developer Options, show new Perps Withdraw UI ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/CONF-1072 ## **Manual testing steps** ```gherkin Feature: Perps Withdraw confirmation UI Background: Given I am logged into MetaMask Mobile And I have Developer Options enabled (export MM_ENABLE_SETTINGS_PAGE_DEV_OPTIONS="true" in .js.env) Scenario: user triggers Perps Withdraw from Developer Options Given I am on the Developer Options screen (Settings -> Developer options) And I scroll to the Perps Withdraw section When user taps the "Withdraw" button under "Perps Withdraw" Then the Perps Withdraw confirmation page should appear And the page title should show "Withdraw" And the available Perps balance should be displayed And the "Withdraw" action button should be visible at the bottom ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** N/A ### **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. <!-- Generated with the help of the pr-description AI skill --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adds a new `perpsWithdraw` transaction type path through the confirmations UI (routing, labels, constants) and a developer-only trigger that creates batched transactions; changes are mostly UI scaffolding but touch confirmation flow selection logic and transaction batching. > > **Overview** > Introduces a **Perps Withdraw** confirmation flow scaffold: a new Developer Options button triggers a `perpsWithdraw` transaction batch on Arbitrum USDC and navigates into the Perps confirmation stack. > > Adds a new `PerpsWithdrawInfo` full-screen `CustomAmountInfo` view that registers Arbitrum USDC, uses the post-quote *Receive as* pattern, and shows an *available Perps balance* via the new `PerpsWithdrawBalance` component. > > Updates confirmations plumbing to recognize `TransactionType.perpsWithdraw` (info routing, full-screen + post-quote type lists, withdraw button labeling, locales) and adds targeted unit tests/snapshots. Also bumps `@metamask/bridge-status-controller` and `@metamask/transaction-controller` dependency versions. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 6d73fcc. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
<!--
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**
* Add Metrics Opt In event in Onboarding, Optinmetrics and
MetaMetricsAndDataCollectionSection screen
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: null
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: METRICS_OPT_IN analytics on user opt-in
Scenario: User opts in from onboarding MetaMetrics screen
Given the user is on the onboarding MetaMetrics / data collection screen with basic usage enabled by default
When the user continues without turning off basic usage
Then the app completes onboarding as before and analytics pipelines receive a "Metrics Opt In" event with onboarding location and expected properties in addition to "Analytics Preference Selected"
Scenario: User enables MetaMetrics from Settings
Given the user is logged in and MetaMetrics is currently off
When the user opens Settings > Security & privacy and turns the MetaMetrics switch on
Then the app opts in successfully and emits "Metrics Opt In" with settings location and updated_after_onboarding before the preference-selected event
Scenario: User enables marketing which requires MetaMetrics
Given MetaMetrics is off and marketing data collection is off
When the user turns marketing data collection on (which enables MetaMetrics)
Then MetaMetrics turns on and "Metrics Opt In" is recorded before the subsequent preference events
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<img width="702" height="94" alt="Screenshot 2026-03-24 at 3 35 19 PM"
src="https://github.com/user-attachments/assets/e5177be9-8c93-413b-ae76-8e10c3e50352"
/>
<img width="703" height="50" alt="Screenshot 2026-03-24 at 3 36 30 PM"
src="https://github.com/user-attachments/assets/6da0d4cb-f660-49b9-818e-bb45fe1e413e"
/>
<img width="695" height="91" alt="Screenshot 2026-03-24 at 3 40 10 PM"
src="https://github.com/user-attachments/assets/229e4a2d-80c3-469e-b1a9-639df7068c17"
/>
<!-- [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 analytics-only change that adds an additional tracking call
when users enable metrics (onboarding, social login, and settings). Main
risk is event ordering/duplication affecting downstream dashboards
rather than app behavior.
>
> **Overview**
> Adds a new `MetaMetricsEvents.METRICS_OPT_IN` event and emits it
whenever users enable metrics, including the onboarding opt-in screen
(`location: onboarding_metametrics`), social login onboarding flow
(`location: onboarding_social_login`), and the settings MetaMetrics
toggle (`location: settings` / `onboarding_default_settings`).
>
> Updates tests to assert the new opt-in event is sent (and in
settings/onboarding cases is sent *before*
`ANALYTICS_PREFERENCE_SELECTED`), including verifying
`updated_after_onboarding` and optional `account_type` properties.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
9968f73. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…yment method (#27487) ## **Description** The "Submitting your trade" persistent toast (with spinner and close button) was being shown for **all** order submissions, regardless of payment method. This new toast design was intended only for the deposit flow when the user pays with a different token — not for orders paid with the perps balance. Additionally, the deposit progress toast in `usePerpsOrderDepositTracking` was configured with `hasNoTimeout: false` and no close button, causing it to auto-dismiss and be impossible to manually close during the deposit. ### Changes 1. **`PerpsOrderView.tsx`** — Conditionally select toast based on payment method: - **Perps balance**: shows the original `submitted()` toast (auto-dismissing "Order submitted" style). - **Custom token (deposit flow)**: shows the persistent `shared.submitting()` toast with close button. 2. **`usePerpsOrderDepositTracking.ts`** — Made the deposit progress toast persistent (`hasNoTimeout: true`) and added a close button so the user can dismiss it. 3. **Tests updated** to cover both payment paths and verify persistence/close behavior. ## **Changelog** CHANGELOG entry: Fixed incorrect toast design shown when submitting a perps order with perps balance, and made the deposit progress toast persistent and closable when trading with a different token ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TAT-2667 Fixes: https://consensyssoftware.atlassian.net/browse/TAT-2570 ## **Manual testing steps** ```gherkin Feature: Perps order submission toast Scenario: user submits order with perps balance Given the user is on the perps order screen with perps balance selected When user taps the Place Order button Then the standard auto-dismissing "Order submitted" toast is shown And the persistent "Submitting your trade" toast is NOT shown Scenario: user submits order with a custom payment token (deposit flow) Given the user is on the perps order screen with a different payment token selected When user taps the Place Order button Then the persistent "Submitting your trade" toast with a close button is shown And the user can dismiss the toast by tapping the close button Scenario: deposit progress toast persists during deposit Given the user confirmed a deposit-and-order transaction with a custom token When the deposit transaction is submitted Then the "Depositing your funds" toast persists on screen (does not auto-dismiss) And the toast has a close (X) button that the user can tap to dismiss it ``` ## **Screenshots/Recordings** N/A — toast behavior change, no new UI elements. ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: changes are limited to toast presentation/UX and associated unit tests, without altering order execution or transaction handling logic. > > **Overview** > Updates `PerpsOrderView` to **conditionally show the standard `submitted()` toast for perps-balance orders** while keeping the **persistent `shared.submitting()` toast only for custom-token (deposit) flows**. > > Adjusts `usePerpsOrderDepositTracking` so the deposit progress toast is **persistent (`hasNoTimeout: true`) and user-dismissable via a close button** wired to `ToastContext`. > > Expands tests to cover both payment paths and verifies the new persistence/close-button behavior; adds a lightweight `nock` type stub for component-view API mocking. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit abf35d6. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…r names (#27734) <!-- 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** On the activity (unified transactions) view, the “View full history on …” footer could show the wrong explorer name for custom or non-selected networks: `TransactionsFooter` preferred the hardcoded Etherscan string using **global** `providerType` before using the explorer URL, while `chainId` / `rpcBlockExplorer` reflected the **enabled** network for the list—so the label could say Etherscan even when the configured explorer was e.g. Gnosisscan. Separately, “View full history” navigation used `getBlockExplorerAddressUrl(providerType, …)` when a network config block explorer existed. That helper only applies the configured base URL when `networkType === RPC`; otherwise it builds an Etherscan URL from `providerType`. If the wallet’s selected network did not match the activity list’s chain, the link opened the wrong explorer. **Solution:** Derive the footer label from `rpcBlockExplorer` when present (before the Etherscan shortcut). For unified activity, build the address URL with `getBlockExplorerAddressUrl(RPC, address, blockExplorerUrl)` whenever the explorer comes from `networkConfigurationsByChainId`, so the opened URL always matches the configured explorer for that chain. ## **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 incorrect block explorer name and link on the activity “View full history” action for custom networks when the selected wallet network did not match the activity chain ## **Related issues** Fixes: #19233 ## **Manual testing steps** ```gherkin Feature: Activity view block explorer footer Scenario: Custom network shows correct explorer name and opens matching URL Given a custom EVM network is added with a non-Etherscan block explorer URL (e.g. Gnosis Chain with gnosisscan.io) And that network is enabled for the account and its activity is visible on the Activity tab And a different EVM network is selected in the network picker (e.g. Ethereum mainnet) When user opens the Activity tab and scrolls to the “View full history on …” link at the bottom Then the link text uses the explorer derived from the activity chain’s block explorer (not “Etherscan” unless appropriate) When user taps the link Then the in-app webview opens the account page on that chain’s block explorer base URL (same host as configured), not Ethereum Etherscan ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <img width="399" height="832" alt="Screenshot 2026-03-20 at 13 41 58" src="https://github.com/user-attachments/assets/d578df27-3c3b-407e-b8c4-17ae8bdf1943" /> <img width="393" height="841" alt="Screenshot 2026-03-20 at 13 42 03" src="https://github.com/user-attachments/assets/6fa4a56a-ff8f-45b3-bd95-08bf629a7b3c" /> <!-- [screenshots/recordings] --> ### **After** <img width="394" height="839" alt="Screenshot 2026-03-20 at 13 40 29" src="https://github.com/user-attachments/assets/fc6298c8-2ce8-4c8a-a992-d566372c5e2c" /> <img width="395" height="842" alt="Screenshot 2026-03-20 at 13 40 34" src="https://github.com/user-attachments/assets/f1f51bac-ff77-472b-a42b-c01967ed75b2" /> <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk UI/navigation tweak that only changes how the block explorer label and destination URL are derived; main potential regression is incorrect/missing explorer link text if `rpcBlockExplorer` parsing fails. > > **Overview** > Fixes the Activity/Unified Transactions footer to **derive the “View full history on …” label from the provided `rpcBlockExplorer` URL first**, instead of prematurely falling back to the hardcoded Etherscan string when `providerType` reflects a different globally-selected network. > > Updates unified activity’s “view block explorer” navigation to build address links via `getBlockExplorerAddressUrl(RPC, ...)` when a per-chain configured explorer exists, ensuring the opened webview matches the enabled chain’s configured explorer. Adds/updates unit tests to cover the mismatched `chainId` vs global `providerType` label case. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 99228cf. 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** Language options in Settings → General → Current language were labeled in English (e.g. “Spanish”, “Chinese - China”), which is awkward for users who don’t read English well. This PR updates display labels only in getLanguages() (locales/i18n.js): each option uses that language’s endonym (e.g. Español, 简体中文). Locale keys and persistence (setLocale, storage, supportedTranslations) are unchanged. ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: Updated the General settings language picker to show each language in its native name. ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TMCU-454 ## **Manual testing steps** ```gherkin Feature: Language selector display in General settings Scenario: User sees native language names in the picker Given the user has opened MetaMask and is logged in And the user navigates to Settings > General When the user views the "Current language" section Then the closed selector shows the current locale using its native label where applicable (e.g. English stays "English") And opening the language selector lists options with native names (e.g. Español, 简体中文, Deutsch) Scenario: Changing language still works Given the user is on Settings > General When the user selects a different language from the list and confirms if prompted Then the app locale updates as before And returning to General settings shows the newly selected language label correctly ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <img width="269" height="573" alt="Screenshot 2026-03-23 at 11 30 48" src="https://github.com/user-attachments/assets/6439354b-358e-4434-9051-248a9415ee78" /> <!-- [screenshots/recordings] --> ### **After** <img width="265" height="571" alt="Screenshot 2026-03-23 at 11 29 29" src="https://github.com/user-attachments/assets/6a08eea8-0206-419f-8ac6-dacb80c36340" /> <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk UI-only change that updates display strings in `getLanguages()` without altering locale codes, storage, or translation loading logic. > > **Overview** > Updates `getLanguages()` in `locales/i18n.js` so the Settings language selector displays **native language names (endonyms)** (e.g., `Deutsch`, `Español`, `简体中文`) instead of English labels. > > Adds a short JSDoc comment clarifying this mapping is *display-only* and does not change locale keys or persistence behavior. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 6bfd5f3. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…lid orders cp-7.71.0 (#27791) ## **Description** Fixes three related bugs in the Perps order form involving Take Profit (TP) and Stop Loss (SL) prices that were restored from a previous session's pending trade configuration: 1. **Stale TP/SL persisted after order submission**: The `pendingTradeConfiguration` was not cleared after a successful order, causing previously set TP/SL values to reappear on the next order form visit — even auto-submitting a stop loss the user never intended. 2. **TP/SL displayed as "off" despite being set**: When the RoE calculation clamped to zero (e.g., the TP/SL price was on the wrong side of the current market price), the "Auto close" summary row showed "off" instead of the actual price. The TP/SL edit form, however, showed the correct value — a confusing inconsistency. 3. **No validation or blocking for invalid TP/SL direction**: A restored TP/SL price that ended up on the wrong side of the market (e.g., take profit below entry for a long) was silently accepted and could be submitted, leading to immediate execution or unexpected behavior. ### Changes - Call `clearPendingTradeConfiguration` after successful order execution to prevent stale TP/SL restoration. - Display the formatted price in the "Auto close" row when RoE rounds to zero, instead of showing "off". - Validate TP/SL prices against current market price and trade direction using existing `isValidTakeProfitPrice` / `isValidStopLossPrice` utilities. - Show inline error warnings when TP or SL is on the wrong side of the current price. - Disable the "Place order" button while TP/SL is invalid. ## **Changelog** CHANGELOG entry: Fixed a bug where stale Take Profit and Stop Loss prices could persist across orders and display incorrectly in the Perps order form ## **Related issues** Fixes: #27793 ## **Manual testing steps** ```gherkin Feature: Perps order TP/SL validation Scenario: stale TP/SL is cleared after placing an order Given the user has a Perps position open with TP and SL set And the user navigates to the order form When the user places the order successfully And the user returns to the order form for the same asset Then the TP and SL fields should be empty (not restored from previous order) Scenario: TP/SL on the wrong side shows warning and blocks submission Given the user is on the Perps order form for a Long position And the user sets a Take Profit price below the current market price When the order form validates the TP price Then a warning is displayed: "Take profit must be above current price. Update or clear it to place the order." And the "Place order" button is disabled Scenario: TP/SL on the wrong side for Short position Given the user is on the Perps order form for a Short position And the user sets a Stop Loss price below the current market price When the order form validates the SL price Then a warning is displayed: "Stop loss must be above current price. Update or clear it to place the order." And the "Place order" button is disabled Scenario: TP/SL with zero RoE displays price instead of "off" Given the user is on the Perps order form with a TP or SL set And the TP/SL price results in an RoE that rounds to 0% When the "Auto close" summary row renders Then it displays the formatted price value instead of "off" ``` ## **Screenshots/Recordings** N/A — validation logic and text changes only; no layout or visual design changes. ### **Before** N/A ### **After** <img width="1320" height="2868" alt="Simulator Screenshot - iPhone 17 Pro Max - 2026-03-23 at 11 46 16" src="https://github.com/user-attachments/assets/6c84ef28-0adc-42e2-818e-3fd0d1c9de6e" /> ## **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 the Perps order submission/validation path to block orders when TP/SL is on the wrong side and clears stored pending trade config after submission, which could affect order placement behavior. Risk is mitigated by added unit coverage for market vs limit reference price and button-disabled states. > > **Overview** > Prevents Perps orders from being submitted with **invalid TP/SL trigger prices** by validating TP/SL against the appropriate reference price (*current* for market orders, *entry/limit* for limit orders), showing inline warnings, and disabling the **Place order** button when TP/SL is wrong-side. > > Fixes TP/SL display inconsistencies by showing the formatted TP/SL *price* in the summary row when computed RoE clamps to `0%` instead of rendering `off`, and clears `PerpsController.clearPendingTradeConfiguration(asset)` after successful submission to avoid restoring stale TP/SL on subsequent visits. > > Adds new i18n strings for the wrong-side TP/SL warnings and expands `PerpsOrderView` tests to cover wrong-side validation, limit-order reference pricing, and the monochrome A/B button variant disablement. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 7c10dc8. 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** Support webcredential for ios google login Part 2/4 - Add feature flag This pr add feature flag for the ios google login PR list Part 1/ 4 - #27741 Part 2/ 4 - #27848 Part 3/ 4 - #27850 Part 4/ 4 - TBA <!-- 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 legacyIosGoogleConfigEnabled feature flag ## **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: adds a new remote feature flag and selector with env override, without changing authentication flow yet; main risk is misconfiguration since the selector defaults to enabled. > > **Overview** > Adds a new remote feature flag, `legacyIosGoogleConfigEnabled`, including registry metadata and a dedicated selector `selectLegacyIosGoogleConfigEnabled` (defaulting to `true`) that can be force-overridden via `MM_LEGACY_IOS_GOOGLE_CONFIG_ENABLED`. > > Includes unit tests covering default/remote/env override behavior, and updates `babel.config.tests.js` to avoid inlining env vars for the new selector and its tests. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit ca7e813. 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? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MUL-1496 ## **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] > **Low Risk** > Mostly deletes unused Ledger Connect/BLE scanning UI and related hooks/tests; functional change is limited to how Ledger device model is sourced when forgetting a device, which could affect metrics labeling but not core wallet logic. > > **Overview** > Removes the legacy Ledger BLE connection/scan flow UI (`LedgerConnect`, `Scan`, `LedgerConnectionError`) along with associated hooks (`useBluetooth`, `useBluetoothDevices`, `useLedgerBluetooth`, `useLedgerDeviceForAccount`) and their unit/snapshot tests. > > Updates `AccountActions` hardware-account removal to stop relying on `useLedgerDeviceForAccount`; when a Ledger keyring becomes empty it now calls `getDeviceId()` from `core/Ledger/Ledger` before `forgetLedger()` to populate the `HARDWARE_WALLET_FORGOTTEN` metric, and adjusts mocks accordingly. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 8bcc324. 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**
MMQA-1384: Extends the existing new-wallet analytics smoke test to
assert a new proxied PUT to
authentication.api.cx.metamask.io/api/v2/profile/accounts after
onboarding (baseline + 1).
Adds proxy observation helpers in mockHelpers.ts
(collectSeenProxiedRequests, filterProxiedRequests,
waitForProxiedRequestsMatching) plus unit tests for
filterProxiedRequests.
<!--
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: changes are confined to test utilities and smoke tests,
adding polling/assertions around proxied network calls and a
feature-flag override that may affect test stability but not production
code.
>
> **Overview**
> Adds new mock-server helper utilities to **collect, filter, and poll
for proxied requests** seen by `mockttp`, including stable matcher
formatting (`formatProxiedRequestMatcher`) and baseline+delta waiting
(`waitForAdditionalProxiedRequestsMatching`). Unit tests were added for
the matcher formatting and filtering logic.
>
> Updates wallet analytics smoke tests to **disable the Predict GTM
onboarding modal via remote flags** and to assert that an additional
proxied `PUT` to `authentication.../profile/accounts` occurs after
new-wallet creation and wallet import, using a shared constants file and
a longer timeout for slower environments.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0c46825. 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? --> Split from #26651 to reduce CODEOWNERS fanout. Batch: mobile-core-ux Source branch: `origin/remove-static-hex-from-tests` This batch removes brittle hardcoded hex theme values from mobile-core-ux-owned tests and replaces them with `mockTheme` so the tests follow the same token values as the components under test. It also expands the `color-no-hex` ESLint rollout in `.eslintrc.js` to the mobile-core-ux component and view folders from `CODEOWNERS`, so future violations are caught at the team ownership boundary instead of only in the few files touched by this PR. The concrete updates are: - `TransactionsFooter.test.tsx` and `AccountsMenu.test.tsx` now mock `useTheme` from `jest.requireActual(...).mockTheme` instead of hand-rolled hex values. - `Transactions/index.test.tsx` now uses `mockTheme.colors` and `mockTheme.typography` for the direct render-context tests, including the remaining `CancelSpeedupModal` case. - `.eslintrc.js` now enables `@metamask/design-tokens/color-no-hex` for the relevant mobile-core-ux component/view CODEOWNERS folders such as `Transactions`, `AccountsMenu`, and related mobile-core-ux UI surfaces. ## **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: color-no-hex lint compliance for mobile-core-ux tests Scenario: developer validates the mobile-core-ux batch Given the mobile-core-ux test files use theme-backed values instead of hardcoded hex literals When the developer runs the targeted lint and unit test commands Then no color-no-hex violations are reported for the updated scope And the updated Transactions and AccountsMenu test suites pass ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- Generated with the help of the pr-description AI skill --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: changes are limited to ESLint override scope and test-only theme mocking, with no production logic changes. Main risk is unexpected new lint failures in the newly enforced folders. > > **Overview** > Expands the `.eslintrc.js` rollout of `@metamask/design-tokens/color-no-hex` by enabling it (as `error`) for additional mobile-core-ux-owned UI/view directories, so new static hex colors are caught at lint time. > > Updates `TransactionsFooter.test.tsx`, `Transactions/index.test.tsx`, and `AccountsMenu.test.tsx` to stop hardcoding hex theme values and instead source colors/typography from `mockTheme` (and mock `useTheme` accordingly), making tests consistent with design token values. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit bb033cb. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Split from #26651 to reduce CODEOWNERS fanout. Batch: shared Standardizes unit tests to avoid hardcoded hex colors by switching theme mocks and style assertions to the shared `mockTheme` from `app/util/theme`. Also updates a small number of test mocks to match current hook signatures (e.g. `useNetworkEnablement` now returns `popularEvmNetworks` / `popularMultichainNetworks` / `popularNetworks`, and `useAnalytics` requires `identify`). Related color-no-hex PRs (same initiative): - #26958 - #26963 - #27008 - #27030 - #27031 - #27149 - #27150 - #27151 ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: color-no-hex test updates Scenario: TypeScript and unit tests are healthy Given the branch is checked out When I run yarn lint:tsc Then it passes ``` ## **Screenshots/Recordings** ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed MetaMask Contributor Docs and MetaMask Mobile Coding Standards. - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable (updated mocks + ran yarn lint:tsc) - [ ] I've documented my code using JSDoc format if applicable - [ ] I've applied the right labels on the PR (see labeling guidelines). Not required for external contributors. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk because changes are confined to unit tests/mocks; main risk is brittle test failures if the shared `mockTheme` shape or mocked hook contracts diverge from production interfaces. > > **Overview** > Refactors a batch of unit tests to stop hardcoding hex colors by switching theme mocks and style assertions to the shared `mockTheme` from `app/util/theme`. > > Updates several test-only mocks to match current hook contracts (notably `useNetworkEnablement` now returning `popularEvmNetworks`/`popularMultichainNetworks`/`popularNetworks`, `useAnalytics` including additional required methods, and `useTailwind` mock shape changes), plus a small Perps test adjustment to mock `usePerpsLivePrices`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 32fe395. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…wind CSS (#27616) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> This PR migrates the `ChoosePassword` view and its `FoxRiveLoaderAnimation` sub-component away from legacy StyleSheet.create()-based styling toward the `MetaMask design system and Tailwind CSS`. Jira Link: https://consensyssoftware.atlassian.net/browse/TO-602 ## **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: migrate ChoosePassword to design system components and Tailwind CSS ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: ChoosePassword screen — visual and functional parity after style migration Scenario: New wallet creation with SRP backup Given the app is freshly installed and onboarding is in progress When the user reaches the "Create Password" screen Then the screen renders with title, password field, confirm field, checkbox, and button And the "Create Password" button is disabled When the user types a password ≥ 8 characters And types the same value in the confirm password field And checks the "I understand" checkbox Then the "Create Password" button becomes enabled When the user taps "Create Password" Then the Fox Rive loading animation appears and the form is hidden And after completion the user is navigated to the Manual Backup step Scenario: Password mismatch validation Given the user is on the "Create Password" screen When the user types different values in each password field Then a mismatch error is displayed and the button stays disabled Scenario: Password too short Given the user is on the "Create Password" screen When the user types fewer than 8 characters Then the helper text "Must be at least 8 characters" is always visible Scenario: OAuth (social login) flow Given the user arrived via a social login Then the button is enabled without checking the checkbox And on submit the user is navigated to the Onboarding Success screen Scenario: Dark-mode theme correctness Given the device is in dark mode When the user opens the "Create Password" screen Then all text, backgrounds, and icons use correct design system colour tokens And no hardcoded colours are visible ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/79e2215f-8874-46eb-b332-840ac271a75d https://github.com/user-attachments/assets/70708f0b-5417-4b65-bbbe-4d765c71a379 ## **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** > UI refactor of the password creation/onboarding flow that changes component primitives, accessibility identifiers, and loading/form rendering, which can cause visual or E2E regressions despite largely preserving business logic. > > **Overview** > Migrates the `ChoosePassword` screen and `FoxRiveLoaderAnimation` from legacy `StyleSheet` + internal component-library primitives to **design-system React Native components** (`Box`, `Text`, `TextField`, `Button`, `Checkbox`, `Icon`) styled via **Tailwind** (`useTailwind`), deleting the old `*.styles.ts` files. > > Adjusts a few UI behaviors and identifiers (e.g., confirm-password eye toggle disabled when empty, adds `accessibilityLabel`s for password fields, updates icon color tokens) and updates snapshots/unit tests accordingly, including refactored `ChoosePassword` tests and Detox page object selectors to use labels on Android. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 7ddefaf. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…gas fee token is selected (#27806) <!-- 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** Hide speed row on network fee section on confirmation page when gas fee token is selected. ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/CONF-1057 ## **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="398" height="848" alt="Screenshot 2026-03-23 at 7 54 41 PM" src="https://github.com/user-attachments/assets/7e9c2a3f-af1b-4ea7-8f1f-beb4685fc633" /> <img width="394" height="844" alt="Screenshot 2026-03-23 at 7 54 12 PM" src="https://github.com/user-attachments/assets/ec597c61-9be2-40a2-a449-fd1339dda958" /> ## **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-logic change gated by existing state (selected gas fee token / simulation loading) with added unit coverage. Main risk is accidentally suppressing the speed row in edge cases where these flags are miscomputed. > > **Overview** > Prevents the Network fee section from rendering the `Speed` row while simulation data is loading and whenever a non-native gas fee token is selected. > > Adds test coverage to ensure `Speed` is hidden in both conditions. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit dc7720f. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
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 : )