Skip to content

[pull] main from MetaMask:main#511

Merged
pull[bot] merged 15 commits into
Reality2byte:mainfrom
MetaMask:main
Feb 10, 2026
Merged

[pull] main from MetaMask:main#511
pull[bot] merged 15 commits into
Reality2byte:mainfrom
MetaMask:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Feb 10, 2026

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 : )

bfullam and others added 15 commits February 10, 2026 12:32
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
Adds icons to the network pills in the bridge token selector.
<!--
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 icons to the bridge token selector network pills

## **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**
> Primarily UI rendering changes plus minor test updates; low risk aside
from potential layout/visual regressions in the network pill row.
> 
> **Overview**
> Bridge token selector network pills now render a network icon
alongside the chain name by switching the `ButtonToggle` label to a
composed `AvatarNetwork` + `Text` row and sourcing icons via
`getNetworkImageSource`.
> 
> Tests are updated to mock the design-system avatar components and
`getNetworkImageSource`, and a new unit assertion verifies icons render
per chain; the bridge smoke test is adjusted to select the destination
network without an extra swipe.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
aa383c3. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

This Pr implements the "First time Interaction" alert for transactions.
mirroring the functionality from the extension. It warns users when they
interact with an address for the first time.

<!--
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 1st interaction alert to warn users when
interacting with an address for the first time.

## **Related issues**

Fixes: MetaMask/MetaMask-planning#6520

## **Manual testing steps**

1- Deploy an ERC20 using test dapp
2- Transfer some tokens and it should trigger the alert

## **Screenshots/Recordings**

