[pull] main from MetaMask:main#590
Merged
pull[bot] merged 32 commits intoReality2byte:mainfrom Mar 10, 2026
Merged
Conversation
## **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 -->
<!--
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 -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )