Skip to content

[pull] main from MetaMask:main#590

Merged
pull[bot] merged 32 commits intoReality2byte:mainfrom
MetaMask:main
Mar 10, 2026
Merged

[pull] main from MetaMask:main#590
pull[bot] merged 32 commits intoReality2byte:mainfrom
MetaMask:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Mar 10, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

wachunei and others added 30 commits March 10, 2026 07:30
## **Description**

Remove the vertical bottom-of-page fade overlay and the horizontal
carousel fades from the homepage, as they are no longer part of the
design.

Changes:
- **Wallet view**: Removed `LinearGradient` bottom fade overlay,
`computeFadeOpacity` function, `bottomFadeOpacity` state, scroll
measurement refs, and associated styles
- **PerpsSection**: Replaced `FadingScrollContainer` render-prop wrapper
with a plain `ScrollView`
- **PredictionsSection**: Replaced `FadingScrollContainer` render-prop
wrapper with a plain `ScrollView`
- **FadingScrollContainer**: Deleted component, tests, and barrel export
- Cleaned up unused imports (`LinearGradient`, `colorWithOpacity`,
`NativeSyntheticEvent`, `NativeScrollEvent`)

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Refs:
[TMCU-544](https://consensyssoftware.atlassian.net/browse/TMCU-544)

## **Manual testing steps**

```gherkin
Feature: Homepage fade removal

  Scenario: user scrolls to the bottom of the homepage
    Given the user is on the Homepage with sections enabled

    When user scrolls to the bottom of the page
    Then no gradient fade overlay appears at the bottom

  Scenario: user scrolls the Perps carousel
    Given the user is on the Homepage with Perps section visible

    When user scrolls the Perps trending markets carousel horizontally
    Then no fade gradient appears on the right edge of the carousel

  Scenario: user scrolls the Predictions carousel
    Given the user is on the Homepage with Predictions section visible

    When user scrolls the prediction markets carousel horizontally
    Then no fade gradient appears on the right edge of the carousel
```

## **Screenshots/Recordings**

### Before 


https://github.com/user-attachments/assets/a5784997-e777-4293-93be-e950d0846699

### After 



https://github.com/user-attachments/assets/4934a682-a36e-4ac5-be33-79a064aaa12a


## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk refactor that removes purely visual fade overlays and related
scroll/gradient plumbing; primary risk is minor UI regression in
carousel/scroll behavior on the homepage.
> 
> **Overview**
> Removes the homepage’s horizontal carousel fade treatment and the
wallet’s bottom-of-page fade overlay, aligning the UI with updated
designs.
> 
> This deletes the `FadingScrollContainer` component (and its
tests/exports), swaps `PerpsSection` and `PredictionsSection` carousels
to plain `ScrollView`s, and simplifies `Wallet` scroll handling by
dropping `LinearGradient`/fade-opacity state and related scroll
measurement callbacks.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
aeaa6be. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Replace `PerpsPositionCard` (compact position variant with TP/SL and
ROE) with the simpler `PerpsCard` component for rendering position rows
in the homepage Perps section, matching the pre-homepage-sections tab UI
behavior.

Changes:
- Replace `PositionCardItem` (memoized `PerpsPositionCard` wrapper) with
`PerpsCard` for position rows
- Remove `positionDisplayKey` helper function (only needed for the
custom memo comparator)
- Remove TP/SL loading state logic (`anyPositionHasTpSl`, `tpSlSettled`,
`tpSlReady`) which was only relevant for `PerpsPositionCard`'s compact
position variant
- Update `PerpsCard` mock in tests to handle both `position` and `order`
props
- Remove `positionDisplayKey` unit tests and TP/SL-specific tests

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Refs:
[TMCU-523](https://consensyssoftware.atlassian.net/browse/TMCU-523)

## **Manual testing steps**

```gherkin
Feature: Perps position row on homepage

  Scenario: user views open perps positions on the homepage
    Given the user has open perps positions
    And the homepage Perps section is visible

    When user views the position rows
    Then the rows display the old/simple PerpsCard format (icon, symbol/leverage + size, value + PnL)
    And the rows do not show TP/SL info or ROE

  Scenario: user taps a position row
    Given the user has open perps positions on the homepage

    When user taps a position row
    Then the app navigates to the market details for that position
```

## **Screenshots/Recordings**

### **Before**


<img width="300" alt="perps_row_before"
src="https://github.com/user-attachments/assets/3538094a-8d96-4f57-ad8e-58f424b2ed7e"
/>


### **After**

<img width="300" alt="perps_row_after"
src="https://github.com/user-attachments/assets/e4aa46d7-a6be-45e6-80ac-6204ff247246"
/>

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk UI refactor in the homepage Perps section that changes which
component renders position rows and removes TP/SL-related loading
behavior; main risk is minor display/regression or performance
differences during live updates.
> 
> **Overview**
> **Homepage Perps position rows are reverted to the simpler `PerpsCard`
UI.** The section no longer uses the memoized `PerpsPositionCard`
wrapper (and its `positionDisplayKey` comparator), so position rows stop
showing TP/SL/ROE-specific behavior and related loading states.
> 
> Tests were updated to match the new rendering: the `PerpsCard` mock
now supports both `position` and `order` rows with `onPress`, and
TP/SL/key-stability assertions were removed/rewritten to validate the
simpler position-row output and leverage display.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
811fabe. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…#27109)

## **Description**

This PR adds comprehensive event tracking for MM Pay token metrics in
the Perps trading flow. The changes include:

1. **MM Pay Token Metrics Enhancement**: When users trade using their
Perps balance (instead of paying with a token), the
`mm_pay_token_selected` property now includes the value `'Perps
Balance'` in trade transaction events. This provides complete visibility
into payment method selection, whether users pay with tokens or use
their Perps balance.

2. **Cancel Trade with Token Event Tracking**: Added event tracking for
the cancel trade with token flow:
- `PERPS_UI_INTERACTION` event with `interaction_type:
'cancel_trade_with_token'` when the user cancels a trade
- `PERPS_SCREEN_VIEWED` event with `screen_type:
'cancel_trade_with_token_toast'` when the "taking longer" toast is
displayed

These metrics enable better analytics on user behavior, payment method
preferences, and cancellation patterns in the Perps trading experience.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TAT-2616

## **Manual testing steps**

```gherkin
Feature: MM Pay token metrics and cancel trade tracking

  Scenario: user trades with Perps balance
    Given user has a Perps account with available balance
    When user places a trade order using Perps balance (not paying with a token)
    Then the PERPS_TRADE_TRANSACTION event should include mm_pay_token_selected: "Perps Balance"

  Scenario: user cancels trade with token during deposit
    Given user has initiated a trade order with token payment
    And the deposit is taking longer than expected
    When the "taking longer" toast appears
    Then the PERPS_SCREEN_VIEWED event should be tracked with screen_type: "cancel_trade_with_token_toast"
    And when user taps the cancel button
    Then the PERPS_UI_INTERACTION event should be tracked with interaction_type: "cancel_trade_with_token"
```

## **Screenshots/Recordings**

### **Before**

N/A (analytics/metrics changes, no UI changes)

### **After**

N/A (analytics/metrics changes, no UI changes)

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: changes are limited to MetaMetrics analytics
properties/events and associated constants/tests, with no changes to
order execution behavior beyond emitting additional tracking calls.
> 
> **Overview**
> Adds new Perps MetaMetrics tracking for the deposit+order cancellation
flow: emits `PERPS_SCREEN_VIEWED` when the "deposit taking longer"
cancel toast is shown and `PERPS_UI_INTERACTION` when the user taps
cancel.
> 
> Extends `PERPS_TRADE_TRANSACTION` analytics so when `trackingData` is
present but `tradeWithToken` is false, `mm_pay_token_selected` is
explicitly reported as `"Perps Balance"` (applied in both
`usePerpsOrderExecution` and `TradingService`). Updates Perps event
constants, tests, and the Perps metametrics reference docs accordingly.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
9a82c62. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…trigger (#26888)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

This PR ensures that the `source` property on Perps analytics events
(e.g. `PERPS_SCREEN_VIEWED`, `PERPS_UI_INTERACTION`) accurately reflects
how the user entered the screen or triggered the action, instead of
defaulting or auto-detecting incorrectly.

**Reason for the change:** Analytics were not consistently capturing the
entry point (e.g. which button or screen led the user to the order
screen, tutorial, or other Perps flows). This made it harder to
attribute behavior to specific entry points.

**Improvement/solution:** Each Perps view/screen now passes an explicit
`source` when tracking screen views or when navigating (e.g. to Order
view or Tutorial). Callers pass `source` via route params where
applicable; `PerpsOrderView` and `PerpsTutorialCarousel` use route
params first, then fall back to session/context (e.g. trending), then to
a sensible default. New source constants (e.g.
`CANCEL_ALL_ORDERS_BUTTON`) and navigation types were added where
needed.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TAT-2370

## **Manual testing steps**

```gherkin
Feature: Perps analytics source attribution

  Scenario: user opens Perps flows from different entry points
    Given the app is on main wallet screen with Perps available

    When user opens Perps from homescreen tab, then navigates to Order Book and taps Long
    Then PERPS_SCREEN_VIEWED / order screen events include source matching the entry (e.g. order_book_long_button)

    When user opens Close All Positions view from the positions list
    Then PERPS_SCREEN_VIEWED for Close All Positions includes source close_all_positions_button

    When user opens Tutorial from a deeplink or GTM modal with source in params
    Then tutorial viewed/interaction events use the passed source (e.g. from route params)
```

## **Screenshots/Recordings**

N/A (analytics/tracking only; no UI changes).

### **Before**

N/A

### **After**

N/A

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Primarily analytics attribution changes that add/propagate a `source`
param through navigation and `PERPS_SCREEN_VIEWED` tracking, with
minimal impact on trading logic. Risk is limited to potential
mis-tagging or missing optional route params affecting analytics
completeness.
> 
> **Overview**
> **Perps analytics attribution is tightened** by adding explicit
`PERPS_EVENT_PROPERTY.SOURCE` values to multiple `PERPS_SCREEN_VIEWED`
events (e.g., close/cancel-all flows, order book, withdraw, connection
error, leverage modal, TP/SL).
> 
> **Navigation now carries `source` into downstream screens**:
`navigateToOrder` calls from market details, order book, and position
modify actions pass a caller-specific `source`; `PerpsOrderView` prefers
`route.params.source` (fallback to trending, then a default); and the
token-details redirect includes `source` when replacing into
confirmations. The Perps tutorial screen similarly reads `source` from
route params and uses it for viewed/started/completed tracking.
> 
> Type and test updates accompany this, including new `source` fields in
`PerpsNavigationParamList` and a new `CANCEL_ALL_ORDERS_BUTTON` source
constant.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
ba22dc5. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Use LD flags to consume price impact threshold.

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

## **Changelog**

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

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

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

CHANGELOG entry: use LD flags to consume price impact threshold

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/SWAPS-4214
 
## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Updates swap/bridge price-impact warning and blocking logic to use
feature-flag thresholds and raw quote values; misconfiguration or
parsing differences could change when users see warnings or get routed
to the price impact modal.
> 
> **Overview**
> **Price impact thresholds are now consumed from remote feature flags**
(with fallback to `AppConstants`) for both *warning* display and
*blocking* (PriceImpactModal) routing.
> 
> This introduces `usePriceImpactViewData` and refactors
`getPriceImpactViewData` to accept explicit `warning`/`error`
thresholds, switches components to evaluate against
`activeQuote.quote.priceData.priceImpact` (raw decimal) instead of
formatted percent strings, and renames `PriceImpactDescription`’s prop
to `formattedPriceImpact` to clarify intent.
> 
> Tests and mocks are updated accordingly (including feature-flag state
setup), and `AppConstants.BRIDGE` defaults are changed from
percent-style `5/25` to decimal `0.05/0.25`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
2b60f9a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…ed (#27190)

## **Description**

Account balances displayed in the account list were not respecting the
hide balances (privacy mode) setting toggled from the main wallet view.
This aligns mobile behaviour with extension.

The fix replaces the plain `Text` component in `AccountCell`'s
`BalanceEndContainer` with `SensitiveText`, reading `privacyMode` from
`selectPrivacyMode` via Redux.

## **Changelog**

CHANGELOG entry: Fixed a bug where hiding balances on the wallet home
screen was not reflected in the account list

## **Related issues**

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

## **Manual testing steps**

```gherkin
Feature: Hide balances in account list

  Scenario: user hides balances then opens account list
    Given the user is on the wallet home screen

    When user taps the eye icon to hide balances
    And user taps the account selector to open the account list
    Then balances should be masked in the account list

  Scenario: user shows balances then opens account list
    Given the user has previously hidden balances

    When user taps the eye icon to show balances
    And user taps the account selector to open the account list
    Then balances should be visible in the account list
```

## **Screenshots/Recordings**

`~`

### **Before**


https://github.com/user-attachments/assets/eb0dcaba-b58e-41d2-a793-e4545177526b

### **After**


https://github.com/user-attachments/assets/f4bf96ae-2f66-467a-9ff8-26b8f3472a26

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> UI-only change that masks displayed balances based on the existing
`privacyMode` preference; low risk aside from potential regressions in
balance rendering/masking conditions.
> 
> **Overview**
> Account list balance rendering now respects the global *privacy mode*
setting by swapping the `AccountCell` balance label from `Text` to
`SensitiveText` and driving masking via `selectPrivacyMode`.
> 
> Tests are updated to seed `PreferencesController.privacyMode` in
mocked Redux state and add coverage for masked/unmasked balance display,
including the no-balance case.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d3b78b9. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
update applinks with deeplinks for apple login

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

## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes OAuth redirect URI selection for Android Apple login; a
misconfiguration could break Apple sign-in or callback handling on
Android.
> 
> **Overview**
> Updates the OAuth login handler factory to stop depending on
`AppRedirectUri` and instead pass `AndroidGoogleRedirectUri`
(universal-link redirect) as the `appRedirectUri` for the Android Apple
login handler.
> 
> This also relaxes the startup env-var validation by removing the
`AppRedirectUri` requirement.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
8ec46e0. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…t/order breadcrumbs (#26863)

## **Description**

We need to measure how long order execution takes depending on the
payment method (Perps balance vs paying with ETH or other tokens) and to
separate deposit from order execution in Sentry.


## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TAT-2618

## **Manual testing steps**

```gherkin
Feature: Perps Sentry tracing

  Scenario: Place order with Perps balance
    Given user is on Perps order view with sufficient Perps balance
    When user places an order (no deposit)
    Then Sentry receives a "Perps Place Order" span with tag payment_token=perps_balance and breadcrumb "Order execution started"

  Scenario: Place order with custom token (e.g. ETH)
    Given user has "pay with any token" and selects ETH
    When user places an order (deposit + order or order only)
    Then Sentry receives "Perps Place Order" span with tag payment_token=ETH and breadcrumb "Order execution started"; if deposit ran first, "Deposit action started" breadcrumb is present
```

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

<!-- [screenshots/recordings] -->
No visible change

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: changes are instrumentation-only (Sentry breadcrumbs and
trace tags) with minimal impact on order/deposit execution paths beyond
additional logging calls.
> 
> **Overview**
> Adds Sentry breadcrumbs to distinguish *deposit start* (in
`PerpsController.depositWithConfirmation`) from *order execution start*
(in `TradingService.placeOrder`).
> 
> Enhances the `PerpsPlaceOrder` Sentry trace by adding a
`payment_token` tag/data field derived from `trackingData`
(`perps_balance`, selected token symbol, or `unknown_token`), with
updated tests and Sentry reference docs to reflect the new
instrumentation.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b942d44. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…D errors (#27178)

## **Description**

Replace `getActiveProvider()` with `getActiveProviderOrNull()` in 5
hooks that call the provider before PerpsController initialization
completes.

The throwing variant causes a race condition when React hooks mount
before async controller init finishes, producing ~249
CLIENT_NOT_INITIALIZED errors/day in Sentry. The null-returning variant
allows hooks to bail early gracefully, matching the pattern already used
by `useWithdrawalRequests`.

**Hooks updated:**
- `usePerpsMarketFills` — was reporting to Sentry via Logger.error
- `useUserHistory` — was surfacing as unnecessary error state
- `useDepositRequests` — was throwing "No active provider available"
- `usePerpsTransactionHistory` — was throwing "No active provider
available"
- `usePerpsHomeData` — defense-in-depth (already had isInitialized
guard)

## **Changelog**

CHANGELOG entry: Fixed a race condition causing CLIENT_NOT_INITIALIZED
errors when navigating to Perps before controller initialization
completes

## **Related issues**

Fixes: METAMASK-MOBILE-5E61

## **Manual testing steps**

```gherkin
Feature: Perps hooks handle uninitialized controller gracefully

  Scenario: User navigates to Perps before controller init completes
    Given the app is launched and PerpsController is still initializing

    When user navigates to PerpsMarketListView
    Then no CLIENT_NOT_INITIALIZED errors appear in Metro logs
    And the UI shows loading state until the controller finishes initializing
    And data loads normally once initialization completes
```

## **Screenshots/Recordings**

### **Before**

N/A — error suppression fix, no UI changes. Verified via Metro logs and
CDP.

### **After**

N/A — error suppression fix, no UI changes. Verified via Metro logs and
CDP.

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk defensive change: swaps provider lookup to a null-safe
variant and adjusts loading/error handling; main risk is masking real
provider-availability issues by returning early without surfacing an
error.
> 
> **Overview**
> Prevents Perps hooks from throwing/logging errors when the
`PerpsController` provider isn’t ready by switching from
`getActiveProvider()` to `getActiveProviderOrNull()` in
`useDepositRequests`, `usePerpsTransactionHistory`, `useUserHistory`,
`usePerpsMarketFills`, and `usePerpsHomeData`.
> 
> When the provider is `null`, these hooks now **bail out gracefully**
(clearing loading state and leaving `error` as `null`) instead of
throwing `No active provider available` and generating
`CLIENT_NOT_INITIALIZED` noise. Tests are updated accordingly to mock
`getActiveProviderOrNull` and assert the new no-error behavior.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b85d67b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…lures (#27242)

## **Description**

In `HyperLiquidProvider.fetchValidatedDexsInternal`, the catch block for
a failed `perpDexs()` API call was using `logger.error()`, which routes
to Sentry. The error is fully handled — the app returns `[null]`, falls
back to main DEX, and retries on the next call. Using `error()`
overstates severity and generates Sentry noise.

I switched to `debugLogger.log()`, consistent with the invalid-response
case directly below in the same function, which uses the same pattern
for the same reason.

This error became visible in Sentry after #27127 fixed the caching bug:
before that fix, the same transient failure was masked by the downstream
"perpDexs not cached" crash.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: Sentry issue
[7317078108](https://metamask.sentry.io/issues/7317078108/) — `Unknown
error (no details provided)
[HyperLiquidProvider.fetchValidatedDexsInternal]`

## **Manual testing steps**

```gherkin
Feature: perpDexs transient failure handling

  Scenario: perpDexs() API call fails transiently
    Given the app is running with HIP-3 enabled
    When the HyperLiquid perpDexs() API returns an error
    Then the app falls back to main DEX without crashing
    And no error is sent to Sentry
    And the next call retries the perpDexs() fetch
```

## **Screenshots/Recordings**

### **Before**

Sentry: ~11 events/day — `Unknown error (no details provided)
[HyperLiquidProvider.fetchValidatedDexsInternal]` on 7.68.0

### **After**

0 Sentry events. Failure logged locally via `debugLogger.log` only.

## **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
- [ ] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: only changes log level/shape for a transient,
already-handled error path while preserving the existing fallback to
main DEX and retry behavior.
> 
> **Overview**
> Stops reporting `HyperLiquidProvider.#fetchValidatedDexsInternal`
transient `perpDexs()` API failures as `logger.error()` (Sentry noise)
and instead logs them via `debugLogger.log()` with a clear fallback
message and context.
> 
> Behavior remains the same on failure: it returns `[null]` (main DEX
only) and does not cache the result so the next call can retry.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
dcefda0. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

- Introduced a new helper function `assertTrendingTokenRowsVisibility`
to streamline visibility checks for trending tokens in the TrendingView
tests.
- Updated existing tests to utilize this helper, improving readability
and maintainability.
- Ensured that the tests now assert the presence and content of trending
tokens more effectively, enhancing overall test coverage.

## **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: test: add back Trending CV test

## **Related issues**

Fixes: #26269
https://consensyssoftware.atlassian.net/browse/ASSETS-2733

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Test-only changes that mainly refactor assertions and input
simulation; the only broader impact is an added Perps controller mock
method that could subtly affect other component-view tests.
> 
> **Overview**
> **TrendingView component tests were refactored and stabilized.** Adds
`assertTrendingTokenRowsVisibility` and shared test IDs to reduce
duplicated row assertions, and introduces `actButtonPress` to prefer
`userEvent.press` with a `fireEvent.press` fallback for platform/device
reliability.
> 
> **Re-enables the previously skipped Explore search test** and updates
trending/full-view tests to use the new helpers, including
network-filter and search visibility checks. Updates the shared
component-view Engine mock to include
`PerpsController.isCurrentlyReinitializing` returning `false` to unblock
rendering in these tests.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
19be038. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…m Asset Details (#27213)

## Description

When users tap **Long** or **Short** from the Asset Details (Token
Details) screen, the app navigates to `PerpsOrderRedirect`, which calls
`depositWithOrder()` to create the deposit transaction. If the user does
not have the Arbitrum network in their wallet (e.g. fresh install or
certain builds), `PerpsController.depositWithConfirmation` throws
because `#findNetworkClientIdForChain(assetChainId)` returns `null`, and
the user sees the generic **"Transaction creation failed. Please try
again."** toast.

The in-Perps flows (Add funds from Perps home, Perps balance in
pay-with) already call `ensureArbitrumNetworkExists()` from
`usePerpsNetworkManagement` before creating the deposit, so Arbitrum is
added when missing. The one-click Long/Short path from Token Details did
not, so it could fail for users without Arbitrum.

This PR adds the same **ensure Arbitrum** step in `PerpsOrderRedirect`:
before calling `depositWithOrder()`, we call
`ensureArbitrumNetworkExists()`. If Arbitrum is missing, it is added and
enabled; then the deposit tx is created. On failure of either step, the
existing toast and go-back behavior is unchanged.

**Changes:**
- `PerpsOrderRedirect`: use `usePerpsNetworkManagement`, call
`ensureArbitrumNetworkExists()` then `depositWithOrder()` in the effect.
- Tests: mock `usePerpsNetworkManagement`, add tests for "ensure then
deposit" and for "toast + go back when ensure fails".

---

## Changelog

CHANGELOG entry: Long/Short from Asset Details now ensures Arbitrum
network exists (adds it if missing) before creating the deposit
transaction, fixing "Transaction creation failed" when the user has no
Arbitrum network (#26756)

---

## Related issues

Fixes: #26756 – Asset Details: Cannot Short/Long from the Asset Details
page, getting "Transaction creation failed. Please try again."

---

## Manual testing steps

**Feature:** Perps one-click Long/Short from Asset Details

**Scenario:** User taps Long or Short from Token Details when Arbitrum
is not in the network list
- **Given:** Perps enabled, Token Details V2 layout (treatment) so
Long/Short are visible, and Arbitrum One removed from Settings →
Networks (or use a profile that never had Arbitrum).
- **When:** User opens Token Details for a perps asset (e.g. ETH) and
taps **Long** or **Short**.
- **Then:** App shows "Preparing order…", adds Arbitrum if missing,
creates the deposit tx, and navigates to the confirmation screen (no
"Transaction creation failed" toast).

**Scenario:** User taps Long or Short when Arbitrum is already present
- **Given:** Arbitrum One is in the network list.
- **When:** User opens Token Details for a perps asset and taps **Long**
or **Short**.
- **Then:** Flow proceeds to confirmation as before (no regression).

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes the perps one-click Long/Short initiation flow to add/enable a
network before creating a deposit transaction, which could affect order
startup timing and error paths. Scope is limited to `PerpsOrderRedirect`
and is covered by added unit tests for success and failure cases.
> 
> **Overview**
> Fixes the Token Details Long/Short redirect flow by **ensuring the
Arbitrum network is present/enabled** via
`ensureArbitrumNetworkExists()` before calling `depositWithOrder()` in
`PerpsOrderRedirect`.
> 
> Updates tests to mock `usePerpsNetworkManagement` and to assert the
new call order (ensure → deposit), plus verify toast + `goBack` behavior
when the network ensure step fails.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
5938c6f. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…26890)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

This PR fixes spacing, border radius, typography and text styles to
polish features across mobile. This makes our app feel more refined, and
reduces the deferred UX.

**Issues addressed:**
- Inconsistent styling across section headers (e.g. “Explore crypto”,
“Your orders”)
- `Prediction` outcome titles (e.g. on Market Details) were set to
`20px`, which deviated from design specs
- Buttons on `Predictions` cards were too large, causing vertical rhythm
issues
- Inconsistent vertical padding across `Perps`, `Explore`, and
`Predictions`
- `16px` border radius was overly rounded and did not match our design
system styles

**Improvements**
- Correct text style applied for “Explore crypto” for `Perps`
- Updated `Prediction` outcome titles to align with our list styling
- Button styling on `Predictions` updated to match design specs
- Perceptibly uniform padding applied across sections
- `12px` border radius applied to cards to align with our Button styles

Changes have been approved by @mmragkandala 

## **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: chore: fixes UI styling on perps, explore and
predictions

## **Related issues**

Fixes: NA

## **Manual testing steps**

```gherkin
Feature: Explore and Perps UI styling updates

  Scenario: user views Explore and Perps sections
    Given the user is on the Explore feed or Perps home
    When the user views Trending tokens, Stocks, Explore crypto, or Your orders sections
    Then section titles use the intended typography (e.g. bold where updated)
    And list content has correct horizontal padding (e.g. 16px on market lists)
    And cards and section containers use consistent border radius (e.g. 12px)

Feature: Explore feed and Perps home UI polish

  Scenario: user sees updated section styling
    Given the user has opened the Explore tab or Perps home
    When the user scrolls through Trending tokens, Stocks, or Explore crypto
    Then section cards and list rows display with consistent spacing and border radius
    And section headers (e.g. "Explore crypto", "Your orders") use the correct font weight and size
```

## **Screenshots/Recordings**

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

### **Before**

<img width="1406" height="759" alt="Screenshot 2026-03-03 at 8 39 00 PM"
src="https://github.com/user-attachments/assets/f2443ec4-0c7a-41d6-aa8f-e7beb8a72d76"
/>

### **After**

<img width="1404" height="745" alt="Screenshot 2026-03-03 at 8 39 23 PM"
src="https://github.com/user-attachments/assets/3b89ca1d-e574-48bf-a85a-e6bfc7421370"
/>


<img width="1414" height="775" alt="Screenshot 2026-03-03 at 8 39 37 PM"
src="https://github.com/user-attachments/assets/b6f4dd02-c620-4b41-abc0-1ccd175037b3"
/>
Original designs for context. Note that polish should happen in the
codebase.

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk visual-only changes adjusting spacing, border radii, and text
variants; no business logic or data flow changes.
> 
> **Overview**
> Polishes UI styling across **Perps**, **Predict**, and
**Trending/Explore** sections to better align with design specs.
> 
> Updates spacing and layout rhythm (e.g., Perps home positions/orders
padding, market row/card padding, recent activity item padding, and
removes extra bottom padding in `PerpsMarketList`). Standardizes rounded
corners to `12px` on various list/card containers and first/last row
groupings.
> 
> Adjusts typography in key headers/labels (e.g.,
`PerpsMarketTypeSection` header uses `TextVariant.HeadingMD`; Predict
market/outcome titles and action button labels use smaller/more
consistent `TextVariant` values) and reduces oversized Predict card
button sizing to `ButtonSize.Sm` in the multi-outcome card.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
32c3f1c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…27195)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

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

- Add `useFiatPaymentHighlightedActions` hook that converts Ramps
payment methods into selectable items for the Pay-With-Modal, gated
behind the `confirmations_pay_fiat` feature flag
- Extend `HighlightedItem` type with optional `paymentType` field to
support rendering `PaymentMethodIcon` alongside existing icon types
- Extract `HighlightedItemIcon` and `HighlightedItemActions` local
components to simplify the `HighlightedItem` rendering logic
- Make fiat and `fiat_description` optional on `HighlightedItem` since
payment method rows don't display fiat values
- Selecting a payment method toggles
`fiatPayment.selectedPaymentMethodId` on the current transaction via
`TransactionPayController.updateFiatPayment`

## **Changelog**

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

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

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

CHANGELOG entry:

## **Related issues**

Fixes: #27112

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Medium risk because it introduces new transaction-updating selection
logic (`TransactionPayController.updateFiatPayment`) and changes the
`HighlightedItem` rendering/type shape, which could affect Pay-With UI
behavior when the fiat feature flag is enabled.
> 
> **Overview**
> Adds `useFiatPaymentHighlightedActions` to convert available Ramps
payment methods into selectable `HighlightedItem`s for the Pay-With
modal (gated by `confirmations_pay_fiat`), toggling
`fiatPayment.selectedPaymentMethodId` via
`TransactionPayController.updateFiatPayment`.
> 
> Updates the highlighted row UI/type to support payment-method icons:
`HighlightedItem` now accepts optional `paymentType` (rendered with
`PaymentMethodIcon`, taking precedence over `icon`) and makes
`fiat`/`fiat_description` optional; `HighlightedItem` rendering is
refactored into `HighlightedItemIcon` and `HighlightedItemActions`.
Tests were added/updated to cover the new hook behavior and payment icon
rendering.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
bf19b0a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## Summary

Aligns the component-view-test agent skill with the repo’s skill
structure and with Cursor/Claude usage.
1. **Skill structure**: Added `.agents/skills/component-view-test/` with
full skill (SKILL.md, workflow, golden rules), reference docs
(writing-tests, navigation-mocking, reference), and `agents/openai.yaml`
for the OpenAI Codex interface (`display_name`, `short_description`,
`default_prompt`), following the same pattern as other skills (e.g.
ab-testing-implementation).
2. **Single source of truth**: Replaced scattered docs with the
canonical skill. Removed `.cursor/rules/component-view-testing.mdc`,
`tests/.cursor/rules/component-view-tests-local.mdc`, and
`tests/component-view/COMPONENT_VIEW_TEST_RULES.md`; their content lives
in the skill and its references. Root `AGENTS.md` no longer lists a
component-view Cursor rule; Test Guidelines now point to
`tests/AGENTS.md`.
3. **Cursor / BUGBOT**: No Cursor rule for component-view tests anymore.
`.cursor/BUGBOT.md` now points to the skill
(`.agents/skills/component-view-test/SKILL.md`) for setup and
enforcement instead of a removed rule.
4. **Agent indexes and Claude**: Added `tests/component-view/AGENTS.md`
(framework, run commands, links to skill). `tests/AGENTS.md` links to it
under Component-View Tests. Added
`.claude/skills/component-view-test/SKILL.md` shim that delegates to the
canonical skill. Cursor and Claude both use the same skill as the single
source.
No changes to the component-view test framework or to test code; only
tooling, discovery, and documentation for Cursor, Claude, and Codex.


Examples how it works:
Cursor:
<img width="552" height="163" alt="Screenshot 2026-03-05 at 13 16 12"
src="https://github.com/user-attachments/assets/5b4de09a-1dde-465a-8a95-c10cf01890fe"
/>

Claude:
<img width="795" height="396" alt="Screenshot 2026-03-05 at 13 14 19"
src="https://github.com/user-attachments/assets/b68ca047-4044-4e84-bf43-201f25dfd406"
/>


## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: Component view test skill and rules

  Scenario: verify skill and rules are referenced correctly
    Given the repo has .ai/skills/component-view-test/ and .cursor/rules/component-view-test.mdc
    When opening a *.view.test.tsx file or tests/component-view/ in the editor
    Then the component-view-test rule/skill is available and points to SKILL.md and references
```




<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Documentation/tooling-only changes that rehome component view test
guidance into a new skill; low runtime risk but could affect developer
workflow if references/paths are wrong.
> 
> **Overview**
> Adds a new canonical `.agents/skills/component-view-test/` skill (plus
OpenAI interface config) with focused references for writing, navigation
mocking, running/self-review, and failure diagnosis for
`*.view.test.tsx`.
> 
> Updates agent entrypoints (`AGENTS.md`, `tests/AGENTS.md`,
`tests/component-view/AGENTS.md`, `.cursor/BUGBOT.md`) and adds a Claude
shim to point to the skill as the *single source of truth*, while
removing the old Cursor rule files and
`tests/component-view/COMPONENT_VIEW_TEST_RULES.md`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
a1f2aec. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

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 the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Adds the provider interface, first provider implementation, HTTP service
layer, country→provider routing, and environment-aware configuration for
the Card feature's multi-provider architecture.

**Why**: The Card feature needs an abstraction layer so that different
card providers can be integrated behind a single interface. Today,
business logic is scattered across hooks, views, and a monolithic SDK.
This PR extracts that logic into a provider class that implements a
shared interface, with a dedicated HTTP service and configuration
resolver.

**What changed**:

- **`provider-types.ts`** (278 lines): Defines the `ICardProvider`
interface and all provider-agnostic types — `CardHomeData`,
`CardFundingAsset`, `CardAuthTokens`, `CardAuthSession`,
`CardProviderCapabilities`, alerts, actions, onboarding, and funding
types. Designed inward from what screens need, not from any specific API
shape.

- **`BaanxProvider.ts`** (~715 lines): First implementation of
`ICardProvider`. Handles auth (PKCE OAuth flow with email/password +
OTP), card home data orchestration (delegation settings → wallet details
→ asset mapping → alerts/actions), card operations (freeze/unfreeze,
secure view), funding config, asset priority, and onboarding step
submission. All provider-specific API concepts are mapped to the shared
interface at the boundary.

- **`BaanxService.ts`** (~128 lines): Axios-based HTTP client for the
provider API. Handles auth headers, location-based routing (`x-us-env`),
timeout, and error mapping to `CardApiError`. Takes `{ apiKey, baseUrl
}` at construction for testability.

- **`baanx-config.ts`** (~47 lines): Environment-aware configuration
resolver. Returns `{ apiKey, baseUrl }` from build-time env vars
(`MM_CARD_BAANX_API_CLIENT_KEY`, `BAANX_API_URL`) with `AppConstants`
fallback per `METAMASK_ENVIRONMENT`. Co-located with the service it
configures.

- **`provider-config.ts`** (~22 lines): Shared `CardProviderConfig`
interface and `CardProviderFactoryMap` type. Standardizes the config
shape all providers must resolve.

- **`provider-map.ts`** (~43 lines): Country→provider routing.
`getProviderForCountry()`, `getSupportedCountries()`, and
`deriveCountryProviderMap()` — derives routing from the existing
`cardSupportedCountries` feature flag. No hardcoded country lists.

- **`babel.config.tests.js`**: Added the config resolver files to the
`transform-inline-environment-variables` exclusion list so `process.env`
reads remain dynamic at test time.

- **Tests**: 758 lines of tests across 4 test files covering the
provider (29 tests), service (12 tests), config resolver (8 tests), and
country mapping (8 tests). Total: 57 new tests.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: No user-facing changes

  Scenario: Card feature continues to work as before
    Given the user is on any screen in the app
    When the app loads
    Then nothing visually changes
    And the Card feature continues to work as before

  Scenario: Existing card authentication is unaffected
    Given the user is authenticated with the Card feature
    When the app updates to this version
    Then the user remains authenticated
    And all card screens render normally
```

## **Screenshots/Recordings**

No UI changes — this is an infrastructure-only PR. The provider,
service, and configuration are not wired into the controller yet.

### **Before**

Business logic scattered across hooks, views, and a monolithic SDK. No
provider abstraction. Configuration read from `process.env` directly
inside the SDK.

### **After**

Provider interface (`ICardProvider`) and first implementation exist
alongside the current code. HTTP service with injected configuration.
Country→provider routing ready for use. None of this code is active in
production yet — it will be wired in when the controller code path
switch ships.

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Mostly additive provider/service code plus unit tests; no production
wiring changes. Minor risk comes from new OAuth/funding logic and the
test Babel override update affecting how `process.env` is handled in
tests.
> 
> **Overview**
> **Adds a new multi-provider foundation for the Card controller (not
yet wired into runtime).** This introduces shared provider types
(`ICardProvider`, auth/funding/onboarding/home-data models), a
country→provider mapping helper, and a standard `CardProviderConfig`
shape.
> 
> Implements the first provider, `BaanxProvider`, backed by a new
axios-based `BaanxService` (location-aware headers, auth header
injection, and `CardApiError` mapping) plus an env-driven
`resolveBaanxConfig()`.
> 
> Small refactor in `CardOnboardingStore` replaces the exported
`EMPTY_ONBOARDING_DATA` constant with an `emptyOnboardingData()`
factory, and `babel.config.tests.js` excludes the new config files from
inline env var transforms to keep tests dynamic. Extensive new unit
tests cover the provider, service, config resolver, and provider-map
helpers.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
1e3f8f4. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…27171)

## **Description**

Refactor `TransactionDetailsSummary` component into more readable
component hierarchy.

- **`StatusIcon`** — Generic severity-based icon component with optional
tooltip, extracted from `TransactionDetailsStatus`
- **`ProgressList` / `ProgressListItem`** — Generic step-based progress
UI with dividers, severity icons, and action buttons
- **`TransactionSummaryLine`** — Shared component handling date
formatting, block explorer navigation, severity mapping, and `0x0` hash
filtering
- **Per-type line components** — `DefaultSummaryLine`,
`ApprovalSummaryLine`, `RelayDepositSummaryLine`, `ReceiveSummaryLine`
each encapsulate type-specific display logic
- **`TransactionDetailsSummary`** — Now a thin orchestrator routing
transaction types to line components via `ProgressList`
- **`TransactionDetailsStatus`** — Simplified by removing
bridge-specific logic and delegating to `StatusIcon`
- Deleted `transaction-details-summary.styles.ts` (no longer needed)

## **Changelog**

CHANGELOG entry: null

## **Related issues**

## **Manual testing steps**

## **Screenshots/Recordings**

### **Before**

### **After**

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Mostly a UI refactor, but it rewires transaction summary routing,
status icon/tooltip behavior, and block-explorer link resolution
(including `0x0` hash filtering), which could change what users see or
can tap in confirmations.
> 
> **Overview**
> **Refactors the confirmations Transaction Details Summary into
smaller, reusable pieces** and replaces the bespoke “summary line”
layout with a new `ProgressList`/`ProgressListItem` step UI.
> 
> `TransactionDetailsSummary` is now a thin router that selects per-type
line components (`DepositSummaryLine`, `ReceiveSummaryLine`,
`ApprovalSummaryLine`, `DefaultSummaryLine`) and skips
non-`relayDeposit` child transactions when the parent is
`musdConversion`.
> 
> Introduces shared building blocks: `TransactionSummaryLine`
centralizes date formatting, block-explorer navigation, and `0x0` hash
suppression; `StatusIcon` provides severity-based icons with optional
error tooltip; and `getSeverity`/`getErrorMessage` move status/error
parsing into `utils/transaction`. `TransactionDetailsStatus` is
simplified to use these helpers and drops bridge-history-based status
overrides. Tests are updated/split accordingly and the old
`transaction-details-summary.styles.ts` is removed.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
c67440b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…tants, whenEngineReady, snapKeyring to app/util/analytics (#26891)

## **Description**

Part of the analytics cleanup workstream (#26686).

- Moves infrastructure files out of `app/core/Analytics/` into
`app/util/analytics/`
- Renames files to drop the `MetaMetrics` prefix:
  - `MetaMetricsPrivacySegmentPlugin` → `privacySegmentPlugin`
  - `MetaMetrics.constants` → `constants`
- Renames the exported constant `METAMETRICS_ANONYMOUS_ID` →
`ANALYTICS_ANONYMOUS_ID`
- Updates import paths
- Adds a previously missing `whenEngineReady.test.ts`

Files scheduled for deletion in later PRs (e.g. `MetaMetrics.ts`) are
intentionally left untouched.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: #26810

## **Manual testing steps**

N/A

## **Screenshots/Recordings**

N/A

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Moderate risk because it rewires import paths and constants across
analytics, Engine readiness polling, and Segment setup used at runtime;
mistakes could break analytics initialization or cause lingering timers,
though behavior is intended to be unchanged and is now covered by new
tests.
> 
> **Overview**
> Refactors analytics infrastructure by moving `whenEngineReady`,
Segment persistence (`segmentPersistor`), the privacy Segment plugin,
and the anonymous-id constant out of `core/Analytics` into
`util/analytics`, including renaming `METAMETRICS_ANONYMOUS_ID` to
`ANALYTICS_ANONYMOUS_ID`.
> 
> Updates runtime imports (e.g., `analytics.ts`, `platform-adapter.ts`,
`OAuthService.ts`, `SnapKeyring.ts`) and a broad set of Jest
tests/global test setup to mock the new module paths, and adds a
dedicated `whenEngineReady` unit test to validate retry/backoff
behavior.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
2737a6e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…27244)

## **Description**

The Predictions section empty-state carousel was using `snapToOffsets` +
`decelerationRate="fast"` to snap card-by-card when swiping. This made
the behavior inconsistent with the Perps section carousel, which
free-scrolls. This PR removes the snap logic from the Predictions
carousel to align both carousels with the same UX pattern.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

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

## **Manual testing steps**

```gherkin
Feature: Predictions carousel scroll behavior

  Scenario: user scrolls the predictions empty-state carousel
    Given the user has no prediction positions
    And trending prediction markets are available

    When user swipes the predictions carousel
    Then the carousel scrolls freely without snapping card-by-card
    And the behavior matches the Perps section carousel
```

## **Screenshots/Recordings**

`~`

### **Before**


https://github.com/user-attachments/assets/22d6d7ff-8fca-4647-a599-70e9d361f0ee

### **After**


https://github.com/user-attachments/assets/60a63895-a255-4e7d-a0cf-1eea97a65f7a

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> UX-only change to scrolling behavior in the Predictions empty-state
carousel; no data, auth, or navigation logic is affected.
> 
> **Overview**
> Removes the card-by-card snapping behavior from the homepage
Predictions empty-state carousel by deleting the computed
`snapToOffsets`/layout constants and dropping `snapToOffsets` +
`decelerationRate="fast"` from the horizontal `ScrollView`.
> 
> The carousel now free-scrolls (matching the Perps carousel) while
keeping the same loading skeletons, market cards, and trailing
`ViewMoreCard`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
65fe3c4. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Updates price impact modals content

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

## **Changelog**

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

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

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

CHANGELOG entry: Updates price impact modals content

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/SWAPS-4239,
https://consensyssoftware.atlassian.net/browse/SWAPS-4240

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

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

### **After**



https://github.com/user-attachments/assets/746ae502-e694-4099-a5eb-6c192ffcd3ec



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

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Mostly UI copy/rendering refactors and test updates; risk is limited
to incorrect i18n key wiring or visual regressions in the bridge price
impact surfaces.
> 
> **Overview**
> Bridge price-impact messaging is refactored so `PriceImpactHeader` and
`PriceImpactDescription` render directly from passed i18n `content` keys
(plus optional icon/color), instead of branching on
`PriceImpactModalType`/“warning state”. The modal now always receives
`formattedQuoteData.priceImpact` and uses `usePriceImpactViewData` to
choose the appropriate `title`/`description` keys and icon styling.
> 
> `getPriceImpactViewData` now returns design-system colors and adds
explicit `title`/`description` keys for info/warning/error states;
`QuoteDetailsCard` updates its price impact row to use those
colors/icons and adjusts tests/snapshots accordingly. English locale
strings are updated and new
`price_impact_warning_title`/`price_impact_error_title`/`price_impact_error_description`
keys are added.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
717dd57. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Fix issue related to info icon press navigating to select quotes rather
than opening info modal.

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

## **Changelog**

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

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

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

CHANGELOG entry: Fix issue related to info icon press navigating to
select quotes rather than opening info modal.

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/SWAPS-4245

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Small UI behavior change confined to the Bridge quote details rate
tooltip, with updated tests/snapshots to prevent regressions.
> 
> **Overview**
> Fixes the Rate info icon in `QuoteDetailsCard` so it opens the
standard tooltip modal (with `bridge.quote_info_*` content) instead of
navigating to the quote selector.
> 
> Refactors the Rate row label to use `KeyValueRowLabel` with an
attached tooltip, and updates the corresponding test and snapshot to
assert the new modal navigation payload and accessibility label-based
selection.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
a421fb9. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…ode (#27102)

## **Description**

This PR improves `ManualBackupStep3` by removing dead code and replacing
the shallow Enzyme snapshot test with a comprehensive
`@testing-library/react-native` test suite.

**Dead code removed from `index.js`:**
- Unused imports: `fontStyles`, `showAlert`
- Unused styles: `actionView`, `wrapper`, `congratulations`, `baseText`,
`successText`, `hintText`, `learnText`, `recoverText`
- Unused method: `learnMore` (navigated to MetaMask support webview)
- Unused dispatch mapping: `showAlert` in `mapDispatchToProps`

**Test rewrite (`index.test.tsx`):**
- Replaced shallow Enzyme snapshot with 24 focused RTL tests
- Coverage includes: rendering branches (steps, Android/iOS), navbar
options, BackHandler registration/cleanup, hint load from storage, hint
save validation (including seed-phrase match alerts), metrics tracking,
and `done` navigation reset
- Deleted the old snapshot file

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: ManualBackupStep3

  Scenario: user completes SRP manual backup step 3
    Given user is on the manual backup step 3 screen after completing SRP verification

    When user views the screen
    Then confetti animation displays
    And "Your wallet is ready" success component renders
    And hint modal is available for saving a recovery hint

  Scenario: dead code removal has no functional impact
    Given user navigates through the full SRP backup flow

    When user reaches step 3 and interacts with all UI elements
    Then all functionality works identically to before (no visual or behavioral changes)
```

## **Screenshots/Recordings**

N/A — No UI changes. This PR only removes unused code and rewrites
tests.

### **Before**

N/A

### **After**

N/A

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: production change is limited to removing unused
imports/styles/method/dispatch mapping in `ManualBackupStep3`, plus a
test rewrite and snapshot deletion.
> 
> **Overview**
> **Removes dead code** from `ManualBackupStep3` by dropping unused
imports (`fontStyles`, `showAlert`), unused style definitions, an unused
`learnMore` navigation helper, and the unused `showAlert` dispatch
mapping.
> 
> **Modernizes tests** by deleting the Jest snapshot and replacing the
Enzyme shallow render with an `@testing-library/react-native` suite that
covers rendering branches, navbar option setup, back-handler
registration/cleanup, hint persistence/validation, metrics tracking, and
`done` navigation reset.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
2589d27. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…ices (#27238)

## **Description**

On devices with increased font sizes (~80% of max accessibility
setting), the seed phrase words across multiple SRP screens would shrink
to unreadable sizes. This happened because:

1. `allowFontScaling` was enabled (default), causing system font scaling
to enlarge the text
2. `adjustsFontSizeToFit` would then shrink it back to fit inside the
fixed-height cell
3. `minimumFontScale={0.1}` allowed shrinking down to 10%, resulting in
tiny text

This fix uses `maxFontSizeMultiplier={1}` to cap the font at its base
design-system size, preventing it from scaling **up** beyond the
intended size on large font devices. Font scaling **down** is still
allowed, so users with smaller-than-default font sizes will see
proportionally smaller text — preserving accessibility in both
directions.

The `adjustsFontSizeToFit`, `minimumFontScale`, and previous
`allowFontScaling` / `maxFontSizeMultiplier={0}` props are removed as
they are no longer needed.

This applies to the index numbers and seed phrase words across **three
screens**:

- **`ManualBackupStep1`** — The "Save your Secret Recovery Phrase"
screen during onboarding
- **`ManualBackupStep2`** — The "Confirm your Secret Recovery Phrase"
screen during onboarding
- **`SeedPhraseDisplay`** (used by `RevealPrivateCredential`) — The
"Show Secret Recovery Phrase" screen in Settings > Security & Privacy

**Note:** At maximum font size, earlier onboarding screens overflow and
prevent navigation to the backup screens entirely — that is a separate
issue tracked in #18590's broader scope.

## **Related issues**

Fixes: #18590
Jira: TO-578

## **Manual testing steps**

### Scenario 1: ManualBackupStep1 — Seed phrase words are readable at
~80% large font size

```
Given I have set my device font size to approximately 80% of max (iOS: Settings > Accessibility > Display & Text Size > Larger Text)
And I navigate through onboarding to the "Save your Secret Recovery Phrase" screen
When I tap "Tap to reveal your Secret Recovery Phrase"
Then all 12 seed phrase words should be displayed at a consistent, readable size
And the word index numbers (1. through 12.) should also be at a readable size
And the text should NOT scale up larger than the default BodyMD size
```

### Scenario 2: ManualBackupStep2 — Confirmation grid words are readable
at ~80% large font size

```
Given I have set my device font size to approximately 80% of max
And I navigate through onboarding past the SRP reveal to the "Confirm your Secret Recovery Phrase" screen
Then the 12-word grid should display all words at a consistent, readable size
And the missing word options at the bottom should also display at a readable size
And the text should NOT scale up larger than the default size
```

### Scenario 3: RevealPrivateCredential — Settings SRP display is
readable at ~80% large font size

```
Given I have set my device font size to approximately 80% of max
And I navigate to Settings > Security & Privacy > Reveal Secret Recovery Phrase
When I enter my password and reveal the SRP
Then all 12 seed phrase words should be displayed at a consistent, readable size
And the word index numbers (1. through 12.) should also be at a readable size
And the text should NOT scale up larger than the default BodyMD size
```

### Scenario 4: Seed phrase words scale down at small font sizes

```
Given I have set my device font size to the smallest setting
And I navigate to any of the three SRP screens above
Then all 12 seed phrase words should scale down proportionally with the system font
And the text should be smaller than default, matching the user's preference
```

### Scenario 5: No visual regression at default font size

```
Given I have the default device font size
And I visit each of the three SRP screens above
Then all seed phrase words should display at normal BodyMD size
And there should be no visual regression from the previous behavior
```

## **Screenshots/Recordings**

<!-- Before/after screenshots at large, default, and small font sizes
-->


<img width="300" height="2868" alt="Simulator Screenshot - iPhone 17 Pro
Max - 2026-03-10 at 17 27 50"
src="https://github.com/user-attachments/assets/f2dfc451-a451-4334-9337-3a34997a6b7d"
/>
<img width="300" height="2868" alt="Simulator Screenshot - iPhone 17 Pro
Max - 2026-03-10 at 17 30 53"
src="https://github.com/user-attachments/assets/d1bb49dd-13a3-4593-bb6c-108dbbef37a0"
/>


<img width="300" height="2868" alt="Simulator Screenshot - iPhone 17 Pro
Max - 2026-03-10 at 17 29 28"
src="https://github.com/user-attachments/assets/f37b3455-c018-44a8-8b7e-de2e438a3818"
/>
<img width="300" height="2868" alt="Simulator Screenshot - iPhone 17 Pro
Max - 2026-03-10 at 17 33 29"
src="https://github.com/user-attachments/assets/db4aa7c5-5d60-4d81-a88f-7fafcc615fb9"
/>

<img width="300" height="2868" alt="Simulator Screenshot - iPhone 17 Pro
Max - 2026-03-10 at 17 26 51"
src="https://github.com/user-attachments/assets/595a2d2a-e4d6-4a99-bd33-ec1ccf963ba1"
/>
<img width="300" height="2868" alt="Simulator Screenshot - iPhone 17 Pro
Max - 2026-03-10 at 17 31 32"
src="https://github.com/user-attachments/assets/45f768a1-81fd-4986-90a1-44ac985ecd9b"
/>



## **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 this PR
- [x] I've manually tested this PR
- [x] I've confirmed there are no breaking changes

CHANGELOG entry: Fixed seed phrase words shrinking to unreadable sizes
on devices with large accessibility font settings while preserving font
scaling for smaller font preferences
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Create a central registry as a single source of truth that tracks all
feature flags with their production defaults. All tests run with this
registry unless the flag is specifically overridden by the tests. The
global mock (mock-e2e.js) reads from the registry to return
production-accurate flag values. Tests that need to test non-default
behavior use manifestFlags or withRemoteFeatureFlags() to override
specific flags. This encourages tests to start from production defaults
and only override what they're specifically testing.

## **Changelog**

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

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

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

CHANGELOG entry:

## **Related issues**


Fixes:[MMQA-1524](https://consensyssoftware.atlassian.net/browse/MMQA-1524)

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Test infrastructure now sources remote-flag defaults from a large,
centrally synced production registry and applies additional E2E-safe
overrides; mistakes or drift in these defaults can broadly change E2E
behavior and masking may hide real regressions.
> 
> **Overview**
> **Introduces a central `FEATURE_FLAG_REGISTRY`** (production-synced
defaults) plus helper APIs (`getProductionRemoteFlagApiResponse`, etc.)
and exports them via `tests/feature-flags/index.ts`.
> 
> **Updates remote feature-flag mocking** to pull defaults from the
registry instead of a hardcoded array, and adds `E2E_SAFE_DEFAULTS`
(e.g., lowering `mobileMinimumVersions.appMinimumBuild`) that are
deep-merged ahead of test overrides.
> 
> Adjusts multiple E2E suites/mocks to match the new production-accurate
defaults and networking paths: adds Accounts API balance mocks (v2/v4)
and fee mocks for mUSD/send/stake flows, adds SSE quote mocking for
bridge, broadens Relay proxy URL matching, expands the E2E allowlist
with additional Infura domains, and makes small stability tweaks in page
objects/tests (timeouts, retry, selectors, and predict flag overrides).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
538e21e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

The STX (Smart Transaction) status page — shown via the
`ApprovalController` after submitting a smart transaction — is legacy
code scheduled for removal. It was already confirmed dead in production:
the `mobileReturnTxHashAsap` feature flag is `true` in production, which
caused the hook to return the transaction hash immediately from the
submit response, bypassing all approval request logic entirely.

This PR removes all code in `smart-publish-hook.ts` that triggered the
status page, along with the utility functions in `index.ts` that
exclusively served it. As a direct consequence, the origin checks
(`isDapp`, `MM_FOX_CODE`, `ORIGIN_METAMASK`) that existed solely to gate
the modal are also removed.

**What was removed:**
- All approval-controller triggering methods from
`SmartTransactionHook`: `#addApprovalRequest`, `#updateApprovalRequest`,
`#addListenerToUpdateStatusPage`,
`#getApprovalIdForPendingSwapApproveTx`, `#cleanup`
- `getTransactionType`, `getShouldStartApprovalRequest`,
`getShouldUpdateApprovalRequest` from `index.ts` (only served the modal)
- `#updateSwapsTransactions` and related swap-type detection fields
(`#isSwapApproveTx`, `#isSwapTransaction`), which wrote legacy swap
metadata to the transaction controller state. Swaps relies on the
`BridgeStatusController` to capture this data now.
- `app/util/swaps/swaps-transactions.ts` and its test file — no
remaining callers
- `approvalController` wiring from `transaction-controller-init.ts`
publish hooks

## **Changelog**

CHANGELOG entry: null

## **Related issues**

#12622 discussed its
removal. I've confirmed with the STX team that the STX status page
should be removed. This PR just removes its triggers currently.

Resolves https://consensyssoftware.atlassian.net/browse/SWAPS-4190

## **Manual testing steps**

```gherkin
Feature: Smart Transactions

  Scenario: user submits a swap via Unified Swaps with STX enabled
    Given the user has STX enabled on mainnet
    And the user has a token balance

    When the user initiates a swap and confirms
    Then the transaction is submitted as a smart transaction
    And the transaction appears in the activity list with correct status
    And no STX status modal/approval page is shown

  Scenario: user submits a send transaction with STX enabled
    Given the user has STX enabled on mainnet

    When the user sends ETH and confirms
    Then the transaction is submitted as a smart transaction
    And the transaction appears in the activity list with correct status
    And no STX status modal/approval page is shown

  Scenario: user submits a dApp transaction with STX enabled
    Given the user has STX enabled on mainnet
    And the user is connected to a dApp

    When the dApp initiates a transaction and the user confirms
    Then the transaction is submitted as a smart transaction
    And the transaction appears in the activity list with correct status
    And no STX status modal/approval page is shown
```

## **Screenshots/Recordings**

### **Before**


https://github.com/user-attachments/assets/d63a9b3c-b1d7-4dec-8b87-675ad6332eb2



https://github.com/user-attachments/assets/b0896773-4853-460e-8080-71fea7a33fdb



### **After**




https://github.com/user-attachments/assets/830b8b00-eee2-4453-b8c8-30a62b5b4c2b



https://github.com/user-attachments/assets/7044325e-e6bb-4e49-bed4-c5345b09a21c




## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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


<!-- CURSOR_SUMMARY -->
> [!NOTE]
> **Medium Risk**
> Changes the smart-transaction publish path to stop creating/updating
`ApprovalController` requests and swap transaction side effects, which
may impact user-facing status UI and swap-related transaction display
during submission.
> 
> **Overview**
> **Removes smart-transaction status page triggering from the submit
path.** The smart-transactions publish hook no longer depends on
`ApprovalController`, no longer derives tx-type flags for UI decisions,
and no longer starts/updates/cleans up approval requests while waiting
for STX status.
> 
> Associated cleanup removes now-unused helpers (`getTransactionType`,
`getShouldStartApprovalRequest`, `getShouldUpdateApprovalRequest`) and
deletes the `swaps-transactions` utility/tests previously used to mirror
swap metadata into `TransactionController` state; tests are updated to
reflect the simpler STX submit behavior.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
9ec3094. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Display TRX that has completed the unstaking lock period and is ready
for withdrawal on the token details view. Refactor Tron staking UI so
`AssetOverviewContent` orchestrates all Tron staking components
directly.

### Added

- **`TronUnstakedBanner` component** — Info-only success banner
displaying "You can claim X TRX..." when TRX has completed the 14-day
unstaking lock period and is ready for withdrawal. No action button
(claim button deferred to NEB-576).
- **`TronStakingCta` component** — "Stake your TRX" promotional CTA with
APR percentage and an "Earn" button, shown to eligible users who have no
staked TRX positions. Gated behind `useStakingEligibility` so
geo-blocked users never see it.
- **`readyForWithdrawalBalance` derivation in `useTokenBalance`** —
Parses `trxReadyForWithdrawal` from the Tron special assets selector and
exposes it as a formatted string (only when > 0 and numeric).
- **`stake.tron.has_claimable_trx` locale string** — New i18n key for
the claimable TRX banner text.
- **Unit tests** for `TronUnstakedBanner`, `TronStakingCta` (including
eligibility guard), and `readyForWithdrawalBalance` edge cases in
`useTokenBalance`.

### Changed

- **`AssetOverviewContent` is now the orchestrator for all Tron staking
UI.** It directly renders, in order: native Balance → staked Balance →
`TronUnstakedBanner` → `TronUnstakingBanner` → `TronStakingButtons` (if
staked) or `TronStakingCta` (if not staked). Previously, staking
buttons/CTA were rendered inside `EarnBalance`.
- **`EarnBalance` no longer renders any Tron staking UI.** When the Tron
staking flag is enabled and the asset is a Tron chain asset, it returns
`null` — all Tron staking rendering responsibility moved to
`AssetOverviewContent`.
- **`TronStakingButtons` simplified** — Removed `showUnstake`,
`hasStakedPositions`, and `aprText` props. The CTA section was extracted
into the new `TronStakingCta`. Now always renders "Unstake" and
conditionally renders "Stake more" based on `useStakingEligibility`.
Removed the `if (!isEligible && !hasStakedPositions) return null` early
exit since the parent now controls when to render it.
- **`useTokenBalance` guards `stakedTrxAsset` with `totalStaked > 0`** —
Previously `createStakedTrxAsset` was always called for Tron native
tokens, producing a truthy object even with zero balance. Now
`stakedTrxAsset` is `undefined` when no TRX is actually staked, which
correctly drives the conditional rendering in `AssetOverviewContent`.

**Note:** This PR intentionally does not include a claim button. The
button and snap interaction are in NEB-576.

## **Changelog**

CHANGELOG entry: Added a banner to display TRX that is ready for
withdrawal on the token details view

## **Related issues**

Refs: NEB-582

## **Manual testing steps**

```gherkin
Feature: TRX ready for withdrawal display

  Scenario: user views TRX token details with TRX ready for withdrawal
    Given user has TRX that has completed the 14-day unstaking lock period

    When user navigates to the TRX token details view
    Then a success banner is displayed showing "You can claim X TRX. Once claimed you'll get TRX back in your wallet."
    And no action button is displayed in the banner

  Scenario: user views TRX token details without TRX ready for withdrawal
    Given user has no TRX ready for withdrawal

    When user navigates to the TRX token details view
    Then no claim banner is displayed
```

## **Screenshots/Recordings**

### **Before**

N/A - new feature

### **After**

<img width="507" height="950" alt="Screenshot 2026-03-09 at 22 42 19"
src="https://github.com/user-attachments/assets/31892885-023f-4a62-be3e-c04978b05348"
/>

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Updates Tron token details balance derivation and reorganizes
staking/unstaking UI rendering paths, which could affect when/where
staking CTAs and banners appear for TRX users; changes are UI/formatting
focused with test coverage.
> 
> **Overview**
> Adds a Tron-only “claimable TRX” success banner on the token details
view by deriving a new `readyForWithdrawalBalance` from
`trxReadyForWithdrawal` in `useTokenBalance` (with numeric/zero guards)
and wiring it through `TokenDetails` into `AssetOverviewContent`.
> 
> Refactors Tron staking UI ownership: `AssetOverviewContent` now
directly renders Tron staking/unstaking components (including a new
`TronStakingCta` for eligible users with no staked TRX), while
`EarnBalance` no longer renders any Tron staking UI and returns `null`
when Tron staking is enabled.
> 
> Simplifies `TronStakingButtons` by removing CTA-related props/markup,
always showing Unstake and conditionally showing “Stake more” based on
eligibility, and introduces shared test IDs; adds/updates unit tests and
introduces the new `stake.tron.has_claimable_trx` locale string.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
4fbff82. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Bumps `@metamask/assets-controllers` to `v100.2.0` and wires up the two
new features introduced in that release:

1. **`AccountTrackerController` — homepage sections v1 flag**
([core#8117](MetaMask/core#8117)): When
`isHomepageSectionsV1Enabled` is `true`, the controller uses all popular
EVM networks (via `NetworkEnablementController:listPopularEvmNetworks`)
for balance refresh on account change and keyring unlock, instead of
only the enabled networks. The `AccountTrackerController` messenger is
extended to delegate the two new `NetworkEnablementController` actions
it requires.

2. **`selectBalanceForAllWallets` — network configurations**: Passes
merged EVM + non-EVM
([core#8141](MetaMask/core#8141)):
`networkConfigurationsByChainId` (via `selectNetworkConfigurations`) as
an additional argument to `calculateBalanceForAllWallets`, enabling the
balance calculation to be aware of all configured networks.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: #23862

## **Manual testing steps**

```gherkin
Feature: Balance display with aggregated homepage

  Scenario: user views wallet balance with homepage sections v1 enabled
    Given the user has the homepageSectionsV1 remote feature flag enabled
    And the user has accounts on multiple EVM networks

    When the user opens the app
    Then balances are refreshed across all popular EVM networks
    And the total balance is displayed correctly

  Scenario: user views wallet balance with homepage sections v1 disabled
    Given the user has the homepageSectionsV1 remote feature flag disabled

    When the user opens the app
    Then balances are refreshed only for enabled networks
    And the total balance is displayed correctly
```

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

## **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.
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

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

Migrated `Skeleton` component to design system.

## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

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

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**


https://github.com/user-attachments/assets/7c871005-b0b1-41d5-9d4e-1b1323990be3

### **After**


https://github.com/user-attachments/assets/a53b3d28-8977-4cac-847e-1f4e677a3bdb

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk UI-only change that swaps Bridge loading placeholders to the
new `components-temp` design-system `Skeleton` wrapper; main risk is
minor visual/animation differences during loading states.
> 
> **Overview**
> Updates Bridge loading UI to use the design-system-backed `Skeleton`
by switching imports from the deprecated
`component-library/components/Skeleton` to
`component-library/components-temp/Skeleton` in
`QuoteDetailsCardSkeleton`, `SkeletonItem`, and `TokenInputArea`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
2ec0763. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

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

Migrate `Label` component (card scope).

## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

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

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

<img width="1206" height="2622" alt="image"
src="https://github.com/user-attachments/assets/6ceb7e27-f2bd-49b2-9b15-ece4843f6572"
/>

### **After**

<img width="1206" height="2622" alt="image"
src="https://github.com/user-attachments/assets/38d76c8f-40b6-464e-9d88-c5ce5885a6c5"
/>

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk UI-only change that swaps the `Label` implementation in card
screens; main risk is minor styling/test snapshot churn or subtle
accessibility differences.
> 
> **Overview**
> Migrates card-related screens/components to use `Label` from
`@metamask/design-system-react-native` instead of the local
`component-library` `Form/Label` (e.g., `CardAuthentication`,
`AddFundsBottomSheet`, and onboarding steps).
> 
> Updates associated Jest mocks and snapshots to reflect the new `Label`
rendering/styling (notably style arrays/fontWeight and removal of the
previous `testID="label"` output).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
65f2d04. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Before this PR, AssetOverviewContent started a manual Sentry trace for
MarketInsightsEntryCardLoad, and the happy-path end happened only when
the MarketInsightsEntryCard component actually mounted. If the asset had
no Market Insights report, that card never rendered, so its endTrace()
never ran. That left the span “open” in the trace map until the generic
cleanup timeout removed it. This is shown in the 5 min traces in the
screenshot.

This PR adds the missing failure/empty-state endTrace() path, ensuring
the trace is closed both when the card renders and when no asset/report
is available, instead of being left dangling until timeout. We can see
that even when the API returns a 404 and the report is not available,
the trace is ended.

<img width="2688" height="734" alt="SCR-20260310-khdy"
src="https://github.com/user-attachments/assets/435b2224-105c-4c08-9c1e-b7ba5a71b02e"
/>


## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TSA-241 


## **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
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk instrumentation-only change that closes a previously orphaned
Sentry span when Market Insights data is missing; main risk is
inadvertently ending a span too early/for the wrong asset id.
> 
> **Overview**
> Fixes an orphaned Sentry trace in `AssetOverviewContent` for
`TraceName.MarketInsightsEntryCardLoad` when Market Insights is enabled
but no report exists (e.g., 404), by explicitly calling `endTrace` once
loading completes.
> 
> Also makes the `onMarketInsightsDisplayResolved` callback
optional-safe (`?.`) and ensures the effect depends on
`marketInsightsCaip19Id` so trace cleanup aligns with the current asset.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
eb747c2. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
georgeweiler and others added 2 commits March 10, 2026 16:43
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

The OTP screen was showing a generic fallback error regardless of what
the API returned. This PR surfaces the actual Transak error messages to
the user on both OTP submission and resend failures.

The resend button state was also changed: instead of starting in the
"resend" state (waiting for the user to trigger a resend), the screen
now starts directly in cooldown mode because the OTP was already sent
when the user lands on this screen. The cooldown is also bumped from 30s
to 60s to match the actual resend window.

## **Changelog**

CHANGELOG entry: Fixed OTP error messages to show the actual error from
the server instead of a generic fallback.

## **Related issues**

Fixes: TRAM-3291

## **Manual testing steps**

```gherkin
Feature: OTP error display

  Scenario: user submits an invalid OTP code
    Given the user is on the OTP screen after starting a buy flow
    When the user enters a wrong 6-digit code
    Then the error message from the server is displayed instead of a generic one

  Scenario: user lands on the OTP screen
    Given the user navigated to the OTP screen
    Then a 60-second cooldown is immediately shown
    And the resend button is not visible until the cooldown ends

  Scenario: user tries to resend after cooldown
    Given the 60-second cooldown has elapsed
    When the user taps the resend button
    Then a new OTP is sent
    And a new 60-second cooldown starts
```

## **Screenshots/Recordings**

### **Before**

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

### **After**

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

Surface error without reseting the countdown:


https://github.com/user-attachments/assets/d09b03d5-44f1-4448-8805-e8d7c18f43b1

Countdown starts as soon as user navigates to OTP screen:


https://github.com/user-attachments/assets/56016104-ad20-46d0-b7fb-88e88e066507



## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes OTP resend timing/state handling and error surfacing on a
critical ramp authentication step; mistakes could prevent users from
resending or understanding failures.
> 
> **Overview**
> **Improves OTP resend UX in the ramp native flow.** The OTP screen now
starts in a *60s cooldown* (was 30s) since an OTP is already sent on
entry, and the initial UI/snapshot reflects the cooldown text instead of
an immediate resend link.
> 
> **Resend failures now show user-facing API errors.** `handleResend` no
longer transitions to a `resendError`/"contact support" UI state on API
failure; it sets the screen `error` using `parseUserFacingError` with a
fallback translation key, and tests add coverage for both message and
no-message resend failures.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
a6a1749. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: AxelGes <axelges9@gmail.com>
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Updates the AI icon in the component library to use the filled version
for visual consistency.

1. **Reason for the change:** The AI icon was using an outline style;
switching to the filled version aligns with design and improves
visibility/recognition.
2. **Improvement:** Replaced the AI icon asset with the filled variant.

## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

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

## **Manual testing steps**

```gherkin
Feature: AI icon display

  Scenario: AI icon shows filled variant
    Given the app is open

    When user navigates to a screen that displays the AI icon (e.g. Predict, or component library / Storybook)
    Then the AI icon is displayed in the filled style
    And the icon renders correctly at various sizes
```

## **Screenshots/Recordings**

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

### **Before**

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

### **After**


https://github.com/user-attachments/assets/756a06f3-f905-4438-ba91-82eff918e842

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

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk asset-only change; impact is limited to UI rendering of the
AI icon and could only affect visual appearance or sizing.
> 
> **Overview**
> Updates the component library AI icon by swapping `assets/ai.svg` to a
filled version and adding explicit `width`/`height` attributes on the
root `<svg>` to standardize sizing.
> 
> No code logic changes; only the rendered appearance of the `ai` icon
is affected wherever it’s used.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
044d67b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@pull pull Bot locked and limited conversation to collaborators Mar 10, 2026
@pull pull Bot added the ⤵️ pull label Mar 10, 2026
@pull pull Bot merged commit d8a188b into Reality2byte:main Mar 10, 2026
2 of 11 checks passed
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.