Skip to content

[pull] main from MetaMask:main#792

Merged
pull[bot] merged 7 commits into
Reality2byte:mainfrom
MetaMask:main
May 28, 2026
Merged

[pull] main from MetaMask:main#792
pull[bot] merged 7 commits into
Reality2byte:mainfrom
MetaMask:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented May 28, 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 : )

PatrykLucka and others added 7 commits May 28, 2026 17:37
…ok and update related components (#30735)

<!--
Please submit this PR as a draft initially.

Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.

In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->

## **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?
-->
Homepage Predict empty-state World Cup discovery was loading markets
through a separate path (useHomepagePredictTaggedMarkets → category:
'sports' + hardcoded tag_id=102350), while the dedicated World Cup
screen uses usePredictWorldCupMarkets with the ALL tab
(buildPredictWorldCupAllQuery → events/keyset?tag_slug=...).

This PR aligns the homepage feed with the World Cup screen by
introducing useHomepagePredictWorldCupMarkets, which wraps
usePredictWorldCupMarkets with PREDICT_WORLD_CUP_TAB_KEYS.ALL and
selectPredictWorldCupConfig. The NBA champion discovery feed is
unchanged and still uses useHomepagePredictTaggedMarkets.

Why: Avoid divergent Polymarket query logic between homepage discovery
and the World Cup screen.

How: Thin homepage hook + swap the World Cup feed in PredictionsSection;
remove the obsolete PREDICT_HOME_WORLD_CUP_TAG_QUERY constant; update
types and test mocks.
## **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 bug that was causing wrong events number in world
cup (predict) section

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: Homepage Predict empty state World Cup discovery

  Scenario: World Cup discovery loads when user has no positions
    Given Predict is enabled
    And the user is in the Predict positions empty state AB treatment
    And the user has no open Predict positions

    When the user opens the Homepage Predict section
    Then the World Cup discovery rail renders (event count, bracket pills, championship row)
    And World Cup markets are fetched via the World Cup ALL-tab keyset query (tag_slug from feature flag config)

  Scenario: World Cup discovery navigation still works
    Given the World Cup discovery rail is visible on Homepage

    When the user taps the men's World Cup row or a bracket pill
    Then navigation opens the World Cup screen (or Predict market list fallback) with the expected initial tab

  Scenario: NBA champion row is unaffected
    Given NBA champion homepage discovery is enabled

    When the user opens the Homepage Predict empty state
    Then the NBA champion row still loads via the existing tagged-markets hook
```

## **Screenshots/Recordings**

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

### **Before**

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

### **After**
<img width="403" height="234" alt="Screenshot 2026-05-28 at 13 26 58"
src="https://github.com/user-attachments/assets/e26cb906-3a85-4ffc-a961-3ee7c1a29652"
/>

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

## **Pre-merge author checklist**

<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.

Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->

- [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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->

- [ ] 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 Polymarket fetch logic for a user-visible homepage discovery
rail (fixes wrong event counts) but is scoped to Predict UI with tests
updated; NBA feed unchanged.
> 
> **Overview**
> Homepage Predict **empty-state World Cup discovery** no longer loads
markets through `useHomepagePredictTaggedMarkets` with a hardcoded
sports `tag_id=102350`. It now uses a new
**`useHomepagePredictWorldCupMarkets`** hook that wraps
**`usePredictWorldCupMarkets`** on the World Cup **ALL** tab with
**`selectPredictWorldCupConfig`**, matching the dedicated World Cup
screen’s keyset/`tag_slug` query path.
> 
> **`PredictionsSection`** and the World Cup discovery UI types were
switched to that hook; the obsolete World Cup tag constant was removed
from **`HOMEPAGE_PREDICT_TAG_QUERIES`**. **NBA champion** discovery
still uses tagged markets. Tests and Homepage mocks were updated for the
new hook and World Cup feature-flag/hook stubs.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
c053706. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!-- CURSOR_AGENT_PR_BODY_BEGIN -->
## **Description**

Updated the Telegram icon SVG in the component-library to use the
official Telegram logo design (without the tail). This was requested by
the design team to align with the proper Telegram branding requirements
for the Telegram social login feature.

The icon was added to:
- `app/component-library/components/Icons/Icon/assets/telegram.svg`

The icon generation script (`yarn generate-icons`) was run to
regenerate:
- `Icon.types.ts` - Added `Telegram` to `IconName` enum
- `Icon.assets.ts` - Added import and mapping for the Telegram SVG

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Related to Telegram social login implementation.

## **Manual testing steps**

```gherkin
Feature: Telegram icon display

  Scenario: user views Telegram icon
    Given the app is running with design system components

    When user views a component using IconName.Telegram
    Then the official Telegram paper plane logo is displayed
```

## **Screenshots/Recordings**

### **Before**

N/A - Icon being added

### **After**

Icon can be verified by importing and using:
```tsx
import { Icon, IconName, IconSize } from '@metamask/design-system-react-native';

<Icon name={IconName.Telegram} size={IconSize.Lg} />
```

## **Pre-merge author checklist**

<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.

Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->

- [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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->

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

[Slack
Thread](https://consensys.slack.com/archives/C0354T27M5M/p1777358027891429?thread_ts=1777358027.891429&cid=C0354T27M5M)

<div><a
href="https://cursor.com/agents/bc-e1704607-edb3-5b15-adad-715dacefda4d"><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>&nbsp;<a
href="https://cursor.com/background-agent?bcId=bc-e1704607-edb3-5b15-adad-715dacefda4d"><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;</div>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
…lidate header hook (#30714)

## **Description**
**For reviewer**: please use this link to better see the diff without
formatting changes:
https://github.com/MetaMask/metamask-mobile/pull/30714/changes?w=1

**Summary**
Migrates the main Card stack (MainRoutes in
app/components/UI/Card/routes/index.tsx) from navigator-provided headers
(headerLeft / headerRight with ButtonIcon) to in-screen HeaderStandard
chrome, matching the pattern already used by Card onboarding via
OnboardingStep.

Also consolidates the two header hooks (onboarding-only + main) into a
single shared useCardHeaderHandlers so every Card screen builds its
header from the same primitives.

**What changed**
New shared hook: useCardHeaderHandlers
- app/components/UI/Card/hooks/useCardHeaderHandlers.ts (+ tests)
- CardHeaderMode:
> back → navigation.goBack()
> close-with-confirmation → exit alert → WALLET.HOME
> close-direct → WALLET.HOME
> close-reset-home → navigation.reset to CARD.HOME
> none → no header handlers
- Returns props that spread directly into <HeaderStandard ...handlers
/>.
- Close button testID standardized as card-header-close-button.

**Removed**
- useCardOnboardingNavigationHandlers.ts + its test — replaced by
useCardHeaderHandlers.
- cardDefaultNavigationOptions, cardChooseYourCardNavigationOptions,
cardSpendingLimitNavigationOptions, headerStyle from routes/index.tsx.

**Navigator (routes/index.tsx)**
- MainRoutes now sets screenOptions={{ headerShown: false }}.
- SpendingLimit keeps per-screen options only to disable swipe-back when
flow === 'onboarding'.

| Screen | Header behavior |
| --- | --- |
| `CardHome` | `back` (main + error state) |
| `ReviewOrder` | `back` |
| `OrderCompleted` | `back` |
| `Cashback` | `back` |
| `CardAuthentication` | `back` (via `OnboardingStep` `headerMode`) |
| `ChooseYourCard` | `none` (`flow: onboarding`) / `back` (`upgrade`,
`home`); safe-area `edges` adjusted |
| `SpendingLimit` | `close-reset-home` (`flow: onboarding`) / `back`
(other flows); header in loading, error, and main branches |
| `CardWelcome` | Unchanged (no header) |
| `OnboardingStep` | Switched to `useCardHeaderHandlers` (types aligned
to `CardHeaderMode`) |


Android test build:
https://github.com/MetaMask/metamask-mobile/actions/runs/26588329872

<!--
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: Card screens render in-screen HeaderStandard chrome
  Background:
    Given the user is signed in to the wallet
    And the user has completed Card onboarding (where required)
  
# ----- CardHome -------------------------------------------------------------
  Scenario: CardHome shows a back header in the main state
    Given the user is on the Wallet home screen
    When the user opens the Card tab
    Then the CardHome screen is shown
    And a back arrow is visible at the top-left of the screen
    And no duplicate header / no gap is rendered above the content
  Scenario: Tapping back from CardHome returns the user to the previous screen
    Given the user is on CardHome
    When the user taps the back arrow in the header
    Then the user is returned to the previous screen (Wallet home)
  Scenario: CardHome error state still shows a back header
    Given CardHome fails to load and renders the error state
    Then the back arrow is still visible in the header
    When the user taps the back arrow
    Then the user is returned to the previous screen
 
 # ----- ReviewOrder / OrderCompleted / Cashback / CardAuthentication ---------
  Scenario Outline: <screen> shows a back header
    Given the user navigates to <screen>
    Then a back arrow is visible at the top-left
    When the user taps the back arrow
    Then the user is returned to the previous screen
    Examples:
      | screen             |
      | ReviewOrder        |
      | OrderCompleted     |
      | Cashback           |
      | CardAuthentication |
 
 # ----- ChooseYourCard -------------------------------------------------------
  Scenario: ChooseYourCard in the onboarding flow has no header chrome
    Given the user is in the Card onboarding flow
    When the user reaches the ChooseYourCard step
    Then no back or close button is visible at the top of the screen
    And the top safe-area inset is respected (no content under the status bar)
  Scenario Outline: ChooseYourCard outside onboarding shows a back header
    Given the user opens ChooseYourCard with flow "<flow>"
    Then a back arrow is visible at the top-left
    When the user taps the back arrow
    Then the user is returned to the previous screen
    Examples:
      | flow     |
      | upgrade  |
      | home     |

  # ----- SpendingLimit --------------------------------------------------------
  Scenario Outline: SpendingLimit outside onboarding shows a back header
    Given the user opens SpendingLimit with flow "<flow>"
    Then a back arrow is visible at the top-left
    And the screen can be dismissed by swiping back (iOS)
    When the user taps the back arrow
    Then the user is returned to the previous screen
    Examples:
      | flow   |
      | manage |
      | enable |
  Scenario: SpendingLimit in the onboarding flow shows a close button that resets to CardHome
    Given the user is in the Card onboarding flow
    And the user is on SpendingLimit with flow "onboarding"
    Then a close (X) button is visible at the top-left
    And the screen cannot be dismissed by swiping back
    When the user taps the close button
    Then the navigator is reset and the user lands on CardHome
    And the back stack does not contain the SpendingLimit onboarding screen
  Scenario: SpendingLimit loading and error states render the header
    Given SpendingLimit is loading
    Then the header is visible above the loading indicator
    Given SpendingLimit fails to load
    Then the header is visible above the error state

  # ----- Onboarding regression (header behavior unchanged) --------------------
  Scenario Outline: Onboarding step header behavior is unchanged
    Given the user is on the "<step>" onboarding screen
    Then the header mode "<mode>" is rendered
    When the user taps the header action
    Then the expected behavior occurs
    Examples:
      | step                | mode                     |
      | SignUp              | back                     |
      | ConfirmEmail        | back                     |
      | PersonalDetails     | close-with-confirmation  |
      | PhysicalAddress     | close-with-confirmation  |
      | VerifyingVeriffKYC  | close-direct             |
  Scenario: Close-with-confirmation prompts before exiting onboarding
    Given the user is on an onboarding step that uses "close-with-confirmation"
    When the user taps the close (X) button
    Then a "leave onboarding?" alert is shown with Cancel and Exit options
    When the user taps "Cancel"
    Then the user remains on the current onboarding step
    When the user taps the close (X) button again and confirms "Exit"
    Then the user is navigated to Wallet home
 
 # ----- Visual / device sanity ----------------------------------------------
  Scenario: Headers respect safe area on notched devices
    Given the device has a top notch / Dynamic Island
    When the user navigates to any migrated Card screen
    Then the header sits below the status bar with no overlap and no double inset


```

## **Screenshots/Recordings**

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

### **Before**

https://github.com/user-attachments/assets/eabfe621-b661-48e6-bcda-10ed152dee70


### **After**

https://github.com/user-attachments/assets/74a922b3-cfb4-4baa-8c81-834c7aa8aa00

Android test:

https://github.com/user-attachments/assets/01826eca-a29b-4766-9d9f-75c50c0a000a



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

## **Pre-merge author checklist**

<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.

Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->

- [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.

#### Performance checks (if applicable)

- [x] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->

- [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**
> Navigation and exit behavior changed across many Card screens
(including onboarding SpendingLimit reset and gesture rules);
regressions would mostly affect UX/back-stack, not security or payments.
> 
> **Overview**
> Main Card stack screens now render navigation chrome in-screen with
**`HeaderStandard`** and a shared **`useCardHeaderHandlers`** hook,
instead of stack **`headerLeft` / `headerRight`** options.
**`routes/index.tsx`** defaults to **`headerShown: false`** and drops
the old per-screen header option helpers; **SpendingLimit** still
disables swipe-back when **`flow === 'onboarding'`**.
> 
> **`useCardOnboardingNavigationHandlers`** is removed and replaced by
**`useCardHeaderHandlers`**, which adds **`close-reset-home`**
(navigator reset to **`CARD.HOME`**) and standardizes the close button
testID. **CardHome**, **Cashback**, **ReviewOrder**, **OrderCompleted**,
and related flows use **`back`**; **ChooseYourCard** uses **`none`** for
onboarding and **`back`** for upgrade/home with safe-area tweaks;
**SpendingLimit** uses **`close-reset-home`** vs **`back`** by flow;
**OnboardingStep** / **CardAuthentication** wire the same modes. Tests
drop navigator-header assertions and mock **`HeaderStandard`** where
needed.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
3bc157d. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.

Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.

In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->

## **Description**
* This PR removes the onboarding success animation for Android
social-login users to prevent a crash observed shortly after wallet
creation
<!--
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: Fixed a crash affecting some Android social-login users
by removing the onboarding success animation in that flow.

## **Related issues**

Fixes: #30737

## **Manual testing steps**

```gherkin
Feature: Android social onboarding success stability

  Scenario: Android social user reaches onboarding success
    Given user is on Android and signs up via social login
    When user completes wallet creation and lands on onboarding success
    Then the onboarding success animation should not render
    And the app should not crash

```

## **Screenshots/Recordings**

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

### **Before**


https://github.com/user-attachments/assets/e13a6a99-88c7-4a02-a5c4-cc8856141d21


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

### **After**


https://github.com/user-attachments/assets/7885dfb0-28e9-4193-8fc4-59ab25034c02


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

## **Pre-merge author checklist**

<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.

Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->

- [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.

#### Performance checks (if applicable)

- [x] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->

- [ ] 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**
> Targeted UI guard on an existing onboarding screen; no auth, key
material, or navigation reset logic changes beyond skipping one
animation.
> 
> **Overview**
> Skips the onboarding success end animation on **Android** when
navigation passes `showPasswordHint: true` (the social-login path from
`ChoosePassword`). The screen still shows the success title and actions;
only `OnboardingSuccessEndAnimation` is omitted for that platform/flag
combination.
> 
> A new optional route param and component prop wire `showPasswordHint`
from the navigator into `OnboardingSuccessComponent`, with `Platform.OS`
used to gate the animation.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
e352fa2. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description**

This is PR 3 of the GE-217 push pre-prompt rollout.

This PR mounts the push notification onboarding pre-prompt from
`Nav/Main` and wires the production flow for the two currently supported
startup variants:

- `push_permission`: shown to eligible users who have not granted OS
push permission or do not yet have notification preferences.
- `marketing_consent`: shown to eligible existing users with push
notifications enabled but marketing notification preferences disabled.

The prompt resolver now gates display on notification runtime
eligibility, completed onboarding, the default-on feature flag, one-time
“shown” storage, OS push permission status, Authenticated User Storage
notification preferences, and pending social-login marketing-consent
backfill. AUS preference reads stay behind the runtime gate, and
resetting the developer “push pre prompt shown” flag does not
immediately reopen the prompt until the app is restarted.

This PR also adds shared notification preference helpers used by
Settings and startup onboarding, background enablement for the push
pre-prompt path, marketing notification preference updates, toast copy,
and MetaMetrics/identify instrumentation for pre-prompt actions, OS
prompt responses, marketing consent, and push notification enablement.

## **Changelog**

CHANGELOG entry: Added a startup prompt for eligible users to enable
push notifications.

## **Related issues**

Fixes: GE-217

## **Manual testing steps**

```gherkin
Feature: Push notification startup pre-prompt

  Scenario: eligible user sees the push permission pre-prompt
    Given notifications are enabled for the build
    And the user is eligible for the push permission pre-prompt
    And the push pre-prompt has not already been shown

    When the user launches the app
    Then the push notification onboarding sheet is shown

    When the user taps "Yes"
    Then the native push permission prompt is requested
    And the startup surface is completed
    And notifications are enabled in the background

  Scenario: eligible user dismisses the push permission pre-prompt
    Given notifications are enabled for the build
    And the user is eligible for the push permission pre-prompt
    And the push pre-prompt has not already been shown

    When the user launches the app
    And the user taps "Not now"
    Then the push notification onboarding sheet closes
    And the startup surface is completed

  Scenario: existing user sees the marketing consent pre-prompt
    Given notifications are enabled for the build
    And the user already has notification preferences
    And the user has not enabled marketing consent
    And the push pre-prompt has not already been shown

    When the user launches the app
    Then the marketing consent onboarding sheet is shown

    When the user confirms marketing consent
    Then marketing consent is enabled
    And the startup surface is completed    
```

## Manual Testing Steps

### Preconditions

- Use a build with the notifications feature flag enabled.
- Use a device/simulator where OS notification permissions can be reset.
- After seeing either pre-prompt once, go to **Settings > Developer
options** and tap **Reset push pre prompt shown**, then fully kill and
reopen the app before testing another prompt.
- To force a clean first-run state, delete the app from the device and
install it again.
- To test update behavior, do not delete the app. Install/update the PR
build over an existing installed build so app data is preserved.

---

## Flow 1: New User / Push Permission Pre-Prompt

### Setup

1. Delete the app from the device.
2. Install the PR build.
3. If needed, reset OS notification permission for MetaMask from device
settings.
4. Open the app and complete onboarding with a new wallet or imported
wallet.
5. Keep marketing consent disabled during onboarding if the option is
shown.
6. Finish onboarding and land in the wallet.

### Steps

1. Confirm the push notification pre-prompt appears after onboarding.
2. Confirm the sheet explains push notifications and personalized
updates.
3. Tap **Not now**.
4. Confirm the sheet closes.
5. Confirm a toast appears saying notifications can be enabled later in
**Settings > Notifications**.
6. Go to **Settings > Developer options** and tap **Reset push pre
prompt shown**.
7. Fully kill and reopen the app.
8. Confirm the push notification pre-prompt appears again.
9. Tap **Yes**.
10. Confirm the native OS push notification prompt appears.
11. Tap **Allow**.
12. Confirm the sheet closes.
13. Confirm a success toast appears.
14. Go to **Settings > Notifications**.
15. Confirm notifications are enabled.
16. Confirm the relevant notification categories, including
marketing/updates, are enabled where available.

### Also Verify

- Repeat the **Yes** path and tap **Don’t Allow** on the OS prompt.
- Confirm the app does not crash.
- Confirm the sheet closes and the user sees guidance to enable
notifications later in settings.

---

## Flow 2: Existing User / App Update With Push Enabled But Marketing
Consent Disabled

### Setup

1. Start from an existing installed app with a completed wallet.
2. Do not delete the app.
3. Enable push notifications from **Settings > Notifications**.
4. Disable marketing consent from **Settings > Security & Privacy > Data
collection for marketing**.
5. Install/update to the PR build over the existing app.
6. Open the app and unlock the wallet.
7. If the prompt was already seen, use **Settings > Developer options >
Reset push pre prompt shown**, then fully kill and reopen the app.

### Steps

1. Confirm the existing-user marketing consent pre-prompt appears.
2. Confirm the prompt asks for personalized/marketing updates.
3. Tap **Not now**.
4. Confirm the sheet closes.
5. Confirm marketing consent remains disabled.
6. Confirm push notifications remain enabled.
7. Reset **push pre prompt shown** in Developer options.
8. Fully kill and reopen the app.
9. Confirm the existing-user marketing consent prompt appears again.
10. Tap **Confirm**.
11. Confirm the sheet closes.
12. Confirm a success toast appears.
13. Go to **Settings > Security & Privacy**.
14. Confirm **Data collection for marketing** is enabled.
15. Go to **Settings > Notifications**.
16. Confirm **Updates and Rewards** / marketing notification preferences
are enabled.

---

## Flow 3: Existing User / App Update With Marketing Consent Enabled But
Push Disabled

### Setup

1. Start from an existing installed app with a completed wallet but push
not enabled (also not denied)
2. Do not delete the app.
3. Enable marketing consent from **Settings > Security & Privacy > Data
collection for marketing**.
4. Disable push notifications from device OS settings or **Settings >
Notifications**.
5. Install/update to the PR build over the existing app.
6. Open the app and unlock the wallet.
7. Reset **push pre prompt shown** in Developer options if needed, then
fully kill and reopen.

### Steps

1. Confirm the push permission pre-prompt appears.
2. Tap **Yes**.
3. Confirm the native OS notification prompt appears.
4. Tap **Allow**.
5. Confirm notifications are enabled.
6. Confirm marketing consent remains enabled.

---

## Regression Checks

- The pre-prompt should only show once per install/session unless reset
from Developer options.
- Resetting **push pre prompt shown** should not immediately reopen the
prompt until the app is restarted.
- Deleting and reinstalling the app should allow the new-user flow to be
tested again.
- Updating the app without deleting it should preserve user state and
trigger the correct existing-user flow.
- Users with both push notifications and marketing consent already
enabled should not see either pre-prompt.

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

<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.

Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See docs/readme/ready-for-review.md for the full
checklist
semantics.
-->

- [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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [trace()](/app/util/trace.ts) for usage and
[addToken](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See docs/readme/ready-for-review.md.
-->

- [ ] 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.

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description**

Wires Batch Sell quote fetching and quote display into the Batch Sell
review flow.

This PR replaces the Batch Sell review placeholder state with real batch
quote request and quote data handling. It builds per-token quote
requests from selected source tokens, allocation amounts, destination
stablecoin, slippage, gas-included settings, and wallet address, then
sends the batch to `BridgeController`.

It also updates the review UI so rows, totals, quote details, and final
review consume real quote data. Rows now show batch-level loading
states, quote-unavailable states, high-price-impact indicators,
per-token slippage settings, and refreshed receive amounts. Allocation
sliders update source amounts in Redux and quote requests are debounced
to avoid excessive refetching.

The destination stablecoin selector now updates the selected stablecoin
immediately on row tap, and quote display is guarded so old-destination
quotes are treated as stale instead of briefly showing mismatched token
or fiat values after switching stablecoins.

## **Changelog**

CHANGELOG entry: Added quote fetching and quote review details to Batch
Sell.

## **Related issues**

Related to:
[SWAPS-4439](https://consensyssoftware.atlassian.net/browse/SWAPS-4439)

## **Manual testing steps**

```gherkin
Feature: Batch Sell quotes

  Scenario: user reviews and updates a batch sell quote
    Given the user has multiple eligible tokens on the same network
    And the user opens Batch Sell and selects multiple source tokens

    When the user taps Continue
    Then the quote screen opens with each allocation defaulted to 100%
    And token rows and Total received show loading skeletons while quotes load
    And token rows and Total received show quote amounts after quotes load

    When the user changes one token allocation with the slider
    Then all token rows and Total received return to loading while quotes refetch
    And updated row and total amounts are shown after the refetch completes

    When the user opens settings for a token row and changes slippage
    Then quotes are refetched for the batch
    And updated row and total amounts are shown after the refetch completes

    When the user changes the destination stablecoin
    Then stale quotes for the previous stablecoin are hidden
    And the Review button remains disabled until matching destination quotes load

    When at least one token has a valid quote and the user taps Review
    Then the final review sheet opens with only valid quoted tokens reflected in totals
```

## **Screenshots/Recordings**

### **Before**

n/a

### **After**


https://github.com/user-attachments/assets/c9193d86-5f53-40c8-a044-57c1e08640bc


## **Automated testing**

```bash
yarn jest app/components/UI/Bridge/hooks/useBatchSellQuoteData/useBatchSellQuoteData.test.ts --runInBand --watchman=false --forceExit
yarn jest app/components/UI/Bridge/Views/BatchSellReview/BatchSellReview.test.tsx --runInBand --watchman=false --forceExit
yarn eslint app/components/UI/Bridge/hooks/useBatchSellQuoteData/index.ts app/components/UI/Bridge/hooks/useBatchSellQuoteData/useBatchSellQuoteData.test.ts
```

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

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

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

[SWAPS-4439]:
https://consensyssoftware.atlassian.net/browse/SWAPS-4439?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches swap/bridge quote flows, Redux amounts, and controller state;
incorrect stale-quote or amount sync could show wrong receive totals
before submit (Sell all still TODO).
> 
> **Overview**
> Replaces Batch Sell review placeholders with **live batch quote
fetching and display** via new `useBatchSellQuoteData` and
`useBatchSellQuoteRequest`, driving row amounts, totals,
loading/unavailable states, high price impact, quote expiry (“Get new
quote”), and gas checks on final review.
> 
> **Allocation and Redux:** Sliders move from 25% snaps to **1%
rounded** values with smoother panning; source token amounts, default
slippages, and destination token are seeded on Continue and kept in sync
when allocations change. **Stale quotes** after switching destination
stablecoin are hidden until matching quotes load.
> 
> **UI/navigation:** Quote details and final review read from
Redux/controller state instead of route params; unmount clears
**BridgeController** quote state but not full bridge Redux. Adds a
price-impact info modal and improves stablecoin balance display (fiat vs
token fallback).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
229dd4a. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Continues the `TouchableOpacity` → `Pressable` migration started in
#30543 by migrating six shared design-system row primitives. These sit
beneath dozens of selector flows (account picker, network selector,
Buy/Deposit modals, Card onboarding, Rewards, multi-select token
search), so fixing them once cascades.

Migrated components:
- `ListItemSelect`
- `ListItemMultiSelect`
- `ListItemMultiSelectButton`
- `ListItemMultiSelectWithMenuButton`
- `CellSelectWithMenu` (the inner secondary-text press target)
- `PickerBase` (+ `PickerAccount` consumer)

Secondary changes:
- **`Pressable` and `PressableGH` now `forwardRef`.** `TouchableOpacity`
forwarded refs; without this the migration would have been a quiet
capability regression for any future caller that wants to `measure()` /
focus / animate the underlying view. Added real ref-forwarding tests
(assert `ref.current.measure` exists) to both primitives.
- **Removed `PickerAccount`'s manual pressed-state machinery.** It
maintained `useState(pressed)` + `onPressIn`/`onPressOut` handlers + a
`basePressed` style swap to `background.pressed` — exactly what
`Pressable` now does for free.
- **Dropped resting `background.default` from
`ListItemSelect`/`ListItemMultiSelect`.** Matches the SettingsDrawer
precedent from #30543: parent surface (sheet / screen) owns the resting
background so the pressed overlay composites correctly, including in
pure-black mode.
- **Test updates:** Multi-select rows now have a correctly role-tagged
row AND an inner `ButtonIcon`, so `getByRole('button')` is ambiguous.
Switched affected tests to `getAllByRole('button')[0]` to target the
row.

## **Changelog**

CHANGELOG entry:null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TMCU-790

## **Manual testing steps**

```gherkin
Feature: Row press feedback across DS primitives

  Scenario: user presses a single-select row in pure-black mode
    Given MM_PURE_BLACK_PREVIEW=true is set in .js.env and the app is rebuilt
    When user opens Buy → Token selector and taps any token row
    Then the row background briefly shifts to background.pressed and remains clearly visible
    And the row does not "disappear" against the pure-black backdrop
    And there is no full-subtree opacity dim

  Scenario: user presses a multi-select row with a side menu button
    Given the app is open
    When user opens the wallet header account picker and taps an account row
    Then the row flashes the pressed token
    And the MoreVertical (⋮) menu button at the right is independently pressable

  Scenario: user presses the wallet header account picker
    Given the app is open on the Wallet screen
    When user taps the account name pill in the header
    Then the pill briefly shifts to background.pressed (no manual state, no opacity dim)
    And the account selector sheet opens

  Scenario: disabled rows still appear dimmed
    Given a list with a disabled ListItemSelect row
    Then the disabled row renders at opacity 0.5 (behavior unchanged)
```

## **Screenshots/Recordings**

### Notice there is no dim anymore when pressed


https://github.com/user-attachments/assets/469def01-dfb1-40f7-a75f-5862430f5f33

### **Before**


https://github.com/user-attachments/assets/3965483c-28aa-4c57-b0c9-c39ad97d2dae

### **After**


https://github.com/user-attachments/assets/469def01-dfb1-40f7-a75f-5862430f5f33

## **Pre-merge author checklist**

<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.

Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->

- [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.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->

- [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**
> Touches widely reused UI primitives and press/visual behavior
(including pure-black mode), but changes are localized to the component
library with added tests and no auth or data-path impact.
> 
> **Overview**
> Continues the **`TouchableOpacity` → design-system `Pressable`**
migration on shared row and picker primitives used across
account/network selectors, buy flows, and multi-select lists.
> 
> **`ListItemSelect`**, **`ListItemMultiSelect`**,
**`ListItemMultiSelectButton`**,
**`ListItemMultiSelectWithMenuButton`**, **`CellSelectWithMenu`**
(clickable secondary text), **`PickerBase`**, and **`PickerAccount`**
now use **`Pressable`** for press handling and **`background.pressed`**
overlay instead of subtree opacity dimming. **`Pressable`** and
**`PressableGH`** gain **`forwardRef`** (with ref tests) so callers can
still **`measure`** the native view.
> 
> Style/layout tweaks: resting **`background.default`** removed from
select rows so parent surfaces own the backdrop; multi-select button
rows move disabled opacity and selection background onto the outer
pressable **`container`**; **`PickerAccount`** drops manual
pressed-state styling and **`onPressIn`/`onPressOut`** wiring. Tests add
**`ROW_TEST_ID`** targeting and assert row
**`accessibilityRole="button"`** where row + side **`ButtonIcon`** both
expose buttons.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
ec0a797. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@pull pull Bot locked and limited conversation to collaborators May 28, 2026
@pull pull Bot added the ⤵️ pull label May 28, 2026
@pull pull Bot merged commit e0eb673 into Reality2byte:main May 28, 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.

7 participants