Skip to content

[pull] main from MetaMask:main#843

Merged
pull[bot] merged 20 commits into
Reality2byte:mainfrom
MetaMask:main
Jun 18, 2026
Merged

[pull] main from MetaMask:main#843
pull[bot] merged 20 commits into
Reality2byte:mainfrom
MetaMask:main

Conversation

@pull

@pull pull Bot commented Jun 18, 2026

Copy link
Copy Markdown

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

Matt561 and others added 20 commits June 17, 2026 17:24
<!--
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.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.

  type=text           Section must contain non-placeholder prose.
  type=changelog      Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
                      comment but do not block the PR.

Sections without a directive are checked for structural presence only.
-->

## **Description**
Added Money account first time deposit animation that is fired from new
globally mounted `useMoneyFirstTimeDepositTracker`. This animation only
fires if there are no other confirmed Money account deposits already.
Previously failed deposits don't block the animation.

Added `selectMoneyFirstTimeDepositAnimationEnabledFlag` which uses
`earnMoneyFirstTimeDepositAnimationEnabled` LD flag and
`MM_MONEY_FIRST_TIME_DEPOSIT_ANIMATION_ENABLED` env var to
enable/disable the first time deposit animation.

<!-- mms-check: type=text required=true -->

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

<!-- mms-check: type=changelog required=true blocking=true -->

<!--
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 Money account first time deposit animation

## **Related issues**

<!-- mms-check: type=issue-link required=true -->