[1st
timeinteraction.webm](https://github.com/user-attachments/assets/ec9dfe00-b477-49f6-b2e7-eff5b3c411cc)


<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches confirmation alert logic and `TransactionController`
initialization gating, which can affect when/if security warnings
appear. Changes are additive and covered by tests, but could alter alert
display conditions in transaction flows.
> 
> **Overview**
> Adds a new **“1st interaction”** warning alert in transaction
confirmations when the recipient address is being interacted with for
the first time (and is not an internal account or a verified/loading
trust-signal address), including new i18n strings and unit tests.
> 
> Plumbs this alert into the confirmation alert pipeline
(`useConfirmationAlerts`), metrics naming
(`useConfirmationAlertMetrics`), and enables the underlying
`TransactionController` first-time-interaction flag behind
`preferencesController.state.securityAlertsEnabled`.
> 
> Refactors alert anchoring in the from/to UI by introducing
`RowAlertKey.FromToAddress` and moving the existing burn-address alert
(and `FromToRow`’s `AlertRow`) to use it, removing the old
`RowAlertKey.BurnAddress`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
1c95a9d. 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**
Homogenized spacing on Explore page for perps items by adding a compact
mode for PerpsMarketRowItem styling.

<!--
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: homogenize spacing on Explore page for perps items

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/ASSETS-2634

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**
<img width="399" height="813" alt="image"
src="https://github.com/user-attachments/assets/5536c575-6b64-4885-8494-93b7b26fc4c8"
/>

<!-- [screenshots/recordings] -->

### **After**
<img width="394" height="823" alt="image"
src="https://github.com/user-attachments/assets/a36c85e8-e9db-4dea-9cab-ea75c28392f6"
/>

<!-- [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**
> Purely UI spacing behavior gated behind a new optional prop and a
single call site, with minimal blast radius and no data/auth logic
changes.
> 
> **Overview**
> Adds an optional `compact` mode to `PerpsMarketRowItem` that reduces
vertical padding (16px � 8px) via `useStyles` vars, enabling tighter
list spacing.
> 
> Updates Trending/Explore perps rows to render in compact mode, and
adjusts the component test mocks to match the new `useStyles` params
signature.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
7734b04. 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?
-->

For MegaETH mainnet and testnet, where speeds are around 250ms for tx
according to the gas api. We ned to display such behavior in the UI.

## **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: Adds FAST_NETWORKS filter for gas-speed component and
returns " < 1 Sec" when speed is < 1000ms
CHANGELOG entry: Modifies toHumanEstimatedTimeRange in utils/time.ts to
handle "fast network" filter and " < 1 Sec" display

## **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**

<img width="391" height="870" alt="Screenshot from 2026-02-08 22-26-49"
src="https://github.com/user-attachments/assets/add14759-0109-42f0-bb0c-eded4ec6f1d6"
/>

<img width="359" height="883" alt="Screenshot from 2026-02-09 13-38-00"
src="https://github.com/user-attachments/assets/8b64e160-b93c-488d-bd0c-c468e702530a"
/>


## **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**
> UI-only formatting change based on an existing timing value; minimal
behavioral impact and no security/data handling implications.
> 
> **Overview**
> Updates the confirmations `GasSpeed` display to special-case very fast
networks: when `minWaitTimeEstimate` is under 1000ms it now renders ` <
1 sec` instead of a humanized seconds value.
> 
> Includes a small cleanup in `useGasFeeEstimateLevelOptions` (no
functional change).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
fe65d96. 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**
Remove the logic in BridgeTokenSelector that pins the currently selected
token to the top of the includeAssets list sent to the popular tokens
and search APIs. Previously, the includeAssets memo would prepend the
selected token to ensure it always appeared first in the asset list.
This pinning is no longer needed — the selected token should appear in
its natural sorted position alongside other tokens.
The change simplifies the includeAssets memo by removing the
shouldPinSelectedToken check, the selectedAsset construction, the
duplicate-exclusion filter, and the conditional prepending. The
dependency array is also simplified from [filteredTokensWithBalance,
selectedToken, chainIdsToFetch, searchQuery] to just
[filteredTokensWithBalance], which reduces unnecessary recomputation
when the selected token or network filter changes without affecting the
underlying balance list.
<!--
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: Token list ordering in Bridge asset picker

  Scenario: selected token is not pinned to the top of the list
    Given the user has a source token selected (e.g. USDC on Ethereum)
    And the user opens the Bridge token selector

    When the token list loads
    Then the previously selected token appears in its natural sorted position
    And the previously selected token is NOT forced to the top of the list

  Scenario: token list displays correctly after network filter change
    Given the user has the Bridge token selector open
    And a specific network filter is selected

    When the user switches to a different network or "All"
    Then the token list updates to show tokens for the selected network
    And no token is artificially pinned to the top

  Scenario: search results are unaffected by selected token
    Given the user has a source token selected
    And the user opens the Bridge token selector

    When the user searches for a token (e.g. "ETH")
    Then search results appear in their natural API-returned order
    And the selected token is not prepended to search results
```

## **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**
> Small, localized change to token-list ordering/filtering logic; risk
is limited to which assets are prioritized in bridge token API queries.
> 
> **Overview**
> Removes the Bridge token selector logic that *prepended/pinned the
currently selected token* into the `includeAssets` list used by
`usePopularTokens`/`useSearchTokens`.
> 
> `includeAssets` is now derived solely from `filteredTokensWithBalance`
(stringified), dropping the selected-token filtering/deduping and
narrowing the memo dependencies accordingly.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
bd23006. 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**
Following #24313 we're
looking to centralize all tools and test resources in one place. This
marks the final PR deprecating `e2e` by moving all page objects and test
specific selectors. A follow up PR will be created to remove all
references from scripts and other tools.

This PR:
- moves the remaining files from `e2e/` to `tests/` , specifically
page-objects and utils
- updates all docs referring to the files being moved with this PR
- Splits `viewHelper.ts` into different `.flow.ts` files


Previous related PRs:
- #24988
- #24313
- #25031
- #25095
- #25167
- #25198
- #25219
- #25263
- #25279
- #25520
- #25533
- #25598
- #25636
- #25638
- #25698
- #25706
- #25764
- #25785


<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry:

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MMQA-1235

## **Manual testing steps**
N/A

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**
N/A
<!-- [screenshots/recordings] -->

### **After**
N/A
<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Large-scale path/import refactor across the test suite plus new flow
helpers; primary risk is broken test/build tooling due to missed
references rather than runtime app behavior.
> 
> **Overview**
> Moves remaining Detox E2E assets out of `e2e/` into `tests/`, updating
imports across sample feature specs, regression specs, helpers, and page
objects to use `tests/page-objects`, `tests/selectors`, `tests/tags`,
and `tests/helpers`.
> 
> Replaces the monolithic `viewHelper` usage by splitting
navigation/wait helpers into dedicated flow modules
(`tests/flows/browser.flow.ts`, `tests/flows/general.flow.ts`) and
refactors `tests/flows/wallet.flow.ts` to rely on the migrated page
objects and framework exports.
> 
> Updates repo hygiene/config to reflect the migration: ESLint test
overrides drop `e2e/`, CODEOWNERS points QA ownership at the new
`tests/page-objects`/`tests/flows` locations, Appwright and test
docs/agent notes remove `e2e` references, and the security code scanner
no longer ignores `e2e/` but continues to ignore `tests/`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
800011b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…Close and goBack calls from firing (#25862)

<!--
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**
Fixes bug where duplicate mUSD conversion transactions could be created
by spam pressing the "Pay with" menu items. The proposed fix is to
harden the `BottomSheet` component to dedupe duplicate events.

Bottomsheet changes:
- Deduped navigation: `navigation.goBack()` now runs at most once per
sheet lifecycle (guards duplicate close events).
- Hardened close requests: `onCloseBottomSheet(callback)` is now
first-wins while closing (ignores subsequent close requests so the
callback can’t be overwritten).
- Single-fire post callback: the `postCallback` now runs at most once on
close (even if multiple close events fire), and is cleared after
running.
- Resets on open: on open we reset the close-state refs so the sheet can
be reused safely.

<!--
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: updated bottomsheet component to dedupe events

## **Related issues**

Fixes: [MUSD-306: Duplicate mUSD transactions created when spam clicking
token in the "Pay with"
menu](https://consensyssoftware.atlassian.net/browse/MUSD-306)

## **Manual testing steps**

```gherkin
Feature: Idempotent BottomSheet close behavior

  Scenario: user closes a bottom sheet multiple times rapidly
    Given a bottom sheet is open and configured to navigate back on close

    When the user triggers multiple close actions in quick succession
    Then the app navigates back only once
    And any post-close callback runs at most once
    And logs are displayed to display this dedupe behaviour
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->
Video shows the bottomsheet calling `navigation.goBack()` twice.


https://github.com/user-attachments/assets/e56cb0f6-0e54-49c6-8bee-26ebc545e97c

### **After**

<!-- [screenshots/recordings] -->
N/A - Bottomsheet dedupes duplicate events


## **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 shared `BottomSheet` control flow used across many modals, so
regressions could affect navigation and post-close actions app-wide,
though changes are narrowly scoped to dedupe/guard logic with logging.
> 
> **Overview**
> Prevents duplicate bottom-sheet close side effects by **deduping
`navigation.goBack()` and post-close callbacks** within a single sheet
lifecycle. `BottomSheet` now ignores repeated `onCloseBottomSheet`
requests while closing, runs the stored post-callback at most once (and
clears it after use), and logs when duplicate close/navigation events
are skipped; these guards are reset on open.
> 
> Updates `PayWithModal` token selection to always close the sheet once
and perform the token-change logic in a single `onClosed` callback,
reducing the chance of duplicate transaction-triggering actions when
users spam-select tokens.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
152b105. 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**

Fixes `[missing {{ symbol }} value] Activity` text on the token details
page by falling back to a generic "Activity" when no symbol is present.

The `ActivityHeader` component previously used `asset.name ||
asset.symbol` directly in the `asset_overview.activity` translation. For
tokens lacking both a name and a symbol (e.g., some trending tokens),
this resulted in the i18n library displaying the missing placeholder
error. The change ensures a graceful fallback to
`navigation.transaction_activity` ("Activity") in such cases.

## **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: fix: Activity header symbol fallback

## **Related issues**

Fixes: #25819
https://consensyssoftware.atlassian.net/browse/ASSETS-2622

## **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.

---
<p><a
href="https://cursor.com/background-agent?bcId=bc-5567aeed-a29d-4e2c-a17a-89c13983d1dd"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img
alt="Open in Cursor" width="131" height="28"
src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;<a
href="https://cursor.com/agents?id=bc-5567aeed-a29d-4e2c-a17a-89c13983d1dd"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a></p>



<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Small UI/i18n fallback change with straightforward test coverage;
minimal blast radius outside the activity header display.
> 
> **Overview**
> Fixes the token details activity header to avoid rendering an i18n
"missing symbol" placeholder when an asset lacks both `name` and
`symbol`, by falling back to the generic `drawer.transaction_activity`
string.
> 
> Adds a new `ActivityHeader` unit test suite covering name-vs-symbol
precedence and the empty/undefined fallback cases.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0435bf5. 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**

Adds a search footer to the browser address bar autocomplete, enabling
direct navigation to URLs and web searches for any query.

## **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: feat: add google/web search inside browser search bar

## **Related issues**

Fixes: #25823
https://consensyssoftware.atlassian.net/browse/ASSETS-2622

## **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**

https://www.loom.com/share/fe79536e7f774dabad58b3f392243f72

## **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.

---
<p><a
href="https://cursor.com/background-agent?bcId=bc-a5f50c53-67da-49b7-8f9b-cfd420fef6ba"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img
alt="Open in Cursor" width="131" height="28"
src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;<a
href="https://cursor.com/agents?id=bc-a5f50c53-67da-49b7-8f9b-cfd420fef6ba"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a></p>


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes browser autocomplete selection behavior by introducing a new
always-visible footer action that feeds into existing
navigation/onSelect flows; risk is mainly UX/regression around what gets
selected and how URLs/search queries are constructed.
> 
> **Overview**
> Adds a **web search / direct URL** footer to the browser URL
autocomplete results, so any non-empty query can be opened as a URL
(when it looks like one) or searched via the user’s configured engine
(Google/DuckDuckGo).
> 
> Refactors `SitesSearchFooter` to support an injectable `onPress`
handler and `containerStyle` (defaulting to the existing browser
navigation via a new `useSearchFooterBrowserNavigation` hook), and wires
it into `UrlAutocomplete` as a `SectionList` footer that converts footer
clicks into a `Sites`-category selection and closes the autocomplete.
> 
> Adds a unit test asserting the footer renders as the default web
search option.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
41d5910. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…ckboxes (#25869)

## Summary
This PR adds several legal consent improvements to the Card onboarding
flow, focusing on US-specific requirements.

## Changes
1. **Email consent legal terms** - Added consent text to ConfirmEmail
screen: "By continuing, you agree to receiving email for login
verifications and alerts."

2. **E-sign consent improvements** - Made the consent text more concise
and improved clickable area usability by making only the document name
("E-Sign Act Consent and Disclosure") clickable instead of the entire
text.

3. **US-only consent checkboxes** - Added two required checkboxes for US
users on the Physical Address screen:
   - **Coinme Terms of Service** - Single checkbox with clickable link
- **Cross River Bank consent** - Checkbox with 4 clickable document
links (Terms & Conditions, Account Opening Disclosures, Notice of
Privacy Practices, CL Privacy Policy)
   - All checkboxes are required for US users to proceed
- Updated consent text to use "Cross River Bank" (without possessive)
and "CL Privacy Policy"

4. **USA PATRIOT Act notice** - Added concise legal notice for US users
on Verify Identity screen: "Federal law (USA PATRIOT Act) requires us to
verify your identity with ID and proof of address to help prevent
terrorism and money laundering. This usually takes 5 minutes."

All US-specific features use `selectedCountry?.key === 'US'` checks,
following the established pattern in the Card onboarding flow.

## Test plan
- [ ] Test email confirmation screen shows legal terms
- [ ] Test e-sign consent clickable area (only document name should be
clickable)
- [ ] Test US users see all 3 consent checkboxes on Physical Address
screen
- [ ] Test non-US users don't see the US-only checkboxes
- [ ] Test all document links open correctly
- [ ] Test consent text displays "Cross River Bank" and "CL Privacy
Policy"
- [ ] Test US users see PATRIOT Act notice on Verify Identity screen
- [ ] Test non-US users see original text on Verify Identity screen
- [ ] Test form validation requires all checkboxes for US users

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Bruno Nascimento <bruno.nascimento@consensys.net>
<!--
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 restores a `.gitignore` change that was no longer ignoring
`e2e/reports` to prevent developers from making commits with these
files.

<!--
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**
N/A

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**
N/A
<!-- [screenshots/recordings] -->

### **After**
N/A
<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] 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**
> Only affects repo hygiene (gitignore + deleting a generated test
artifact) with no runtime code changes.
> 
> **Overview**
> Prevents accidental commits of legacy end-to-end test report artifacts
by adding `e2e/reports` to `.gitignore`.
> 
> Removes the previously committed `e2e/reports/junit.xml` report file
from the repository.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
577a08b. 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**
CI now includes component-view-test coverage in the unified coverage
merge by running yarn test:view with JSON coverage output, renaming the
report to coverage-view.json, and uploading it as an artifact.

The merge-unit-tests job is updated to wait for both unit-tests and
component-view-test, so the existing test:merge-coverage step merges
coverage from both sources before publishing the final lcov.info.

Adds an HTML artifact to check fully the component view test coverage by
file. It can be find under Summary > Artifacts

<!--
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**
> Workflow-only changes to CI test/coverage steps; primary risk is
broken artifact paths or coverage merge ordering causing CI failures.
> 
> **Overview**
> CI now includes `component-view-test` coverage in the unified coverage
merge by running `yarn test:view` with JSON coverage output, renaming
the report (`coverage-component-view.json`), and uploading it as an
artifact.
> 
> The `merge-unit-tests` job is updated to wait on both `unit-tests` and
`component-view-test` before running the existing coverage
merge/validation, and `component-view-test` additionally publishes an
HTML coverage report artifact for easier inspection.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
c06a120. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

The Perps market category filter pills had two UX issues:

1. **Pills disappeared when a category was selected** — selecting a
category (e.g. "Crypto") would hide all other pills and show only the
selected one with a dismiss "×". This made it impossible to quickly
switch between categories without first dismissing the current filter.

2. **Selected pill was invisible in light mode** — the selected pill
background used `theme.colors.overlay.inverse` which resolves to
`#ffffff` (white) in **both** light and dark themes. On a white/light
background this made the selected pill completely invisible.

### Changes

**`PerpsMarketCategoryBadges`** — Removed the dual-render-path pattern.
The component now always renders all pills in a horizontal `ScrollView`.
The selected pill is visually highlighted and shows a dismiss "×" icon.
Tapping the selected pill toggles it off (back to "all"). Tapping
another pill switches the filter directly. Removed unused `View` and
`FadeOut` imports, and the unused `container` style.

**`PerpsMarketCategoryBadge.styles`** — Changed the selected pill
background from `overlay.inverse` (`#ffffff` in both themes) to
`icon.default` (`#121314` in light mode, `#ffffff` in dark mode),
ensuring strong contrast in both themes. Text color (`icon.inverse`)
already correctly inverts per theme.

**Tests** — Updated `PerpsMarketCategoryBadges.test.tsx` to reflect the
new behavior: all pills remain visible when one is selected, tapping a
selected pill deselects it, tapping a different pill switches
categories, and the dismiss icon only appears on the selected pill.

## **Changelog**

CHANGELOG entry: Fixed Perps market category filter pills disappearing
when a category is selected, and fixed selected pill being invisible in
light mode

## **Related issues**

Fixes: #25900

## **Manual testing steps**

```gherkin
Feature: Perps Market Category Filter Pills

  Scenario: user views category pills with no filter active
    Given the user is on the Perps markets list screen
    And no category filter is selected

    When the user views the filter bar
    Then all category pills (Crypto, Stocks, Commodities, Forex, New) are visible
    And no pill is highlighted

  Scenario: user selects a category filter
    Given the user is on the Perps markets list screen
    And no category filter is selected

    When the user taps the "Crypto" pill
    Then the "Crypto" pill is highlighted with a dark background (light mode) or white background (dark mode)
    And the "Crypto" pill shows a dismiss "×" icon
    And all other pills (Stocks, Commodities, Forex, New) remain visible and unselected
    And the market list is filtered to show only Crypto markets

  Scenario: user deselects a category filter by tapping the selected pill
    Given the user is on the Perps markets list screen
    And the "Crypto" category filter is active

    When the user taps the "Crypto" pill (or its dismiss "×" icon)
    Then no category filter is active
    And all pills return to unselected state
    And the market list shows all markets

  Scenario: user switches category filter directly
    Given the user is on the Perps markets list screen
    And the "Crypto" category filter is active

    When the user taps the "Stocks" pill
    Then the "Stocks" pill becomes highlighted with dismiss icon
    And the "Crypto" pill returns to unselected state
    And the market list is filtered to show only Stocks markets

  Scenario: selected pill is visible in light mode
    Given the user is using the app in light mode
    And the user is on the Perps markets list screen

    When the user taps any category pill
    Then the selected pill is clearly visible with a dark background and white text
    And it is distinguishable from the unselected pills
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

- Selecting a category hid all other pills, showing only the selected
one
- Selected pill was invisible in light mode (white on white)

### **After**

- All pills always remain visible; selected pill is highlighted with
dismiss "×"
- Selected pill has strong contrast in both light and dark modes



https://github.com/user-attachments/assets/f54536f0-29e2-4c71-8bdd-d4549db51619



## **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**
> UI-only behavior/styling change limited to the Perps category filter
pills, with updated unit tests; low risk aside from potential UX
regressions in selection toggling.
> 
> **Overview**
> Fixes Perps market category filter pills UX by always rendering the
full horizontal list and letting the selected pill *toggle off* back to
`all` when tapped again (instead of switching to a single-pill
dismiss-only view).
> 
> Updates selected-pill styling to use `theme.colors.icon.default` for
the background (with `icon.inverse` text) to ensure the selected state
is visible in light mode, removes unused container styling/animations,
and adjusts tests to cover the new toggle/switch and dismiss-icon
behavior.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
8411e05. 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**

Fixes a bug with payment method selection in the feature flagged unified
buy V2 feature. Related core PR:
MetaMask/core#7863

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [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**
> Dependency-only version bump with no direct application code changes;
risk is limited to behavioral differences introduced by
`@metamask/ramps-controller@7.1.0`.
> 
> **Overview**
> Bumps the `@metamask/ramps-controller` dependency from `7.0.0` to
`7.1.0` and updates `yarn.lock` accordingly, pulling in the upstream
bugfixes (notably around payment method selection in unified buy v2).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
7671b49. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…onents (#25791)

## **Description**

Reorganizes the Ramp code domain (`app/components/UI/Ramp/`) to clearly
separate Views (screens/modals) from reusable components, and moves
`RegionSelector` from the Settings domain into Ramp ownership.

**Problem:**
1. `RegionSelector` lived in `app/components/Views/Settings/` which is
owned by `@MetaMask/mobile-core-ux` in CODEOWNERS. Any Ramp changes to
it triggered cross-team reviews.
2. `app/components/UI/Ramp/components/` mixed navigable Views
(screens/modals) with pure reusable components, making the codebase
harder to navigate and understand.

**Solution:**
- Created `app/components/UI/Ramp/Views/` directory for all navigable
screens and modals
- Moved `RegionSelector` from
`app/components/Views/Settings/RegionSelector/` to
`app/components/UI/Ramp/Views/Settings/RegionSelector/`
- Moved all screen-like components from `components/` to `Views/`:
  - `BuildQuote` → `Views/BuildQuote/`
  - `TokenSelection` → `Views/TokenSelection/`
  - `PaymentSelectionModal` → `Views/Modals/PaymentSelectionModal/`
  - `SettingsModal` → `Views/Modals/SettingsModal/`
  - `UnsupportedTokenModal` → `Views/Modals/UnsupportedTokenModal/`
- Updated all import paths across the codebase
- Regenerated snapshots for moved test files

**New structure:**
```
app/components/UI/Ramp/
├── Views/                          # Screens & modals (navigated to)
│   ├── BuildQuote/
│   ├── TokenSelection/
│   ├── Settings/
│   │   └── RegionSelector/         # ← moved from Views/Settings/
│   └── Modals/
│       ├── PaymentSelectionModal/
│       ├── SettingsModal/
│       └── UnsupportedTokenModal/
└── components/                     # Pure reusable components only
    ├── PaymentMethodPill/
    ├── QuickAmounts/
    ├── TokenListItem/
    └── ...
```

This follows the same pattern already established by `Aggregator/Views/`
and `Deposit/Views/`.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Refs: #25615 (the PR that introduced `RegionSelector` usage in Ramp,
which highlighted the cross-team ownership issue)

## **Manual testing steps**

```gherkin
Feature: Ramp folder reorganization

  Scenario: User navigates through token selection flow
    Given the app is running on the BuildQuote screen (post-merge of #25615)

    When user taps back to go to token selection
    Then the token list should load and display correctly
    And user can search for tokens
    And tapping an unsupported token's info icon shows the modal

  Scenario: User selects payment method
    Given user is on the BuildQuote screen with an amount entered

    When user taps the payment method pill
    Then the payment selection modal should open
    And payment methods should display correctly
    And tapping "change provider" should slide to provider selection
    And selecting a provider should return to payment methods

  Scenario: User opens build quote settings
    Given user is on the BuildQuote screen

    When user taps the settings gear icon
    Then the settings modal should open with order history option
    And contact support option should be visible if provider has support URL

  Scenario: User changes region in settings
    Given user navigates to Settings > Region

    When user opens the region selector
    Then countries should load and display with flags
    And user can search for countries
    And tapping USA should show states view
    And selecting California should save and navigate back
    And the back button in states view should return to countries

  Scenario: Cold start verification
    Given the app is freshly started

    When user navigates through the complete Buy flow
    Then no blank screens or navigation crashes occur
    And all screens render correctly
```

**Video recording is attached showing all scenarios working correctly.**

## **Screenshots/Recordings**

### **Before**
N/A - Internal refactor only, no UI changes

### **After**
Video recording demonstrating all manual testing scenarios:


https://github.com/user-attachments/assets/b73ae1f3-252f-4210-875e-1a222297574f

## **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**
> Mostly folder/import re-wiring plus snapshot updates; main risk is a
broken import/navigation route if the moved `RegionSelector` path is
incorrect.
> 
> **Overview**
> Moves the `RegionSelector` screen import used by main navigation from
`Views/Settings` into the Ramp-owned
`UI/Ramp/Views/Settings/RegionSelector` location.
> 
> Updates Ramp Aggregator/Deposit Jest snapshots to match the new UI
rendering for icon buttons (notably smaller icon sizes and reduced
`borderRadius`).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
5af35f1. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Amitabh Aggarwal <aggarwal.amitabh@gmail.com>
@pull pull Bot locked and limited conversation to collaborators Feb 10, 2026
@pull pull Bot added the ⤵️ pull label Feb 10, 2026
@pull pull Bot merged commit 3633f95 into Reality2byte:main Feb 10, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.