[pull] main from MetaMask:main#306
Merged
Merged
Conversation
<!-- 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 pull request enhances the flexibility of the `ListItemSelect` component by allowing custom props to be passed directly to its nested `ListItem` component. This makes it easier to customize accessibility and other properties when using `ListItemSelect`. **Component extensibility improvements:** * Added a new optional `listItemProps` prop to the `ListItemSelectProps` interface, allowing consumers to pass custom props to the nested `ListItem` component. * Updated the `ListItemSelect` component implementation to spread `listItemProps` onto the nested `ListItem` element. [[1]](diffhunk://#diff-b1ce9235b1fa82fff3758d3a8cefedb7decb33dd7445bf3411fb53925c9b06baR25) [[2]](diffhunk://#diff-b1ce9235b1fa82fff3758d3a8cefedb7decb33dd7445bf3411fb53925c9b06baL37-R38) **Testing enhancements:** * Added a test to verify that custom `listItemProps` are correctly passed through to the nested `ListItem`, ensuring that properties like `accessibilityHint` are set as expected. ## **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** N/A ## **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] > Adds `listItemProps` to `ListItemSelect` to forward props to its nested `ListItem`, with a test verifying passthrough (e.g., accessibility hints). > > - **Component Library** > - **`ListItemSelect`**: > - Adds optional `listItemProps` to `ListItemSelectProps` and spreads onto nested `ListItem` in `ListItemSelect.tsx`. > - **Tests**: > - Adds test ensuring `listItemProps` (e.g., `accessibilityHint`, `testID`) are passed through to the nested `ListItem`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 5e7b8bf. 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**
Re-order migrations 105, 106, 107
Removal of migration 104 redux-persist slicing. No longer needed
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry:
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [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]
> Reorders and repurposes migrations (104–106), removes 107, updates
inflation/deflation thresholds, and aligns tests with the new behaviors.
>
> - **Migrations**:
> - **104**: Simplified to only reset `PhishingController.urlScanCache`;
adds error reporting for invalid state.
> - **105**: Now removes `RatesController` from
`engine.backgroundState`; no-ops if absent; standardized error handling.
> - **106**: Now cleans PPOM MMKV storage (`PPOMDB`); logic moved from
former `107`; returns unchanged state; error captured.
> - **Removed**: `107` migration and its tests.
> - **Index** (`migrations/index.ts`): Dropped `107` from
`migrationList`; changed inflate trigger to `> 106` and deflate on last
version `>= 106`.
> - **Tests**:
> - Updated/added tests for 104–106 reflecting new responsibilities and
error messages.
> - Adjusted async migration flow tests to new version thresholds;
removed old 107 tests; renamed for concision.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
a52e123. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Aslau Mario-Daniel <marioaslau@gmail.com>
## **Description** - Account group rows in settings view show tracked/total supported addresses labels show the appropriate CTA icon depending on tracked addresses - Account group modal spawnable via settings view show unsupported header/addresses remove unsupported account type banner/alert aways show headers (tracked/untracked/unsupported) ## **Changelog** CHANGELOG entry: show tracked/untracked in reward settings view ## **Related Issue** https://consensyssoftware.atlassian.net/browse/RWDS-769 ## **Screenshots/Recordings** <img width="920" height="1486" alt="image" src="https://github.com/user-attachments/assets/9187c873-f5d0-4d16-b2ce-c5b8351b5977" /> <img width="984" height="1724" alt="image" src="https://github.com/user-attachments/assets/96bb17ea-77d7-478d-b7be-bd6d6fe23eea" /> ## **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] > Adds tracked/total labels to account group rows, always shows tracked/untracked/unsupported sections in the opt-in modal, refines address processing and button logic, and updates tests/i18n accordingly. > > - **Rewards Settings UI**: > - Show tracked/total label via `strings('rewards.link_account_group.tracked_count')` in `RewardSettingsAccountGroup`. > - Contextual CTA icon (`check` when all tracked, `add` otherwise); disable link when no opted-out accounts. > - Minor layout tweaks; remove balance/Privacy Mode logic. > - **Opt-in Modal (`RewardOptInAccountGroupModal`)**: > - Refactor address flattening with wildcard/invalid-scope handling; treat `isSupported: undefined` as supported and filter EVM testnets. > - Always render section headers: `tracked`, `untracked`, and new `unsupported`; remove unsupported banner. > - Link button shows only when supported, untracked addresses exist; `onClose` triggers `navigation.goBack`. > - Update item testIDs to `flat-list-item-<address>-<scope>` and use `MultichainAddressRow` fields. > - **Account Group List**: > - Optimize `allAddresses` via `getAddressesForGroup`; provide `getItemType` to `FlashList`; header spacing tweaks; stable skeleton keys. > - **i18n**: > - Add `rewards.link_account_group.unsupported` and `rewards.link_account_group.tracked_count`. > - **Tests**: > - Large test updates to reflect new testIDs, sections, button states, loading, key extraction, item typing, and edge cases (wildcards, invalid scopes, missing data). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit ff4d9e9. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** This PR fixes the issue when the user selects a BTC network, it would switch the user to the first multichain account. <!-- 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: Changing networks to btc does not switch the selected account. ## **Related issues** Fixes: #22236 (comment) ## **Manual testing steps** ```gherkin Feature: network switching Scenario: user wants to change the network filter Given the user is using a multichain account When user selected the btc network Then the account does not change. ``` ## **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/ee43b688-8f64-4d16-bde9-b7efecef6cfe <!-- [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] > Stops auto-switching to a BTC account when toggling a popular BTC network; BTC address selection now only occurs during custom BTC network selection. > > - **Hooks (`useNetworkSelection.ts`)**: > - Remove Bitcoin-specific `Engine.setSelectedAddress` logic from `selectPopularNetwork`; keep BTC address handling only in `selectCustomNetwork`. > - Simplify `selectPopularNetwork` dependencies to exclude Bitcoin internals. > - **Tests (`useNetworkSelection.test.ts`)**: > - Delete test asserting BTC address is set on `selectPopularNetwork` for Bitcoin networks. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit b4746e4. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…unding fees and live data (#22229) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** Fixes bug where close position view showed incorrect receive amounts, sometimes displaying negative values when position value had dropped. Root causes: 1. Used stale position data from route params instead of live WebSocket updates 2. HyperLiquid's marginUsed already includes PnL, but code was double-counting 3. Recalculated PnL from prices, which missed accumulated funding fees 4. Timing mismatch between price updates and position updates Changes: - Add usePerpsLivePositions to subscribe to real-time position data - Use livePosition.marginUsed which already includes accumulated PnL and funding fees - Use livePosition.positionValue for fee calculations to keep margin and fees synchronized - Remove effectivePnL recalculation that missed funding fees - Round margin and fees separately before subtraction for transparent calculation - Update tests to reflect that marginUsed includes PnL from HyperLiquid Result: - Position card and close position view now show matching margin values - Funding fees correctly included in all calculations - No more incorrect negative receive amounts - Calculation transparency: displayed margin - displayed fees = displayed receive amount <!-- 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: https://consensyssoftware.atlassian.net/browse/TAT-1956 ## **Manual testing steps** ```gherkin Feature: Close Position Calculation with Funding Fees Scenario: Close position with accumulated funding fees shows correct receive amount Given I have an open position with the following details: | Coin | ETH | | Margin Used | $100 | | Unrealized PnL| -$5 | | Entry Price | $2000 | | Current Price | $2000 | When I navigate to the close position view And I view the close position summary Then the margin displayed should be "$100" And the receive amount should match "margin - fees" And the receive amount should be positive And the receive amount should not be negative or zero Scenario: Receive amount calculation matches visual breakdown Given I have an open position When I view the close position summary Then the displayed margin should be rounded to 2 decimals And the displayed fees should be rounded to 2 decimals And the receive amount should equal "rounded margin minus rounded fees" And the calculation should be transparent to the user ``` ## **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/29289663-7b77-45f7-8ff6-c48917e1e21a <!-- [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] > Close Position view now uses live position data (incl. funding fees) and computes receive amount as rounded margin minus rounded fees, with updated PnL/effective price logic and tests. > > - **Perps Close Position (UI)**: > - Subscribe to `usePerpsLivePositions` and derive `isLong`, `absSize`, `marginUsed`, and `unrealizedPnl` from live data. > - Rework P&L logic: `effectivePnL` uses live `pnl` for `market` orders; for `limit`, uses `limitPrice` (fallback `currentPrice`). > - Compute `positionValue` and `closingValue` with current/limit price in deps; remove ref-based price shortcuts. > - Recalculate `receiveAmount` as `(close% of marginUsed) - fees` with per-component rounding; update `Summary` `totalMargin` to `(close% of marginUsed)`. > - Pass `livePosition` to `handleClosePosition`; include updated `receivedAmount` and `realizedPnl` in params. > - Derive `unrealizedPnlPercent` by back-calculating initial margin from `marginUsed - pnl`. > - **Tests**: > - Mock `usePerpsLivePositions` and update expectations: receive = `marginUsed - fees`; PnL display uses live `unrealizedPnl`. > - Add price update sync test ensuring P&L/margin react to live price/position changes. > - Adjust confirmation assertions (e.g., `receivedAmount: 1405`) and various limit/market calculation cases. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 5c3d3be. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: abretonc7s <107169956+abretonc7s@users.noreply.github.com>
## **Description**
Users were reporting that the TabsBar component in the Wallet view was
not horizontally scrollable when tabs overflowed, particularly when
device font size settings were increased.
**Root causes identified:**
1. **Overflow detection didn't account for container padding** - The
component has `px-4` (32px total) padding, but the overflow calculation
compared total content width against the full container width, not the
available space minus padding.
2. **Underline positioning race condition** - With font scaling, layout
measurements would race with font rendering, causing the underline to
have inconsistent width/position on initial load.
3. **No dynamic recalculation** - When font size changed after initial
load, the overflow detection would not recalculate, leaving tabs
non-scrollable even when they overflowed.
**Solution:**
- Fixed overflow detection to account for container's 32px horizontal
padding in both calculation points
- Added layout change detection to re-animate underline when tabs resize
due to font scaling
- Implemented dynamic recalculation of scroll state when any tab's
layout changes significantly (>1px)
- Used refs to avoid circular dependencies and performance issues
## **Changelog**
CHANGELOG entry: Fixed TabsBar not being horizontally scrollable when
tabs overflow, especially with increased font size settings
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: TabsBar horizontal scrolling with increased font size
Scenario: user increases device font size with many tabs
Given user has multiple tabs visible in the Wallet view (Tokens, Perps, Predictions, NFTs)
And tabs fit within the screen width at default font size
When user increases device font size in Settings > Display & Brightness > Text Size
Then tabs should become horizontally scrollable
And the underline indicator should correctly match the width of active tab
And user should be able to swipe horizontally to see all tabs
Scenario: user views tabs with default font size
Given user has multiple tabs in the Wallet view
And device font size is at default setting
And tabs do not overflow the screen width
When user views the Wallet screen
Then tabs should not be scrollable
And all tabs should be visible without scrolling
And the underline should correctly align with active tab
Scenario: user switches between tabs after font size increase
Given user has increased device font size
And tabs are horizontally scrollable due to overflow
When user taps on a different tab or swipes to navigate
Then the underline should animate smoothly to the new tab
And the ScrollView should automatically scroll to show the active tab
And the underline width should match the tab width accurately
```
## **Screenshots/Recordings**
### **Before**
https://github.com/user-attachments/assets/3359232b-c54a-4d6b-9124-c6e194de7fc1
### **After**
https://github.com/user-attachments/assets/b83a5cc9-9232-4fb1-bbde-3e73d6c75332
## **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]
> Improves TabsBar by accounting for container padding in overflow
detection and re-animating the underline when tab layouts change (e.g.,
font scaling).
>
> - **TabsBar
(`app/component-library/components-temp/Tabs/TabsBar/TabsBar.tsx`)**
> - **Overflow detection**: Accounts for container padding (`-32px`)
when computing `shouldScroll`.
> - **Dynamic layout handling**:
> - Detects significant tab layout changes (>1px) and recalculates
scroll state.
> - Re-animates active tab underline via `requestAnimationFrame`; added
`activeIndexRef` to sync with `activeIndex`.
> - **Stability/cleanup**: Cancels in-flight animations and pending RAF
callbacks on updates/unmount.
> - **Deps**: Updates effect/callback deps to include `animateToTab`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f60d961. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…22291) ## **Description** Fixed Toast component theme not updating when switching between light and dark mode in production builds (TestFlight). The issue only affected production builds while working correctly in development/simulator. ### Root Cause: The Toast component had an empty dependency array `[]` in its `useMemo` hook (line 69), which cached the initial theme styles and never updated when the theme changed. This was a remnant from when Toast used inverse/hardcoded theming. ### Solution: Updated the `useMemo` dependency array to properly track `[styles.base, animatedStyle]`, ensuring the component re-renders with correct theme colors when theme changes occur. ## **Changelog** CHANGELOG entry: Fixed Toast component not updating theme colors when switching between light and dark mode ## **Related issues** Fixes: Theme change issue in Toast component ## **Manual testing steps** ```gherkin Feature: Toast theme updates correctly Scenario: User switches device theme while Toast is visible Given the app is running with a visible Toast notification When user switches from light mode to dark mode (or vice versa) in device settings Then the Toast should update to match the new theme colors immediately Scenario: Toast appears with correct theme in production build Given the app is running in a TestFlight production build And user has dark mode enabled When a Toast notification appears Then the Toast displays with correct dark theme colors (not stuck in light theme) ``` ## **Screenshots/Recordings** ### **Before** Toast remained in previous theme colors when device theme was changed in production builds. https://github.com/user-attachments/assets/d96faa41-10c3-4777-baf0-cb33ec137309 ### **After** Toast correctly updates to match current theme in both development and production builds. https://github.com/user-attachments/assets/aea3a725-0aa1-4412-bd56-5bde79fbfbbd ## **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] > Update `Toast` `baseStyle` `useMemo` to depend on `styles.base` and `animatedStyle` (and simplify its type) so styling updates correctly. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 1a4dca6. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…in-app browser) (#22012) ## **Description** Fixes: https://github.com/MetaMask/mobile-planning/issues/2341 This PR fixes an issue where MetaMask deeplinks clicked within the in-app browser or carousel banners were redirecting users to the app store instead of navigating internally within the app. ### Problem When users clicked MetaMask deeplinks (e.g., `https://link.metamask.io/swap`, `metamask://dapp/uniswap.org`) from within the app: - **In-App Browser**: Links would attempt to open the app externally, causing an app store redirect - **Carousel Banners**: Action links would trigger OS-level handling instead of internal navigation This occurred because these URLs were being passed to the OS linking system (`Linking.openURL()`), which would try to open MetaMask again, resulting in an app store redirect since the app was already running. ### Solution The fix intercepts MetaMask deeplinks and routes them through `SharedDeeplinkManager` for internal handling: 1. **Created utility function** (`isInternalDeepLink`) to identify MetaMask URLs that should be handled internally 2. **Updated BrowserTab** to intercept deeplinks in `onShouldStartLoadWithRequest` and use `browserCallBack` for in-browser navigation 3. **Updated Carousel** to differentiate between internal deeplinks and external URLs 4. **Added comprehensive unit tests** covering all deeplink types and edge cases The `browserCallBack` mechanism allows deeplinks that should stay in the browser (e.g., `dapp://` URLs) to navigate the current WebView tab, while other deeplinks (e.g., `swap`, `buy-crypto`) navigate to their respective app screens. ## **Changelog** CHANGELOG entry: Improve handling of links originating from in-app browser and carousel ## **Related issues** Fixes: #[ISSUE_NUMBER] ## **Manual testing steps** ```gherkin Feature: Internal deeplink handling in browser Scenario: user clicks MetaMask dapp deeplink in browser Given user has opened a website in the in-app browser And the website contains a link to "https://link.metamask.io/dapp/uniswap.org" When user taps the deeplink Then the current browser tab navigates to "https://uniswap.org" And the user remains in the browser (no app store redirect) Scenario: user clicks MetaMask feature deeplink in browser Given user has opened a website in the in-app browser And the website contains a link to "https://link.metamask.io/swap" When user taps the deeplink Then the app navigates to the Swap screen And the browser is exited Scenario: user clicks MetaMask deeplink in carousel Given user is viewing the wallet home screen And a carousel banner contains a MetaMask deeplink When user taps the carousel banner Then the app navigates to the appropriate feature screen And no app store redirect occurs Scenario: user clicks external link in browser Given user has opened a website in the in-app browser And the website contains a regular external link When user taps the external link Then the link behaves as normal (opens in browser or externally) Feature: Deeplink type detection Scenario: utility correctly identifies internal deeplinks Given various URL types are tested When "https://link.metamask.io/swap" is checked Then it is identified as internal deeplink When "metamask://dapp/uniswap.org" is checked Then it is identified as internal deeplink When "https://google.com" is checked Then it is identified as external URL ``` ### Additional Testing Steps: 1. **Browser Test Page**: Create an HTML page with test links covering: - Universal links: `https://link.metamask.io/dapp/uniswap.org` - Custom schemes: `metamask://dapp/app.aave.com`, `dapp://curve.fi` - Feature links: `https://link.metamask.io/swap`, `/buy-crypto`, `/home` - External links: `https://ethereum.org` (control group) 2. **Unit Tests**: Run `yarn jest app/util/deeplinks/index.test.ts` 3. **TypeScript**: Run `yarn lint:tsc` to verify type safety ## **Screenshots/Recordings** ### **Before** <!-- User clicks metamask deeplink in browser → App store opens (broken behavior) --> ### **After** <!-- User clicks metamask deeplink in browser → Navigates internally (fixed behavior) --> ## **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). - [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] > Intercept MetaMask deeplinks in the in-app browser and carousel to handle them via SharedDeeplinkManager while opening only external URLs with the OS; add isInternalDeepLink utility and tests. > > - **Deeplink handling**: > - Add `util/deeplinks/isInternalDeepLink` to detect MetaMask internal links (universal and custom schemes). > - In `BrowserTab`, intercept internal links in `onShouldStartLoadWithRequest` and route via `SharedDeeplinkManager.parse` with `origin: AppConstants.DEEPLINKS.ORIGIN_IN_APP_BROWSER` and `browserCallBack` support; block WebView load for these. > - In `Carousel`, differentiate links: internal via `SharedDeeplinkManager.parse` (`origin: ORIGIN_CAROUSEL`), external via `Linking.openURL`. > - Extend `AppConstants.DEEPLINKS` with `ORIGIN_CAROUSEL` and `ORIGIN_IN_APP_BROWSER`. > - **Tests**: > - Add `app/util/deeplinks/index.test.ts` covering schemes/hosts and edge cases. > - Update `Carousel` tests to assert external vs internal link behavior and correct origins; mock `Linking.openURL`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 924a4bc. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
….59.0 (#22288) ## **Description** The back arrow in `PerpsHomeScreen` was using `navigation.goBack()`, which would work correctly when navigating from Main wallet view → Perps Home → Main wallet view But when entering `PerpsHomeScreen` from another entry point, such as PerpsOnboarding, it would create a loop when navigating from Perps Tutorial → Perps Home (back arrow would return to tutorial) This PR fixes this by changing this to `navigateToWallet` which explicitly navigates to the wallet home screen as expected ## **Changelog** CHANGELOG entry: Fix navigation loop from PerpsHomeScreen ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TAT-1984 ## **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] > PerpsHomeView back arrow now always navigates to wallet home; tests updated to assert wallet navigation. > > - **UI/Perps**: > - `PerpsHomeView.tsx`: Change back handler from `navigateBack` to `navigateToWallet` to avoid navigation loops; keep search navigation via `navigateToMarketList`. > - **Tests**: > - `PerpsHomeView.test.tsx`: Update mocks and expectations to use `navigateToWallet` for back action; clear relevant mocks; retain existing behavior checks for sections and actions. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 3695aa8. 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 : )