Fixes: [MUSD-997: First time deposit
animation](https://consensyssoftware.atlassian.net/browse/MUSD-997)

## **Manual testing steps**

<!-- mms-check: type=manual-testing required=true -->

```gherkin
Feature: First-time Money account deposit animation

  Scenario: user completes their first Money account deposit
    Given the user has no prior confirmed Money account deposit transactions
    And the first-time deposit animation feature flag is enabled

    When user confirms a Money account deposit transaction
    Then the first-time deposit animation screen is shown with parallax and celebratory animation
    And the user can dismiss the screen to return home

  Scenario: user completes a subsequent Money account deposit
    Given the user already has a prior confirmed Money account deposit
    And the first-time deposit animation feature flag is enabled

    When user confirms another Money account deposit transaction
    Then no animation screen is shown
    And the user is not navigated away from the confirmation flow

  Scenario: animation feature flag is disabled
    Given the first-time deposit animation feature flag is disabled

    When user confirms their first Money account deposit transaction
    Then no animation screen is shown
```

## **Screenshots/Recordings**

<!-- mms-check: type=screenshot required=true -->

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

### **Before**

<!-- [screenshots/recordings] -->
N/A - Animation didn't exist
### **After**

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


https://github.com/user-attachments/assets/c230a093-f569-431d-bd61-a02190ef0478


## **Pre-merge author checklist**

<!-- mms-check: type=checklist required=true -->

<!--
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
- [x] 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
- [x] 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.
<!--
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.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.

  type=text           Section must contain non-placeholder prose.
  type=changelog      Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
                      comment but do not block the PR.

Sections without a directive are checked for structural presence only.
-->

## **Description**
Bump `@metamask/money-account-balance-service` to `v2.1.0`. This version
uses the `pending` block tag for balance fetching.
<!-- mms-check: type=text required=true -->

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

<!-- mms-check: type=changelog required=true blocking=true -->

<!--
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: bump @metamask/money-account-balance-service to v2.1.0
to use pending block tag in balance fetches


## **Related issues**

<!-- mms-check: type=issue-link required=true -->

Fixes: [MUSD-1016: Update @metamask/money-account-balance-service to
v2.1.0](https://consensyssoftware.atlassian.net/browse/MUSD-949)

## **Manual testing steps**

<!-- mms-check: type=manual-testing required=true -->

```gherkin
Feature: Money account balance fetching

  Scenario: user can load Money account balance
    Given user have Money account

    When user launches app
    Then user sees Money account balance on Wallet home and Money home screens

Feature: Money account balance update sending to Perps/Predict

  Scenario: user's Money account balance updates after sending to Perps/Predict
    Given user have Money account with non-zero balance

    When user sends funds from Money account to Perps/Predict
    And the transaction confirms
    Then user's Money account balance updates to reflect send
```

## **Screenshots/Recordings**

<!-- mms-check: type=screenshot required=true -->

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

### **Before**

<!-- [screenshots/recordings] -->
N/A - Balance wasn't updating after sending to Perps/Predict
### **After**

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


https://github.com/user-attachments/assets/75787005-e93b-41b1-a35f-2adee340b47a

## **Pre-merge author checklist**

<!-- mms-check: type=checklist required=true -->

<!--
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
- [x] 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
- [x] 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.
<!--
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.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.

  type=text           Section must contain non-placeholder prose.
  type=changelog      Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
                      comment but do not block the PR.

Sections without a directive are checked for structural presence only.
-->

## **Description**

<!-- mms-check: type=text required=true -->

Fixes two QuickBuy UX issues on the trader position sheet:

- Rate tag flip: Pre-quote metadata showed 1 [dest] = X [source] while
the quote pill showed 1 [source] = X [dest], so the tag swapped sides
when a quote landed. Buy-mode pre-quote now uses the same source-first
orientation as the quote-derived rate.
- Amount loading state: Replaced the secondary-line spinner with a
skeleton + token symbol so the fiat headline and token context stay
visible during blocking quote loads. Buy/Sell button spinner behavior is
unchanged.

<img height="790" alt="Simulator Screenshot - iPhone 17 Pro - 2026-06-17
at 15 44 37"
src="https://github.com/user-attachments/assets/93e3af49-edaf-46f1-a0ca-a163b35738da"
/>


https://github.com/user-attachments/assets/9735648c-51b4-495c-9344-0563ad59b15e


## **Changelog**

<!-- mms-check: type=changelog required=true blocking=true -->

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

<!-- mms-check: type=issue-link required=true -->

Fixes:
https://consensyssoftware.atlassian.net/browse/TSA-608
https://consensyssoftware.atlassian.net/browse/TSA-716

## **Manual testing steps**

<!-- mms-check: type=manual-testing required=true -->

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

<!-- mms-check: type=screenshot required=true -->

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

### **Before**

NA

### **After**

NA

## **Pre-merge author checklist**

<!-- mms-check: type=checklist required=true -->

<!--
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.
<!--
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.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.

  type=text           Section must contain non-placeholder prose.
  type=changelog      Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
                      comment but do not block the PR.

Sections without a directive are checked for structural presence only.
-->

## **Description**

<!-- mms-check: type=text required=true -->

Design-polish batch across the Social Leaderboard / Top Traders surfaces
to match the latest Figma.

- Leaderboard rows: new RankMedal medallion badge (gold/silver/bronze
SVG) on the avatar for top-3, replacing the rank column + crown/ring;
subline shows only the signed full PnL.
- Home carousel: compact horizontal cards (155px, full-width small
Follow button).
- Trader profile view also updated to match figma spec
- Position chart: trade markers 10px / 2px stroke.
- Trades list: removed white title underline; rows show action now:
"Bought"/"Sold".

<img height="790" alt="Simulator Screenshot - iPhone 17 Pro - 2026-06-17
at 14 11 42"
src="https://github.com/user-attachments/assets/5a6e3593-8522-44a3-8699-56293ae15786"
/>
<img height="790" alt="Simulator Screenshot - iPhone 17 Pro - 2026-06-17
at 16 24 07"
src="https://github.com/user-attachments/assets/0254e371-55b2-49a8-b361-ff4f72a5bb7c"
/>
<img height="790" alt="Simulator Screenshot - iPhone 17 Pro - 2026-06-17
at 15 08 14"
src="https://github.com/user-attachments/assets/b4680457-83eb-44a9-bb81-ec75abd2c124"
/>
<img height="790" alt="Simulator Screenshot - iPhone 17 Pro - 2026-06-17
at 14 14 39"
src="https://github.com/user-attachments/assets/6d66d5aa-95ac-4d97-b403-52ee36f2fab5"
/>
<img height="790" alt="Simulator Screenshot - iPhone 17 Pro - 2026-06-17
at 15 07 48"
src="https://github.com/user-attachments/assets/26588fbc-2375-49bc-b142-9662c5f335c5"
/>

## **Changelog**

<!-- mms-check: type=changelog required=true blocking=true -->

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

<!-- mms-check: type=issue-link required=true -->

Fixes:
https://consensyssoftware.atlassian.net/browse/TSA-765
https://consensyssoftware.atlassian.net/browse/TSA-468

## **Manual testing steps**

<!-- mms-check: type=manual-testing required=true -->

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

<!-- mms-check: type=screenshot required=true -->

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

### **Before**

NA

### **After**

NA

## **Pre-merge author checklist**

<!-- mms-check: type=checklist required=true -->

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

---------

Co-authored-by: Xavier Brochard <xavier.brochard@consensys.net>
Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description**

This PR standardizes section spacing and structure across the Explore
feed (TrendingView) so all tabs follow a consistent layout pattern.

**Motivation:** Section spacing was previously handled with ad-hoc
margins on individual components (`mb-7`, `mb-9`, `compactSectionTail`,
etc.), which led to inconsistent gaps between sections across tabs and
made it hard to maintain visual rhythm as sections were added or
reordered.

**Solution:**
- Introduced a shared `sectionLayout` pattern on each Explore tab (Now,
Crypto, Dapps, Macro, RWAs, Sports) that computes `showDivider` and
`addSectionTailGap` from the set of visible sections.
- Migrated Explore section headers to MMDS `SectionHeader` and added
MMDS `SectionDivider` between sections.
- Removed per-component bottom/top margin hacks from carousels, pill
lists, card lists, and tile carousels; spacing is now owned by section
wrappers.
- Updated `WhatsHappeningSection` with `hideHeader`, `showDivider`, and
`addSectionTailGap` props so it integrates cleanly into the Explore
layout (including A/B variant ordering on the Now tab).
- Aligned Explore search result section headers with the same MMDS
components.
- Added bottom padding to `ExploreScroll` and replaced `SafeAreaView`
with `Box` in `TrendingView`.

## **Changelog**

CHANGELOG entry: Aligned section spacing and dividers across Explore
tabs for a more consistent layout

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-781

## **Manual testing steps**

```gherkin
Feature: Explore section spacing alignment

  Scenario: Now tab sections use consistent dividers and spacing
    Given the user is on the Wallet tab with Explore visible
    And Perps, Predict, and What's Happening feature flags are enabled
    When the user opens the Explore "Now" tab
    Then sections are separated by dividers (except the first visible section)
    And horizontal sections (carousels, pill lists) have consistent tail spacing before the next section
    And vertical list sections (e.g. Stocks) do not have extra tail gap below the list

  Scenario: Crypto tab section layout
    Given the user opens the Explore "Crypto" tab
    When Trending Tokens, Crypto Perps, and Predictions sections are visible
    Then each section after the first shows a SectionDivider
    And spacing between carousel sections is consistent

  Scenario: Dapps tab section layout
    Given the user opens the Explore "Sites" tab
    When Recents, Favorites, Ecosystems, and Popular sections are visible
    Then dividers appear between sections in the correct order
    And the Ecosystems subtitle still renders under its section header

  Scenario: Explore search results headers
    Given the user opens Explore search and enters a query with results
    When search results render grouped by section
    Then section headers use MMDS SectionHeader styling
    And dividers appear between search result sections (not before the first)

  Scenario: What's Happening on Explore (non-homepage)
    Given What's Happening is enabled on the Now tab
    When the What's Happening carousel renders in Explore
    Then it uses the Explore SectionHeader (not the homepage temp header)
    And divider/spacing props match adjacent sections
```

## **Screenshots/Recordings**

### **Before**


https://github.com/user-attachments/assets/e8494120-87c6-4e4c-b7e0-3577e510b426

### **After**


https://github.com/user-attachments/assets/eb00f187-9330-4e4e-ae7e-dfd31f0525bc

## **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 *(no new tests in this commit —
visual/layout refactor only)*
- [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
- [x] 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
- [x] 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

## **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 layout and styling across Explore tabs and search; no auth,
data, or navigation logic changes beyond visual structure.
> 
> **Overview**
> Standardizes **Explore (TrendingView)** section rhythm by moving
spacing and separators out of individual carousels/lists and into
tab-level section wrappers.
> 
> Each Explore tab now builds a **visible-section list** and uses a
shared `sectionLayout` helper to derive **`showDivider`** (MMDS
`SectionDivider` between sections, not before the first) and
**`addSectionTailGap`** (`pb-3` after horizontal sections only; vertical
`CardList` sections skip extra tail gap). **Per-section margin hacks**
(`mb-7`, `mb-9`, `compactSectionTail`, default `PillScrollList` wrapper
margins, `CardList` bottom margin) are removed from shared components.
> 
> **Section headers** on Explore switch to MMDS `SectionHeader` via
`TrendingView/components/SectionHeader`; **Explore search** headers
follow the same pattern with `isFirstHeader` to control dividers.
**`WhatsHappeningSection`** gains `hideHeader`, `showDivider`, and
`addSectionTailGap` so the Now tab can render the Explore header/divider
layout while keeping the homepage temp header elsewhere.
**`ExploreScroll`** adds bottom padding; **`TrendingView`** drops
`SafeAreaView` for `Box`. Perps tabs hoist **`PerpsSectionProvider`** to
the tab root after splitting content components.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
5a408e5. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
…ll (#31931)

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

On Money Home, every Card-related entry point was navigating to
`Routes.CARD.ROOT` with `animation: 'slide_from_bottom'`, so Card Home
opened with a bottom-to-top modal transition even for cardholders and
linked users. That animation should be reserved for the CardWelcome
educational screen shown to brand-new users in upsell mode.

This change hoists the existing `metamaskCardMode` derivation and reuses
it in `navigateToCardHome`: only when `metamaskCardMode === 'upsell'` do
we pass `animation: 'slide_from_bottom'`. All other modes (`manage`,
`link`, `verifying`) omit the animation param and fall back to the
MainNavigator default (`slide_from_right`). Unit tests cover manage-mode
navigation and guard against regressions to the modal animation.

## **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 Card navigation from Money Home to use a push
animation except when opening the CardWelcome educational screen

## **Related issues**

Fixes: CARD-450

## **Manual testing steps**

```gherkin
Feature: Card navigation animation from Money Home

  Background:
    Given I am logged into MetaMask Mobile
    And I am on the Money Home screen

  Scenario: brand-new user opens Card from upsell Get now
    Given I am not a cardholder
    And the MetaMask Card section is in upsell mode

    When user taps "Get now" on the MetaMask Card section
    Then the CardWelcome screen should slide in from the bottom

  Scenario: linked cardholder opens Card from Manage
    Given I am a cardholder with my card linked to my Money account
    And the MetaMask Card section is in manage mode

    When user taps "Manage" on the MetaMask Card section
    Then Card Home should push in from the right

  Scenario: cardholder opens Card from the action row
    Given I am a cardholder with my card linked to my Money account

    When user taps the Card button in the Money Home action row
    Then Card Home should push in from the right
    And the screen should not slide in from the bottom
```

## **Screenshots/Recordings**

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

### **Before**

N/A — animation change; screen recordings recommended to compare
bottom-to-top vs right-to-left transitions.

### **After**

N/A — screen recordings recommended showing upsell (bottom-to-top) vs
manage/action-row (right-to-left) flows.

## **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
- [x] 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
- [x] I've instrumented key operations with Sentry traces for
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.

<!-- Generated with the help of the pr-description AI skill -->

Co-authored-by: Cursor <cursoragent@cursor.com>
<!--
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.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.

  type=text           Section must contain non-placeholder prose.
  type=changelog      Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
                      comment but do not block the PR.

Sections without a directive are checked for structural presence only.
-->

## **Description**

<!-- mms-check: type=text required=true -->

Adds the TMCU-926 homepage discovery pills A/B/C experiment on the
legacy scroll wallet homepage. Users in `grayIcons` or `colorIcons`
variants see a horizontal pill rail below the growth banner with
Perpetuals, Predictions, Stocks, and Crypto shortcuts. Control users see
no pills.

Implementation includes LaunchDarkly flag wiring
(`homeTMCU926AbtestDiscoveryPills`), `HomepageDiscoveryPills` UI (gray
design-system icons vs color PNG assets), wallet integration (legacy
homepage only; excludes MCU-589 discovery-tabs treatment), navigation to
perps / predict / explore destinations, and Segment instrumentation
(`pill_tapped` Home Viewed plus destination attribution).

## **Changelog**

<!-- mms-check: type=changelog required=true blocking=true -->

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

<!-- mms-check: type=issue-link required=true -->

Fixes:

Refs: https://consensyssoftware.atlassian.net/browse/TMCU-926

## **Manual testing steps**

<!-- mms-check: type=manual-testing required=true -->

```gherkin
Feature: Homepage discovery pills A/B test (TMCU-926)

  Background:
    Given I am logged into MetaMask Mobile on the legacy scroll wallet homepage
    And LaunchDarkly flag homeTMCU926AbtestDiscoveryPills is configured

  Scenario: control variant shows no discovery pills
    Given I am assigned to the control variant

    When I view the wallet home screen below the growth banner
    Then I should not see discovery pills

  Scenario: grayIcons variant shows pills and navigates
    Given I am assigned to the grayIcons variant

    When I tap the Perpetuals pill
    Then I should navigate to the perps home screen

    When I return and tap the Predictions pill
    Then I should navigate to the predict market list

    When I return and tap the Crypto pill
    Then I should navigate to Explore on the Crypto tab

    When I return and tap the Stocks pill
    Then I should navigate to Explore on the RWAs tab

  Scenario: colorIcons variant shows color pill assets
    Given I am assigned to the colorIcons variant

    When I view the discovery pills below the growth banner
    Then each pill should display its color icon asset

  Scenario: discovery pills hidden for discovery-tabs treatment
    Given I am in the MCU-589 hub page discovery tabs treatment

    When I view the wallet home screen
    Then I should not see discovery pills on the legacy homepage layout
```

## **Screenshots/Recordings**

<!-- mms-check: type=screenshot required=true -->

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

### **Before**

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

### **After**

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


https://github.com/user-attachments/assets/6a66727f-47fa-4e47-b535-01b4a4a2e8b6

<img width="300"
src="https://github.com/user-attachments/assets/192369be-ac39-4460-87fe-5a0f4b5f027a"
/>
<img width="300"
src="https://github.com/user-attachments/assets/434f6522-6e84-4161-b88d-6be139831157"
/><img width="300"
src="https://github.com/user-attachments/assets/ee305bc6-5dc6-4d32-846b-cd287b7c0c54"
/>


## **Pre-merge author checklist**

<!-- mms-check: type=checklist required=true -->

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

<!-- Generated with the help of the pr-description AI skill -->
…31888)

## **Description**

This PR fixes the hardware wallet (Ledger/QR) confirmation flow, which
was broken for sends and signature requests originating from a hardware
wallet account.

## **Changelog**

CHANGELOG entry: Fixed a bug that prevented hardware wallet users from
completing sends and signatures

## **Related issues**

Fixes: #31845

## **Manual testing steps**

Feature: Hardware wallet confirmation flow

  Scenario: Ledger account completes a send
    Given the active account is a Ledger hardware wallet account
    And the Ledger device is connected
    And the user is on the send screen with a valid recipient and amount

    When user taps confirm to submit the transaction
    Then the Ledger device prompts to sign for the correct account
    And the transaction is submitted from the selected account

  Scenario: Ledger account signs a message from a dApp
    Given the active account is a Ledger hardware wallet account
    And a dApp has requested a signature

    When user confirms the signature request
    Then the Ledger device prompts to sign for the correct account
    And the signature is completed successfully

Scenario: Confirmation is rejected when no signing address is available
    Given a confirmation request with no resolvable `from` address

    When user attempts to confirm
    Then the confirmation is rejected
    And no hardware wallet operation is attempted

## **Screenshots/Recordings**

<!-- TODO: attach before/after recordings of the Ledger send/sign flow.
Recording the "After" path showing the device signing with the correct
account is the key evidence. -->

### **Before**


### **After**


https://github.com/user-attachments/assets/6bb222b6-a662-4f56-aadd-24ecc60a3df9



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

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

## **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.
Notes on my choices:
- Checklists: I checked only the items I could verify (coding standards
followed, template completed, tests included in the diff, JSDoc on
getDeviceIdForAddress). Left performance/labels unchecked honestly —
those need your confirmation.
- CHANGELOG: rewrote to past-tense user-facing prose per the template's
examples.
- Tests: the commit added/updated useConfirmActions.test.ts,
useLedgerConfirm.test.ts, and useQrConfirm.test.ts, so "tests included"
is legitimately checkable.
…live pricing cp-7.81.2 (#31852)

## **Description**

Extended sports game-details tabs (moneyline, spreads, totals, and
future market types) were not grouping or pricing outcomes reliably
compared to Polymarket.

This PR:

1. **Adds `enabledSportsMarketTypes`** to the
`predictExtendedSportsMarkets` remote flag so outcome grouping respects
an allowlist of supported market types (defaults to moneyline, spreads,
and totals when the field is omitted on an enabled flag).
2. **Fixes spread line ordering** to match Polymarket’s
ascending/descending display based on the first spread’s displayed sign.
3. **Polls REST ask prices** (`entry.sell`) for non-moneyline grouped
outcomes while keeping moneyline on live WebSocket best-ask prices;
polling pauses while the buy sheet is open.
4. **Refactors game-details outcome UI** into `outcomeGrouping.ts`,
`PredictGameOutcomeCards.tsx`, `usePricedOutcomeGroup.ts`, and
`utils.ts`, with unit tests colocated by module.

**Why:** PRED-957 — corners, team totals, and first-half team totals
(and related extended markets) were not showing up or behaving correctly
in game details.

**How:** Filter groupable outcomes at parse time, sort line markets
consistently, price cards through the correct source per market type,
and slim `PredictGameOutcomesTab` to routing + composition only.

## **Changelog**

CHANGELOG entry: Fixed extended sports game-details outcome tabs to
group enabled market types correctly, order spread lines like
Polymarket, and show current buy prices for non-moneyline markets.

## **Related issues**

Fixes: 
- PRED-957
- PRED-958

## **Manual testing steps**

```gherkin
Feature: Extended sports game details outcomes

  Scenario: User views grouped game lines with live prices
    Given extended sports markets are enabled for the game league
    And enabledSportsMarketTypes includes moneyline, spreads, and totals
    When the user opens a live or upcoming game details screen
    And selects the Game Lines chip
    Then moneyline, spreads, and totals subgroups render
    And spread lines appear in the same order as on Polymarket
    And non-moneyline buy button prices reflect REST ask prices
    And moneyline buy button prices reflect live WebSocket best ask

  Scenario: Price polling pauses while buy sheet is open
    Given the user is on a game details spreads or totals card
    When the user opens the buy preview sheet
    Then REST price polling stops until the sheet is dismissed

  Scenario: Enabled market types flag limits grouped tabs
    Given enabledSportsMarketTypes is set to ["moneyline"] only
    When the user opens game details for an extended-league game
    Then only moneyline appears in outcome groups
    And the full outcomes list remains available on the market object
```

**Automated tests run locally:**

```bash
npx jest --runTestsByPath \
  app/components/UI/Predict/components/PredictGameDetailsContent/utils.test.ts \
  app/components/UI/Predict/components/PredictGameDetailsContent/usePricedOutcomeGroup.test.tsx \
  app/components/UI/Predict/components/PredictGameDetailsContent/PredictGameOutcomesTab.test.tsx \
  app/components/UI/Predict/providers/polymarket/outcomeGrouping.test.ts \
  app/components/UI/Predict/providers/polymarket/utils.test.ts \
  app/components/UI/Predict/utils/resolvePredictFeatureFlags.test.ts \
  --coverage=false
```

## **Screenshots/Recordings**

N/A — manual QA pending on device/simulator. Will attach before/after
recordings of game-details Game Lines (spreads order + buy prices)
before marking Ready for review.

### **Before**

<!-- Add recording: spread lines out of order / stale buy prices -->

### **After**

<!-- Add recording: spread lines match Polymarket / REST prices on
spreads & totals -->

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

- [x] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [x] 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
- [x] 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

## **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.
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.

  type=text           Section must contain non-placeholder prose.
  type=changelog      Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
                      comment but do not block the PR.

Sections without a directive are checked for structural presence only.
-->

## **Description**

<!-- mms-check: type=text required=true -->

Removing old ways of calling `keyring_createAccount` via the Snap
keyring.

## **Changelog**

<!-- mms-check: type=changelog required=true blocking=true -->

CHANGELOG entry: null

## **Related issues**

<!-- mms-check: type=issue-link required=true -->

Fixes: N/A

## **Manual testing steps**

<!-- mms-check: type=manual-testing required=true -->

N/A

## **Screenshots/Recordings**

<!-- mms-check: type=screenshot required=true -->

N/A

## **Pre-merge author checklist**

<!-- mms-check: type=checklist required=true -->

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

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

#### 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: Hassan Malik <hbmalik88@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
<!--
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.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.

  type=text           Section must contain non-placeholder prose.
  type=changelog      Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as a warning in the sticky
                      comment but do not block the PR.

Sections without a directive are checked for structural presence only.
-->

## **Description**

<!-- mms-check: type=text required=true -->

Updates the VIP invite and referee splash experiences to use the **Gold
Fox Collective** branding, consolidates duplicated splash UI/copy, and
updates the VIP referee dashboard stats.

**Splash screens**
- Rebranded `splash_title` from "Gold Fox VIP" to "Welcome to Gold Fox
Collective" across all locales
- Removed duplicate `referee_splash_*` translation keys that mirrored
shared `splash_*` strings (kept `referee_splash_continue` since it
differs from `splash_accept_invite`)
- Extracted shared `VipSplashGradientTitle` and `VipSplashScreenLayout`
components
- Removed thin `VipSplashScreen` / `VipRefereeSplashScreen` wrappers;
views now render the shared layout directly

**VIP referee dashboard**
- Replaced the generic **Points** stat with **Points to
{referredByCode}** using `dashboard.points`
- Kept **Swaps volume** and **Perps volume** as separate stat cells (not
combined)
- Updated loading skeleton to match the three-cell layout
- Added `referee_points_to_label` and restored
`referee_swaps_volume_label` / `referee_perps_volume_label` in all
supported locales

**Tests**
- Added unit tests for `VipSplashGradientTitle` and
`VipSplashScreenLayout`
- Extended `RewardsVipRefereeView` coverage for separate volume cells,
points-to label, and missing referral code

## **Changelog**

<!-- mms-check: type=changelog required=true blocking=true -->

CHANGELOG entry: Updated VIP splash screens to say "Welcome to Gold Fox
Collective" and updated the VIP referee dashboard to show swaps volume,
perps volume, and points to referrer.

## **Related issues**

<!-- mms-check: type=issue-link required=true -->

Fixes: https://consensyssoftware.atlassian.net/browse/RWDS-1402

## **Manual testing steps**

<!-- mms-check: type=manual-testing required=true -->

```gherkin
Feature: VIP splash and referee dashboard updates

  Scenario: VIP invite splash shows Gold Fox Collective branding
    Given a user with VIP program enabled and an unaccepted VIP invite
    When the user opens the VIP splash screen
    Then the title reads "Welcome to Gold Fox Collective"
    And the primary CTA reads "Accept invite"

  Scenario: VIP referee splash shows Gold Fox Collective branding
    Given a user flagged as a VIP referee who has not accepted the referee splash
    When the user opens the VIP referee splash screen
    Then the title reads "Welcome to Gold Fox Collective"
    And the primary CTA reads "Continue"
    And the referred-by code is shown when available

  Scenario: VIP referee dashboard shows updated stats
    Given a VIP referee user with dashboard data loaded
    When the user opens the VIP referee dashboard
    Then the stats section shows "Swaps volume" and "Perps volume" separately
    And the stats section shows "Points to {referredByCode}" with dashboard points
```

## **Screenshots/Recordings**

<!-- mms-check: type=screenshot required=true -->

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

### **Before**

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

### **After**

Edit: Screenshots look good, removed. 

## **Pre-merge author checklist**

<!-- mms-check: type=checklist required=true -->

<!--
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
- [x] 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
- [x] 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.
…ar lists (#30997)

## **Description**

### What

`useNetworkEnablement` is consumed in ~22 files (network selectors,
polling setup, token lists, `useCurrentNetworkInfo`, etc.). It returned
a **brand-new object literal on every render**, and its
`popularEvmNetworks` / `popularMultichainNetworks` / `popularNetworks`
members were **fresh arrays each render** (computed inline with a `??
[]` fresh fallback). Any consumer that feeds those into a
`useMemo`/`useEffect`/`useCallback` dependency array re-ran every render
— which is exactly what polling and token-list code does (several
consumers even work around it today with `popularNetworks.join(',')`).

### Changes

- Memoize the three popular-network lists in a single `useMemo`
(returning a tuple), keyed on the controller instance **and**
`selectNetworkConfigurations`, with a stable module-level empty-array
fallback.
- Wrap the returned object in `useMemo` so consumers get a stable
identity.

### Why key on `selectNetworkConfigurations` (not just the controller)

The controller's `listPopularEvmNetworks()` /
`listPopularMultichainNetworks()` / `listPopularNetworks()` filter the
static `POPULAR_NETWORKS` list by **mutable** NetworkController /
MultichainNetworkController config state
(`networkConfigurationsByChainId` /
`multichainNetworkConfigurationsByChainId`). The controller instance
reference never changes, so memoizing on it alone would serve a
**stale** list when the user adds/removes a network.
`selectNetworkConfigurations` is a `createDeepEqualSelector` that merges
both EVM and non-EVM configs, so it changes only when the configs
actually change — keeping the lists fresh on config changes while stable
between them. (An `eslint-disable react-hooks/exhaustive-deps` is used
with a comment because the dependency is read internally by the
controller methods and isn't syntactically visible to the linter.)

**Behavior is unchanged** (same values; lists still reflect current
configs).

### Risk

Low — memoization + a more-correct dependency key; no output changes.
From the internal performance audit (`unstable-hook`, `fix_risk:
Simple`, `test_safety_net: Covered`). Note: review flagged (and this PR
fixes) that the naive "memoize on the controller instance" approach
would have introduced stale data — hence the config-selector key.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: #31381

## **Manual testing steps**

> **Validation status:** behavior-preserving refactor validated by the
unit test(s) below; not yet manually profiled on Android / a power-user
device, and no new Sentry traces added — the underlying audit finding is
still `status: UNVALIDATED`. The Performance-checks boxes are
intentionally left **unchecked** until that profiling is done.

## **Screenshots/Recordings**

N/A — internal performance refactor; no user-facing UI change.

### **Before**

N/A

### **After**

N/A

## **Pre-merge author checklist**

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

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

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Performance-only memoization with unchanged outputs; config selector
dependency avoids stale popular-network lists.
> 
> **Overview**
> **`useNetworkEnablement`** now returns a **stable object** and stable
**`popularEvmNetworks` / `popularMultichainNetworks` /
`popularNetworks`** references across re-renders when inputs are
unchanged, instead of new literals and `?? []` arrays every time.
> 
> Popular lists are built in one **`useMemo`**, keyed on the enablement
controller and **`selectNetworkConfigurations`** (deep-equal), so lists
stay correct when networks are added or removed—not only when the
controller reference changes. Empty lists share a module-level
**`EMPTY_ARRAY`** fallback for constant identity.
> 
> Tests add **referential stability** coverage (`===` on the hook result
and `popularNetworks` after `rerender`). This should reduce unnecessary
**`useMemo`/`useEffect`** churn in many consumers (polling, token lists,
balance UI) that today depend on those values or work around unstable
arrays.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
4c7c7fc. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Vince Howard <vincenguyenhoward@gmail.com>
<!--
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.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.

  type=text           Section must contain non-placeholder prose.
  type=changelog      Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
                      comment but do not block the PR.

Sections without a directive are checked for structural presence only.
-->

## **Description**

<!-- mms-check: type=text required=true -->

<!--
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?
-->

Remove more dead code around Snap keyring clients this time.

## **Changelog**

<!-- mms-check: type=changelog required=true blocking=true -->

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

<!-- mms-check: type=issue-link required=true -->

Fixes: N/A

## **Manual testing steps**

<!-- mms-check: type=manual-testing required=true -->

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

<!-- mms-check: type=screenshot required=true -->

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

<!-- mms-check: type=checklist required=true -->

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

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

#### 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.
…31942)

## **Description**

The bridge Redux slice had a local copy of `hasMinimumRequiredVersion`
that duplicated the canonical implementation in
`app/util/remoteFeatureFlag`. This PR removes the bridge-specific helper
and updates the slice to import the shared utility instead.

**Reason for change:** Avoid maintaining two equivalent version-check
implementations that can drift over time.

**Improvement:** Bridge feature-flag version gating now uses the same
helper as the rest of the app (feature flag selectors, rewards, etc.),
with existing coverage retained in
`app/util/remoteFeatureFlag/index.test.ts`. Bridge-related test mocks
were updated to target the shared module path.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:
[MCWP-665](https://consensyssoftware.atlassian.net/browse/MCWP-665)

## **Manual testing steps**

N/A — internal refactor with no user-facing behavior change. Verified
via unit tests:

- `yarn jest app/util/remoteFeatureFlag/index.test.ts`
- `yarn jest app/core/redux/slices/bridge/selectNoFeeAssets.test.ts`

## **Screenshots/Recordings**

N/A — no UI changes.

### **Before**

N/A

### **After**

N/A

## **Pre-merge author checklist**

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

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

Made with [Cursor](https://cursor.com)

[MCWP-665]:
https://consensyssoftware.atlassian.net/browse/MCWP-665?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

Co-authored-by: Cursor <cursoragent@cursor.com>
…ive markets cp-7.81.2 (#31922)

## **Description**

This PR updates Predict sport game market cards so Moneyline odds can
update from live WebSocket market prices.

The main sport market card now subscribes to live prices for the visible
Moneyline tokens and displays live `bestAsk` values when available,
falling back to static token prices when live data is missing or
disabled. The featured carousel sport card uses the same live-price
fallback for payout rows and buy button odds.

The live sport-card price behavior is controlled by a default-on remote
feature flag, `predictSportCardLivePrices`, so the WebSocket
subscriptions can be disabled remotely while preserving the existing
static price display. Diagnostic console logs were also added around
live market price subscribe/unsubscribe events to make subscription
behavior visible during validation.

## **Changelog**

CHANGELOG entry: Updated Predict sport game market cards to show live
Moneyline prices.

## **Related issues**

Fixes: PRED-958 / PRED-1028

## **Manual testing steps**

```gherkin
Feature: Predict sport game card live prices

  Scenario: sport game cards show live Moneyline odds
    Given Predict sport game markets are visible on the feed or featured carousel
    And the predictSportCardLivePrices remote feature flag is enabled or missing

    When live market price WebSocket updates are received for the visible Moneyline tokens
    Then the sport game card odds update from the live best ask price
    And the card falls back to the static token price when live prices are unavailable

  Scenario: live sport card prices are disabled remotely
    Given the predictSportCardLivePrices remote feature flag is disabled

    When Predict sport game cards render
    Then the cards do not enable live market price subscriptions
    And the cards continue showing static token prices
```

Focused automated tests run:

```bash
npx jest --runTestsByPath app/components/UI/Predict/utils/resolvePredictFeatureFlags.test.ts --coverage=false
npx jest --runTestsByPath app/components/UI/Predict/selectors/featureFlags/index.test.ts --coverage=false
npx jest --runTestsByPath app/components/UI/Predict/components/PredictMarketSportCard/PredictMarketSportCard.test.tsx --coverage=false
npx jest --runTestsByPath app/components/UI/Predict/components/FeaturedCarousel/FeaturedCarouselSportCard.test.tsx --coverage=false
```

## **Screenshots/Recordings**

N/A - this change updates live odds data plumbing and feature flag
behavior. Visual output is covered by component tests for the rendered
odds text.

### **Before**

N/A

### **After**

N/A

## **Pre-merge author checklist**

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

#### Performance checks (if applicable)

- [x] N/A - targeted Predict card price display and feature flag gating
change; Android-specific performance validation was not required.
- [x] N/A - no expected impact on power-user account/token scenarios.
- [x] N/A - no new production performance trace was needed for this UI
price-display change.

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

Extended sports game-details tabs (moneyline, spreads, totals, and
future market types) were not grouping or pricing outcomes reliably
compared to Polymarket.

This PR:

1. **Adds `enabledSportsMarketTypes`** to the
`predictExtendedSportsMarkets` remote flag so outcome grouping respects
an allowlist of supported market types (defaults to moneyline, spreads,
and totals when the field is omitted on an enabled flag).
2. **Fixes spread line ordering** to match Polymarket’s
ascending/descending display based on the first spread’s displayed sign.
3. **Polls REST ask prices** (`entry.sell`) for non-moneyline grouped
outcomes while keeping moneyline on live WebSocket best-ask prices;
polling pauses while the buy sheet is open.
4. **Refactors game-details outcome UI** into `outcomeGrouping.ts`,
`PredictGameOutcomeCards.tsx`, `usePricedOutcomeGroup.ts`, and
`utils.ts`, with unit tests colocated by module.

**Why:** PRED-957 — corners, team totals, and first-half team totals
(and related extended markets) were not showing up or behaving correctly
in game details.

**How:** Filter groupable outcomes at parse time, sort line markets
consistently, price cards through the correct source per market type,
and slim `PredictGameOutcomesTab` to routing + composition only.

## **Changelog**

CHANGELOG entry: Fixed extended sports game-details outcome tabs to
group enabled market types correctly, order spread lines like
Polymarket, and show current buy prices for non-moneyline markets.

## **Related issues**

Fixes: PRED-957

## **Manual testing steps**

```gherkin
Feature: Extended sports game details outcomes

  Scenario: User views grouped game lines with live prices
    Given extended sports markets are enabled for the game league
    And enabledSportsMarketTypes includes moneyline, spreads, and totals
    When the user opens a live or upcoming game details screen
    And selects the Game Lines chip
    Then moneyline, spreads, and totals subgroups render
    And spread lines appear in the same order as on Polymarket
    And non-moneyline buy button prices reflect REST ask prices
    And moneyline buy button prices reflect live WebSocket best ask

  Scenario: Price polling pauses while buy sheet is open
    Given the user is on a game details spreads or totals card
    When the user opens the buy preview sheet
    Then REST price polling stops until the sheet is dismissed

  Scenario: Enabled market types flag limits grouped tabs
    Given enabledSportsMarketTypes is set to ["moneyline"] only
    When the user opens game details for an extended-league game
    Then only moneyline appears in outcome groups
    And the full outcomes list remains available on the market object
```

**Automated tests run locally:**

```bash
npx jest --runTestsByPath \
  app/components/UI/Predict/components/PredictGameDetailsContent/utils.test.ts \
  app/components/UI/Predict/components/PredictGameDetailsContent/usePricedOutcomeGroup.test.tsx \
  app/components/UI/Predict/components/PredictGameDetailsContent/PredictGameOutcomesTab.test.tsx \
  app/components/UI/Predict/providers/polymarket/outcomeGrouping.test.ts \
  app/components/UI/Predict/providers/polymarket/utils.test.ts \
  app/components/UI/Predict/utils/resolvePredictFeatureFlags.test.ts \
  --coverage=false
```

## **Screenshots/Recordings**

N/A — manual QA pending on device/simulator. Will attach before/after
recordings of game-details Game Lines (spreads order + buy prices)
before marking Ready for review.

### **Before**

<!-- Add recording: spread lines out of order / stale buy prices -->

### **After**

<!-- Add recording: spread lines match Polymarket / REST prices on
spreads & totals -->

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

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

## **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.
…ions (#31938)

## **Description**

<!-- mms-check: type=text required=true -->

<!--
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?
-->

Cashback redemption is moving to Money Accounts as the primary
destination for users outside restricted regions. Previously, every user
without an approved Linea funding source was prompted to set up Linea
USDC delegation — even when Money Account was the correct redemption
path.

This PR updates the Cashback screen to branch setup and withdrawal
gating by region and feature flag:

- **Supported regions** (Money Account FF enabled and user not
residency-blocked): withdrawal requires a delegated Money Account. Users
without one see a new Money Account warning and are redirected to the
Money Account link flow via `startLinkFlow`, returning to Cashback after
setup.
- **UK / restricted regions or FF off**: both Linea and Money Account
delegations are valid redemption destinations (backend resolves the
landing wallet by spending priority). The gate accepts either funding
source so UK users with only Monad/Money Account delegation are no
longer shown a false Linea warning. The existing Linea USDC Spending
Limit redirect is preserved when neither destination is configured.

Also includes a small fix to `truncateAddress` so Solana base58
addresses are truncated directly instead of falling through the EVM
checksum path.

## **Changelog**

<!-- mms-check: type=changelog required=true blocking=true -->

<!--
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 cashback redemption setup to redirect
supported-region users to Money Account delegation instead of Linea USDC

## **Related issues**

<!-- mms-check: type=issue-link required=true -->

Fixes: CARD-417

## **Manual testing steps**

<!-- mms-check: type=manual-testing required=true -->

```gherkin
Feature: Cashback redemption destination routing

  Background:
    Given I am a verified MetaMask Card holder with available mUSD back balance
    And I am on the Card Cashback screen

  Scenario: supported-region user without Money Account sees Money Account setup prompt
    Given the Money Account feature flag is enabled
    And my card residency is outside a blocked region (e.g. US)
    And I do not have a Money Account delegated for card spending

    When I open the Cashback screen
    Then I should see a "Set up Money Account" warning banner
    And the Withdraw button should be disabled

    When I tap "Set up Money Account"
    Then the Money Account link flow should open
    And after completing setup I should return to the Cashback screen

  Scenario: supported-region user with Money Account delegated can withdraw
    Given the Money Account feature flag is enabled
    And my card residency is outside a blocked region
    And I have a Money Account delegated for card spending

    When I open the Cashback screen
    Then I should not see a funding setup warning
    And the Withdraw button should be enabled

  Scenario: UK user with only Linea funding can withdraw
    Given my card residency is in the UK (blocked region)
    And I have approved Linea USDC funding
    And I do not have a Money Account delegated

    When I open the Cashback screen
    Then I should not see a funding setup warning
    And the Withdraw button should be enabled

  Scenario: UK user with only Money Account delegated can withdraw
    Given my card residency is in the UK (blocked region)
    And I do not have approved Linea funding
    And I have a Money Account delegated for card spending

    When I open the Cashback screen
    Then I should not see a Linea funding warning
    And the Withdraw button should be enabled

  Scenario: UK user with neither destination sees Linea setup prompt
    Given my card residency is in the UK (blocked region)
    And I do not have approved Linea funding
    And I do not have a Money Account delegated

    When I open the Cashback screen
    Then I should see a "Set up Linea funding" warning banner

    When I tap "Set up funding"
    Then I should be navigated to Spending Limit with Linea USDC pre-selected

  Scenario: Money Account FF off uses UK-style Linea or Monad gate
    Given the Money Account feature flag is disabled
    And I have a Money Account delegated but no Linea funding

    When I open the Cashback screen
    Then I should not see a funding setup warning
    And the Withdraw button should be enabled
```

## **Screenshots/Recordings**

<!-- mms-check: type=screenshot required=true -->

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

### **Before**

N/A

### **After**

N/A

## **Pre-merge author checklist**

<!-- mms-check: type=checklist required=true -->

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

<!-- Generated with the help of the pr-description AI skill -->

---------

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

Adds a scheduled GitHub Actions workflow that aggregates Playwright JSON
artifacts from Appium smoke runs on `main` (`ci.yml`) and posts
infra/flaky/watch test summaries to Slack via the
`playwright-test-health-report` action
([github-tools](https://github.com/MetaMask/github-tools/tree/main/.github/actions/playwright-test-health-report),
merged in [#262](MetaMask/github-tools#262)).

Pinned to `MetaMask/github-tools@4a2ddd75`. Runs weekdays at 10:00 and
15:00 UTC, with `workflow_dispatch` and a configurable lookback window.
Uses `SLACK_WEBHOOK_PLAYWRIGHT_HEALTH_REPORT`.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Refs: Appium CI health reporting follow-up to #31730 / #31756

## **Manual testing steps**

```gherkin
Feature: Playwright Appium test health report

  Scenario: PR trigger posts report to Slack
    Given SLACK_WEBHOOK_PLAYWRIGHT_HEALTH_REPORT_TEST was configured in repo secrets
    And this PR was open against main with a temporary pull_request trigger
    When the pull_request workflow ran on playwright-test-health-report.yml changes
    Then a Playwright Test Health Report (Mobile Appium) message appeared in Slack (see screenshot)

  Scenario: Scheduled report after merge to main
    Given the workflow exists on main with SLACK_WEBHOOK_PLAYWRIGHT_HEALTH_REPORT configured
    When the weekday schedule runs or an engineer triggers workflow_dispatch with lookback_days=1
    Then the report is generated from main ci.yml Playwright JSON artifacts
```

## **Screenshots/Recordings**

### **Before**

N/A — new workflow only.

### **After**

Slack report from PR test run (1-day lookback on `main` Appium smoke):

![Playwright Test Health Report Slack
message](https://raw.githubusercontent.com/MetaMask/metamask-mobile/ci/playwright-test-health-report/.github/assets/playwright-test-health-report-slack.png)

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

- [x] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [x] 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
- [x] 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

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

Made with [Cursor](https://cursor.com)

---------

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

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

Adds a new memoized selector, `selectShouldShowMoneyEducation`, that
gates the Money account education/warning screen. It returns `true` only
when the user is in the US **and** is not authenticated with the card
service **and** is not a cardholder.

To support it, this PR also adds `selectIsUserInUS`, which derives US
residency from the detected geolocation (`getDetectedGeolocation`). It
handles both `US` and `US-CA` (country-region) formats, is
case-insensitive, and defaults to `false` when geolocation is unknown or
still loading — consistent with the existing
`selectIsMoneyAccountGeoEligible` pattern in this file.

The "authenticated" and "cardholder" signals reuse the existing
`selectIsCardAuthenticated` and `selectIsCardholder` selectors from
`app/selectors/cardController`.

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

CHANGELOG entry: null

## **Related issues**

<!-- mms-check: type=issue-link required=true -->

Fixes: null

## **Manual testing steps**

<!-- mms-check: type=manual-testing required=true -->

N/A — selector-only change covered by unit tests
(`eligibility.test.ts`). The selector is not yet wired into a UI
surface, so there is no user-facing flow to exercise manually.

## **Screenshots/Recordings**

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

### **Before**

N/A

### **After**

N/A

## **Pre-merge author checklist**

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

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

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

<!-- Generated with the help of the pr-description AI skill -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
)

<!--
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.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.

  type=text           Section must contain non-placeholder prose.
  type=changelog      Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
                      comment but do not block the PR.

Sections without a directive are checked for structural presence only.
-->

## **Description**

<!-- mms-check: type=text required=true -->

<!--
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?
-->

Users with access to the Money account tab no longer need a separate
Card entry point in the wallet header. This PR removes that redundant
discovery path when the Money account is both feature-flag enabled and
geo-eligible, while keeping the Card button visible in regions where
Money is unavailable so users can still discover MetaMask Card.

Changes:

- **Wallet header**: Hide the `CardButton` when `isMoneyAccountVisible`
(Money account flag on and geo-eligible), matching the same inline
pattern used by `MainNavigator` and the wallet `MoneyBalanceCard`.
- **Money Home**: Gate `MoneyMetaMaskCard` upsell and verifying modes on
Money account visibility via `deriveMoneyMetaMaskCardMode`; link/manage
modes continue to use existing linkage requirements.
- **Card ↔ Money linkage**: `useMoneyAccountCardLinkage` now requires
Money account flag **and** geo eligibility before reporting base
requirements / `canLink`. Card residency blocking reads
`selectMoneyAccountGeoBlockedCountries` instead of the legacy Earn mUSD
conversion geo list.

Unit and component-view tests cover wallet header visibility, Money Home
card section gating, linkage hook flag/geo behavior, and updated
residency selector fixtures.

## **Changelog**

<!-- mms-check: type=changelog required=true blocking=true -->

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

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

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

CHANGELOG entry: Removed the wallet header Card button for users who
have the Money account tab available

## **Related issues**

<!-- mms-check: type=issue-link required=true -->

Fixes: CARD-410

## **Manual testing steps**

<!-- mms-check: type=manual-testing required=true -->

```gherkin
Feature: Card entry point gating when Money account is visible

  Background:
    Given I am logged into MetaMask Mobile
    And I have a wallet with at least one account

  Scenario: wallet header Card button is hidden when Money account is available
    Given the Money account feature flag is enabled
    And my detected geolocation is eligible for Money account (e.g. US, not in blocked regions)

    When I open the Wallet home screen
    Then I should see the Money tab in the bottom navigation
    And I should not see the Card icon in the wallet header

  Scenario: wallet header Card button remains when Money account is geo-ineligible
    Given the Money account feature flag is enabled
    And my detected geolocation is in a blocked region (e.g. GB when GB is blocked)

    When I open the Wallet home screen
    Then I should not see the Money tab in the bottom navigation
    And I should see the Card icon in the wallet header

  Scenario: wallet header Card button remains when Money account flag is off
    Given the Money account feature flag is disabled

    When I open the Wallet home screen
    Then I should not see the Money tab in the bottom navigation
    And I should see the Card icon in the wallet header

  Scenario: Money Home hides card upsell when Money account is not visible
    Given the Money account feature flag is enabled
    And my detected geolocation is in a blocked region
    And I navigate to Money Home via deeplink or internal route

    When the Money Home screen loads
    Then I should not see the MetaMask Card upsell section

  Scenario: Money Home shows card upsell when Money account is visible
    Given the Money account feature flag is enabled
    And my detected geolocation is eligible
    And I am not a cardholder

    When I open the Money tab
    Then I should see the MetaMask Card upsell section on Money Home

  Scenario: Card Home link CTA respects Money account visibility
    Given the Money account feature flag is enabled
    And my detected geolocation is eligible
    And I have a MetaMask Card that is not linked to my Money account

    When I open Card Home
    Then I should see the link Money account CTA

    When the Money account feature flag is disabled or geolocation is blocked
    Then the link Money account CTA should not appear on Card Home
```

## **Screenshots/Recordings**

<!-- mms-check: type=screenshot required=true -->

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

### **Before**

N/A

### **After**

N/A

## **Pre-merge author checklist**

<!-- mms-check: type=checklist required=true -->

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

<!-- Generated with the help of the pr-description AI skill -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
<!--
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.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.

  type=text           Section must contain non-placeholder prose.
  type=changelog      Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
                      comment but do not block the PR.

Sections without a directive are checked for structural presence only.
-->

## **Description**

<!-- mms-check: type=text required=true -->

Fixes Predict the Pitch campaign stats navigation and aligns the stats
page with the campaign details summary.

1. **Navigation fix:** Register `RewardsPredictThePitchCampaignStats` in
`RewardsNavigator` so tapping through from campaign details no longer
throws an unhandled `NAVIGATE` action.
2. **Stats page parity:** Add a **Markets traded** cell to
`PredictThePitchCampaignStatsView` on the same row as **Total volume**,
using the same display rules as `PredictThePitchStatsSummary` (`x/y`
below minimum, count only when met).

## **Changelog**

<!-- mms-check: type=changelog required=true blocking=true -->

<!--
If this PR is not End-User-Facing and should not be labeled with
`no-changelog`,
write a short User-Facing description in the past tense.
-->

CHANGELOG entry: Fixed Predict the Pitch campaign stats navigation and
added markets traded to the stats performance section.

## **Related issues**

<!-- mms-check: type=issue-link required=true -->

Refs: Predict the Pitch campaign stats navigation error

## **Manual testing steps**

<!-- mms-check: type=manual-testing required=true -->

```gherkin
Feature: Predict the Pitch campaign stats

  Scenario: user opens campaign stats from details
    Given the user is opted into an active Predict the Pitch campaign
    And the user is on the campaign details screen

    When the user navigates to campaign stats
    Then the stats screen opens without a navigation error
    And performance shows ROI, PnL, total volume, and markets traded on one row

  Scenario: markets traded display below minimum
    Given the user's leaderboard position has marketsTraded below minimumMarketsTraded

    When the user views campaign stats
    Then markets traded is shown as "x/y"

  Scenario: markets traded display at or above minimum
    Given the user's leaderboard position meets the minimum markets traded requirement

    When the user views campaign stats
    Then markets traded shows the count only
```

## **Screenshots/Recordings**

<!-- mms-check: type=screenshot required=true -->

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

### **Before**

Navigation to stats failed with: `The action 'NAVIGATE' with payload
{"name":"RewardsPredictThePitchCampaignStats",...} was not handled by
any navigator.`

### **After**
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-06-17 at 17 04 08"
src="https://github.com/user-attachments/assets/41f6cdc0-bf34-4dda-97ce-b5440f33c24b"
/>

Stats screen loads successfully and shows markets traded beside total
volume.

N/A — screenshots not attached in this update.

## **Pre-merge author checklist**

<!-- mms-check: type=checklist required=true -->

<!--
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
- [x] 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
- [x] 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.
@pull pull Bot locked and limited conversation to collaborators Jun 18, 2026
@pull pull Bot added the ⤵️ pull label Jun 18, 2026
@pull
pull Bot merged commit 8db338a into Reality2byte:main Jun 18, 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.