[pull] main from MetaMask:main#319
Merged
Merged
Conversation
## **Description** Fix scrolling in the MetaMask Pay asset picker on Android. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: [#6147](MetaMask/MetaMask-planning#6147) ## **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] > Switches asset picker and network filter to use react-native-gesture-handler ScrollView to fix Android scrolling. > > - **Mobile UI**: > - Replace `react-native` `ScrollView` with `react-native-gesture-handler` in `app/components/Views/confirmations/components/network-filter/network-filter.tsx` and `app/components/Views/confirmations/components/send/asset/asset.tsx`. > - Minor `ScrollView` prop formatting cleanup in `asset.tsx`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit a7e0901. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Show additional details in Predict claim confirmation if single won position. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: [6004](MetaMask/MetaMask-planning#6004) ## **Manual testing steps** ## **Screenshots/Recordings** ### **Before** ### **After** <img width="300" alt="Claim Single" src="https://github.com/user-attachments/assets/088c99d2-d3b7-4852-9009-357ad4ccd546" /> ## **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] > Enhances Predict claim footer to display detailed info for a single win and refactors component structure with accompanying tests. > > - **Predict claim footer** (`predict-claim-footer.tsx`): > - Show single-win details: large token avatar, market title, formatted fiat amount, and outcome. > - Refactor into `SingleWin` and `MultipleWinnings` subcomponents; memoize fiat formatting; return null when no won positions. > - **Tests**: > - Add tests for single-win extra info, avatar count (max 3), button press, and fallback selected address. > - Update mocks/render helper to support `singlePosition` and `accountMock`. > - Remove predict-claim footer render check from generic `Footer` tests and drop unused `TransactionType` import. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 8073f69. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…22517) ## **Description** This PR fixes an issue in the Perps Market Tabs component where the TabsList wasn't properly re-rendering when the number of visible tabs changed. ## **Changelog** CHANGELOG entry: Fixed an issue where perps market tabs would not update correctly when the number of visible tabs changed ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TAT-1982 ## **Manual testing steps** ```gherkin Feature: Perps Market Tabs Rendering Scenario: user switches between market states that affect tab visibility Given user is on the perps market details view with active position When user closes their position or opens new positions Then the tabs should correctly update to reflect the current state (position tab should appear/disappear) And the active tab selection should remain consistent ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> No visible change ### **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] > Ensure `TabsList` remounts when the number of visible tabs changes by incorporating `tabsToRender.length` into the component key. > > - **Perps UI**: > - **Tabs re-rendering**: Update `tabsKey` in `PerpsMarketTabs.tsx` to `tabs-${tabs.length}-${tabsToRender.length}` so `TabsList` remounts when the visible tab count changes. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e03f2b2. 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?
-->
- Introduced PortManager to handle port allocation and release for
various servers.
- Updated Ganache, MockServerE2E, DappServer, CommandQueueServer,
FixtureServer, and AnvilManager to utilize PortManager for setting and
releasing ports.
- Added methods to set server ports and handle server status in
respective classes.
- Implemented retry logic for starting resources with automatic port
management to avoid conflicts.
- Updated FixtureUtils to include new port management functions and
ensure correct RPC URLs are used based on allocated ports.
- Update swaps tests to use Anvil (from ganache)
## **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
- [ ] 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 PortManager-driven dynamic port allocation with retries and
platform handling, refactors test servers/utilities to use it, migrates
swaps tests to Anvil, and standardizes “Network fee” casing.
>
> - **E2E Infra (Port Management)**:
> - Introduces `PortManager` for dynamic/random port allocation
(single/multi-instance), release, and BrowserStack fallbacks; adds
robust retry start helpers (`startResourceWithRetry`,
`startMultiInstanceResourceWithRetry`).
> - Implements Android `adb reverse` mapping, iOS LaunchArgs, and
MockServer host-side fallback→actual port translation.
> - **Server/Utility Refactors**:
> - Update `Ganache`, `AnvilManager`, `FixtureServer`,
`CommandQueueServer`, `DappServer`, `MockServerE2E` to `setServerPort`,
track status, and release ports; `DappServer` supports multi-instance.
> - Revamps `FixtureUtils`/`FixtureHelper` APIs (`getDappUrl*`,
`get*PortForFixture`, RPC/Dapp URL rewrites) and improves
network-store/shim host resolution.
> - **Tests**:
> - New comprehensive `PortManager.test.ts`.
> - Migrate swaps tests to Anvil; update fixtures and helpers to new
APIs; remove manual reverse logic.
> - **UX/Text**:
> - Standardize casing to `Network fee` across tests and
`locales/languages/en.json`.
> - **Misc**:
> - Adjust allowlist/mocks; minor README formatting.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f63e958. 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? --> ## **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 error message when trying to import an SRP with an account that is already imported via private key ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MUL-491 ## **Manual testing steps** 1. Import private key account 2. Import SRP that includes this private key account 3. Verify that the error message "The account you are trying to import is a duplicate." is shown ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <img width="925" height="903" alt="image" src="https://github.com/user-attachments/assets/77abb409-feac-4ba4-92bd-387d122928dd" /> ## **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 explicit handling and user-facing message when an SRP import fails due to a duplicate account, with tests and i18n updates. > > - **Import SRP View (`app/components/Views/ImportNewSecretRecoveryPhrase/index.tsx`)**: > - Refactor error handling to `switch` and add case for `KeyringController - The account you are trying to import is a duplicate`, showing `error_duplicate_account` alert. > - **Tests (`app/components/Views/ImportNewSecretRecoveryPhrase/index.test.tsx`)**: > - Add test to assert duplicate account import error triggers the correct alert. > - **Localization (`locales/languages/en.json`)**: > - Add `import_new_secret_recovery_phrase.error_duplicate_account` copy. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit f43d802. 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** As part of developing the "Trending" feature we needed to add a global search that would allow searching amongst trending tokens, perps, trending predictions... I have developed a MODULAR search hook and global search that allows searching across all existing sections and allows for easy integration of new sections. If a new section is added, the user will have to only modify the configuration in `exploreSearchConfig` like this: <img width="387" height="328" alt="image" src="https://github.com/user-attachments/assets/e00ce4fb-3831-422e-80a3-30d2436cddad" /> and add the necessary hook inside `useExplorerSearch`: <img width="416" height="449" alt="image" src="https://github.com/user-attachments/assets/78366050-4ab8-4859-ad09-095077be89cf" /> Everything else is handled automatically which makes it **easy** for developers to add new configurations <!-- 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: added new trending search functionality ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/ASSETS-1528 & https://consensyssoftware.atlassian.net/browse/ASSETS-1527 ## **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/d912d5d0-4cd1-45c9-8a94-459d437f03aa ## **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] > Introduces an Explore Search flow with a modular search hook, UI components, navigation, i18n, and tests, enabling search across tokens, perps, and predictions from the Trending tab. > > - **Trending / Explore Search**: > - **UI**: > - Add `ExploreSearchBar` and `ExploreSearchScreen` with `ExploreSearchResults` list (headers, items, skeletons). > - Integrate search entry in `TrendingView` (button + navigation), wrap with `PerpsStreamProvider`. > - **Hook & Config**: > - Add generic `useExploreSearch` (200ms debounce, top-3 on empty, per-section filtering). > - Define configurable sections in `exploreSearchConfig` for `tokens`, `perps`, `predictions` with item renderers and key extractors. > - **Navigation**: > - Add route `Routes.EXPLORE_SEARCH`; register in `TrendingView` stack; update imports in `MainNavigator`. > - **i18n**: > - Extend `trending` strings: `search_placeholder`, `perps`, `predictions`, `no_results`. > - **Tests**: > - Add tests for `ExploreSearchBar`, `ExploreSearchResults`, `useExploreSearch`, and update `TrendingView` tests for search button and navigation. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit b35671b. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** ### Summary Adds Segment analytics tracking for QR Scanner usage to measure feature adoption and understand user scanning patterns. ### Events Added - **QR Scanner Opened** - Tracks when QR scanner is opened with camera permission granted - **QR Scanned** - Tracks all QR code scan attempts with success/failure, type classification, and detailed scan results ### Properties **QR Scanned** includes: - `scan_success` (boolean) - Technical success: camera successfully read the QR code - `qr_type` (string) - Classification: `"seed phrase"` | `"private key"` | `"send flow"` | `"wallet connect"` | `"deeplink"` | `"url"` - `scan_result` (string) - Functional outcome: `"completed"` | `"deeplink_handled"` | `"url_navigation_confirmed"` | `"unrecognized_qr_code"` | `"invalid_address_format"` | `"url_navigation_cancelled"` | `"wallet_locked"` ### Use Cases - Measure scanner success rate (filter by `scan_result` to exclude failures) - Understand QR type distribution (`qr_type` breakdown) - Debug scan failures (`scan_result` analysis) - Improve UX by identifying common failure patterns - Track WalletConnect connection initiation via QR codes ### Implementation Details #### QR_SCANNER_OPENED - Fires once per scanner session when permission is granted and camera is available - Includes global properties only #### QR_SCANNED - Tracks all 6 QR code types with appropriate success/failure states: - Seed Phrase - Private Key - Send Flow - Wallet Connect - Deeplink - URL Segment PR: Consensys/segment-schema#360 ## **Changelog** CHANGELOG entry: Added segment events for QR scanning ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TMCU-66 ## **Manual testing steps** ```gherkin Feature: QR Scanner Metrics Tracking Scenario: QR Scanner Opened event fires when scanner is accessed Given the user is on the MetaMask Mobile homepage And camera permissions are granted When user taps the QR scanner icon Then the QR scanner opens And "QR Scanner Opened" event is tracked with no custom properties And the event appears in console logs and Segment debugger Scenario: user scans a seed phrase QR code Given the QR scanner is open And a QR code containing a 12-word seed phrase is displayed When user scans the seed phrase QR code Then "QR Scanned" event is tracked And scan_success property is true And qr_type property is "seed phrase" Scenario: user scans a private key QR code Given the QR scanner is open And a QR code containing "0x" followed by 64 hex characters is displayed When user scans the private key QR code Then "QR Scanned" event is tracked And scan_success property is true And qr_type property is "private key" Scenario: user scans a valid Ethereum address in send flow Given the user is in the Send Flow screen And user taps the QR scanner icon And a QR code containing a valid Ethereum address is displayed When user scans the address QR code Then "QR Scanned" event is tracked And scan_success property is true And qr_type property is "send flow" Scenario: user scans an invalid address in send flow Given the user is in the Send Flow screen And user taps the QR scanner icon And a QR code containing invalid address text is displayed When user scans the invalid QR code Then "QR Scanned" event is tracked And scan_success property is false And qr_type property is "send flow" And an error alert is displayed Scenario: user scans a WalletConnect URI Given the QR scanner is open And a QR code containing a WalletConnect URI (wc:...) is displayed When user scans the WalletConnect QR code Then "QR Scanned" event is tracked And scan_success property is true And qr_type property is "wallet connect" Scenario: user scans a MetaMask deeplink Given the QR scanner is open And a QR code containing "metamask-sdk://" or "metamask-sync:" is displayed When user scans the deeplink QR code Then "QR Scanned" event is tracked And scan_success property is true And qr_type property is "deeplink" Scenario: user scans a URL and confirms navigation Given the QR scanner is open And a QR code containing "https://example.com" is displayed When user scans the URL QR code And user taps "Continue" on the confirmation dialog Then "QR Scanned" event is tracked And scan_success property is true And qr_type property is "url" Scenario: user scans a URL and cancels navigation Given the QR scanner is open And a QR code containing "https://example.com" is displayed When user scans the URL QR code And user taps "Cancel" on the confirmation dialog Then "QR Scanned" event is tracked And scan_success property is false And qr_type property is "url" ``` ## **Screenshots/Recordings** ### Seed Phrase Flow https://github.com/user-attachments/assets/6f8357c3-f1e4-467b-8c6a-9188a71948f4 ### Private Key Flow https://github.com/user-attachments/assets/1ce6f4cf-62e7-4bde-bce5-8d14bf9fba50 ### Send Flow - Valid Address __Send flow is currently broken there is a PR [here](#21498) to fix the issue. The video is just a demonstration of the event being tracked__ https://github.com/user-attachments/assets/909d5687-9789-41b5-be45-4503a1bb0e53 ### Send Flow - Unknown Address https://github.com/user-attachments/assets/fd15c33c-e90a-4427-a7ed-684a741a075f ### Send Flow - Invalid Address https://github.com/user-attachments/assets/34f27530-b1d6-4035-9713-19955c501090 ### Wallet Connect https://github.com/user-attachments/assets/b41f9fcc-a6a1-4440-9bba-63be4305ad4e ### SDK ### Website - Accept https://github.com/user-attachments/assets/d7f00d09-a03a-4e6c-9056-99575ed2302d ### Website - Cancel https://github.com/user-attachments/assets/2c3d9cff-36cd-475c-958e-e16034030e46 ### **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** - [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 MetaMetrics tracking for QR Scanner open/scan with standardized properties and QR type detection, plus comprehensive tests and event definitions. > > - **Analytics**: > - Add `QR_SCANNER_OPENED` and `QR_SCANNED` to `core/Analytics/MetaMetrics.events.ts`. > - Track scanner open when permission granted and camera available. > - Track scans with properties: `scan_success`, `qr_type`, `scan_result` across types (`seed phrase`, `private key`, `send flow`, `wallet connect`, `deeplink`, `url`), including outcomes (e.g., URL confirm/cancel, wallet locked, invalid address, deeplink handled). > - **QR Scanner**: > - New `app/components/Views/QRScanner/constants.ts` for event keys, QR types, and scan result values. > - New `getQRType` in `app/components/Views/QRScanner/utils.ts` to classify scanned content. > - Update `app/components/Views/QRScanner/index.tsx` to emit events, handle URL redirection flow, SDK/deeplink handling, and wallet-locked checks; minor typing/refactors. > - **Tests**: > - Expand `index.test.tsx` to validate event emission for all paths. > - Add `utils.test.ts` to verify `getQRType` classification logic. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e419028. 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 enables live PnL (Profit and Loss) updates in the Perps Market Tabs by subscribing to real-time price updates from the WebSocket stream. ## **Changelog** CHANGELOG entry: Fixed live PnL updates in Perps market tabs to reflect real-time price changes ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TAT-1946 ## **Manual testing steps** ```gherkin Feature: Live PnL updates in Perps Market Tabs Scenario: user views position with live PnL updates Given user has an open perpetual position And user is on the Perps Market Tabs screen When market price changes Then the unrealized PnL and ROE values update in real-time And the position card reflects current market conditions ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** No visible changes ### **After** No visible 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] > Enable live PnL updates by passing `useLivePnl: true` to `usePerpsLivePositions` in `PerpsMarketTabs.tsx`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 32657d9. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Nicholas Smith <nick.smith@consensys.net>
<!-- 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 introduces **AppStateAPI**, a new centralized API for monitoring React Native app state changes (foreground/background/inactive) and managing lock timers. ### **Reason for the change** Currently, app state monitoring is scattered across the codebase with direct React Native `AppState` imports in multiple components. This creates tight coupling and makes it difficult to: - Track which components are monitoring app state - Test app state behavior consistently - Manage lock timers in a centralized way - Ensure proper cleanup of native listeners ### **The improvement/solution** **AppStateAPI** provides a clean, singleton-based API with the following benefits: 1. **Centralized Monitoring**: Single source of truth for app state changes 2. **EventEmitter Pattern**: Components can subscribe to specific events (`foreground`, `background`, `inactive`, `change`) without tight coupling 3. **Separation of Concerns**: The API only monitors and emits events—it does NOT perform locking. State machines/sagas handle actual locking logic 4. **Lock Timer Management**: Built-in timer functionality for auto-lock features with background timer support 5. **Clean Lifecycle**: Explicit `initialize()` and `cleanup()` methods with proper native listener management 6. **Type Safety**: Full TypeScript implementation with exported types ### **Key Features** - **App State Events**: `foreground`, `background`, `inactive`, `change` - **Lock Timer**: `startLockTimer(duration, callback)`, `clearLockTimer()`, `getLockTimerRemaining()`, `isLockTimerActive()` - **State Queries**: `getCurrentAppState()`, `isAppInForeground()`, `isAppInBackground()`, `isAppInactive()` - **Lifecycle**: `initialize()`, `cleanup()`, `isInitialized()` ### **Architecture Summary** | Component | Status | Lines | Purpose | |------------------------|--------|-------|----------------------------------| | AppStateAPI | ✅ New | 267 | Monitor app state & lock timers | | Authentication.ts | ✅ Existing | 1230 | Keep using (works well) | | State Machines (Sagas) | 🔄 Update | 234 | Will use AppStateAPI events | | LockManagerService |⚠️ Deprecate | 122 | Gradually migrate away | This PR includes debug instrumentation in `Root/index.tsx` for manual testing (dev mode only). ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: [Add issue number here] ## **Manual testing steps** ```gherkin Feature: AppStateAPI monitors app state changes Scenario: Developer tests app state monitoring in development mode Given the app is running in development mode And AppStateAPI is initialized in Root component When the app is launched Then console logs should show "APPSTATEAPI: 🔵 Initializing AppStateAPI for manual testing" And console logs should show "APPSTATEAPI: 🔵 Starting 10-second lock timer" And console logs should display current app state as "active" Scenario: Developer backgrounds the app Given the app is running in foreground And AppStateAPI is initialized When the developer backgrounds the app Then console logs should show "APPSTATEAPI: 🔴 App BACKGROUNDED" And the background event should be emitted with state "background" Scenario: Developer foregrounds the app Given the app is running in background And AppStateAPI is initialized When the developer brings the app to foreground Then console logs should show "APPSTATEAPI: 🟢 App FOREGROUNDED" And the foreground event should be emitted with state "active" Scenario: Lock timer expires while app is backgrounded Given the app is running And a 10-second lock timer has been started When the developer backgrounds the app for more than 10 seconds Then console logs should show "APPSTATEAPI: ⏰ Lock timer EXPIRED" And the timer callback should be invoked Scenario: Developer checks AppStateAPI state queries Given the app is running And AppStateAPI is initialized When the developer views the console logs Then logs should show "Is in foreground?" with a boolean value And logs should show "Lock timer active?" with a boolean value And logs should show the current app state Scenario: AppStateAPI cleanup on unmount Given the app is running with AppStateAPI initialized When the Root component unmounts Then console logs should show "Cleaning up AppStateAPI" And all event listeners should be removed And lock timers should be cleared ``` ## **Screenshots/Recordings** https://github.com/user-attachments/assets/b9dfe51e-9ab9-45cc-802d-7f5fd9281c38 ### **Before** No centralized app state monitoring—components directly import `AppState` from React Native. ### **After** New `AppStateAPI` provides centralized monitoring with console output in dev mode: <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Introduce a singleton AppState service that emits app state events and manages a lock timer, with comprehensive tests and exports. > > - **Core**: > - **`app/core/AppStateService/AppStateService.ts`**: New singleton `AppStateServiceImplementation` (EventEmitter-based) to monitor React Native `AppState` and emit `foreground`, `background`, `inactive`, and `change` events. > - Provides lifecycle methods: `initialize()`, `cleanup()`, `isInitialized()`. > - Adds lock timer utilities: `startLockTimer()`, `clearLockTimer()`, `getLockTimerRemaining()`, `isLockTimerActive()` using `react-native-background-timer`. > - Exports singleton `AppStateService` and `AppStateStatus` type. > - **Exports**: > - **`app/core/AppStateService/index.ts`**: Re-exports service, implementation, and types. > - **Tests**: > - **`app/core/AppStateService/AppStateService.test.ts`**: Comprehensive unit tests mocking React Native and background timer to verify initialization/cleanup, event emissions, lock timer behavior, and state query helpers. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 574d3df. 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**
Current BUGBOT rules and are too verbose and don't consistently run in
the pipeline without manual intervention. This change updates the file
structure as per the Cursor docs and simplifies the rule.
1. Changes BUGBOT file location for more consistent ci running
2. Replaces verbose rules with simple rules and adds markdown links so
Cursor can read them.
<!--
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?
3. 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**
This test fork repo shows the rule now hits every Unit Test violation in
the Unit Testing Guidelines. Including
Test naming violations
AAA pattern violations
TypeScript type violations
Import/require violations
Test isolation violations
Assertion quality violations
Test complexity violations
https://github.com/michaelmccallam/metamask-mobileBugbotTest/pull/6/files
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
Didn't pick up on the rules consistently
<!-- [screenshots/recordings] -->
### **After**
Now picks up on each rule in the Unit Testing Guidelines and calls it
out in the comments.
<img width="730" height="441" alt="Screenshot 2025-11-08 at 09 50 23"
src="https://github.com/user-attachments/assets/ffd7a768-d012-49ae-92ec-e05a67266c5e"
/>
<!-- [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
- [ ] 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]
> Moves BUGBOT rules to `.cursor/BUGBOT.md` and streamlines content,
updating test file pattern and guideline link.
>
> - **BUGBOT rules**:
> - **Relocation**: Move from `.cursor/rules/BUGBOT.md` to
`.cursor/BUGBOT.md`.
> - **Simplification**: Replace verbose rule set with concise core
mission and minimal execution protocol.
> - **Testing pattern**: Update naming pattern to
``*.test.{ts,tsx,js,jsx}``.
> - **Guidelines link**: Reference `rules/unit-testing-guidelines.mdc`
from new location.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
6949b1f. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
# Predict Buy: Rewards Display and Fee Consolidation ## Overview This PR adds rewards point estimation and consolidates fee display in the Predict Buy confirmation screen. Users can now see estimated MetaMask Rewards points they'll earn from their transaction, and view detailed fee breakdowns through an intuitive bottom sheet. CHANGELOG entry: null https://github.com/user-attachments/assets/cf20a4e3-1375-4f9b-97ff-c75a3d68f737 ## Changes ### 🎁 Rewards Integration - **Added "Est. points" row** to the Predict Buy confirmation screen - Displays estimated rewards points based on MetaMask fee - **Calculation**: `Math.round(metamaskFee * 100)` (1 point per cent spent on MM fee) - Position: Last row after "Total" - White text with gray info icon for consistency - Reuses `RewardsAnimations` component from Swap/Bridge features - Conditional display based on `rewardsEnabled` feature flag and transaction amount ### 💰 Fee Display Consolidation - **Consolidated two fee rows into single "Fees" row** - Previously: Separate "Provider fee" and "MetaMask fee" rows - Now: Single "Fees" row showing sum of both fees - Added gray info icon that opens detailed breakdown - **New Fee Breakdown Bottom Sheet** (`PredictFeeBreakdownSheet`) - Displays individual fee breakdown: - Polymarket fee (provider fee) - MetaMask fee - Opens when user taps info icon next to "Fees" - Closes without navigating back (uses `shouldNavigateBack={false}`) ### 🎨 UI/UX Improvements - **Fee Summary Row Order**: 1. Fees (consolidated, with info icon) 2. Total 3. Est. points (when rewards enabled) - **Styling**: - Est. points text: White (`TextColor.Default`) - Info icons: Gray (`IconColor.Alternative`) - Consistent with design system ## Technical Details ### Files Modified #### Components - **`PredictBuyPreview.tsx`** - Import `selectRewardsEnabledFlag` selector - Calculate `estimatedPoints` from `metamaskFee` - Add `isFeeBreakdownVisible` state - Add `handleFeesInfoPress` and `handleFeeBreakdownClose` callbacks - Pass rewards props to `PredictFeeSummary` - Conditionally render `PredictFeeBreakdownSheet` - **`PredictFeeSummary.tsx`** - Remove individual fee rows - Add consolidated "Fees" row with `ButtonIcon` - Calculate `totalFees = providerFee + metamaskFee` - Move rewards row to last position (after Total) - Update text colors (white for Est. points label) - Add `onFeesInfoPress` callback prop #### New Files - **`PredictFeeBreakdownSheet.tsx`** - Bottom sheet component for fee breakdown - Displays provider and MetaMask fees separately - Uses `shouldNavigateBack={false}` to prevent parent modal closure - Accepts `onClose` callback - **`PredictFeeBreakdownSheet/index.ts`** - Export file for new component #### Localization - **`locales/languages/en.json`** ```json { "predict.fee_summary.fees": "Fees", "predict.fee_summary.provider_fee_label": "Polymarket fee", "predict.fee_summary.estimated_points": "Est. points", "predict.fee_summary.points_tooltip": "Points", "predict.fee_summary.points_tooltip_content_1": "Points are how you earn MetaMask Rewards for completing transactions, like when you swap, bridge, or predict.", "predict.fee_summary.points_tooltip_content_2": "Keep in mind this value is an estimate and will be finalized once the transaction is complete. Points can take up to 1 hour to be confirmed in your Rewards balance." } ``` ### Tests #### New Tests (22 total) - **`PredictFeeSummary.test.tsx`** (12 tests) - Consolidated fees display and calculation - Fees info icon callback handling - Rewards row conditional rendering - Rewards row positioning - Edge cases (zero fees, missing callbacks) - **`PredictFeeBreakdownSheet.test.tsx`** (10 tests - New file) - Bottom sheet rendering - Fee display (Polymarket and MetaMask) - `shouldNavigateBack` behavior - Close callback handling - Ref methods exposure - **`PredictBuyPreview.test.tsx`** (10 new tests) - Rewards calculation formula - Rewards point rounding - Feature flag conditional display - Fee breakdown sheet visibility - Loading state propagation #### Updated Tests (1) - Fixed existing test to expect "Fees" instead of "Provider fee" **Total Test Results**: 2,038 tests passing ✅ ## Rewards Calculation Logic ```typescript // Formula: 1 point per cent spent on MetaMask fee const estimatedPoints = useMemo( () => Math.round(metamaskFee * 100), [metamaskFee], ); // Display conditions const shouldShowRewards = rewardsEnabled && currentValue > 0; ``` ### Examples: - MetaMask fee: $0.50 → **50 points** - MetaMask fee: $1.23 → **123 points** - MetaMask fee: $0.00 → **0 points** ## Component Reusability This implementation reuses existing components: - ✅ `RewardsAnimations` (from Bridge/Swap) - ✅ `KeyValueRow` (component library) - ✅ `ButtonIcon` (design system) - ✅ `BottomSheet` (design system) - ✅ Design system tokens (`TextColor`, `IconColor`) ## Feature Flags - **Rewards display**: Controlled by `selectRewardsEnabledFlag` - **Fee breakdown**: Always available ## Testing Checklist - [x] Unit tests for all new components - [x] Unit tests for modified components - [x] All existing tests passing (2,038 tests) - [x] No linter errors - [x] Tests follow AAA pattern - [x] Tests follow project guidelines (no "should" in names) - [x] Edge cases covered (zero values, missing callbacks, etc.) ## Manual Testing ### Test Scenarios 1. **Rewards Display** - [ ] Verify Est. points row appears when rewards enabled - [ ] Verify points calculation: fee * 100 rounded - [ ] Verify Est. points row does NOT appear when rewards disabled - [ ] Verify Est. points row does NOT appear when amount is 0 2. **Fee Consolidation** - [ ] Verify single "Fees" row shows sum of provider + MetaMask fees - [ ] Verify info icon appears next to "Fees" label - [ ] Verify tapping info icon opens bottom sheet - [ ] Verify bottom sheet shows individual fee breakdown 3. **Bottom Sheet Behavior** - [ ] Verify bottom sheet displays "Polymarket fee" and "MetaMask fee" - [ ] Verify closing bottom sheet does NOT close parent modal - [ ] Verify bottom sheet closes on swipe down - [ ] Verify bottom sheet closes on backdrop tap 4. **Visual/Styling** - [ ] Verify Est. points text is white - [ ] Verify all info icons are gray - [ ] Verify row order: Fees → Total → Est. points - [ ] Verify layout on different screen sizes ## Before/After ### Before ``` Provider fee $0.10 MetaMask fee $0.04 Total $10.14 ``` ### After ``` Fees [i] $0.14 ← Tappable info icon Total $10.14 Est. points [i] 14 ← New rewards row (white text) ``` ### Fee Breakdown Sheet (when tapping [i]) ``` ╔════════════════════════╗ ║ Fees ║ ╠════════════════════════╣ ║ Polymarket fee $0.10 ║ ║ MetaMask fee $0.04 ║ ╚════════════════════════╝ ``` ## Commit History 1. `feat: Add rewards row to Predict Buy confirmation screen` - Initial rewards implementation 2. `refactor: Consolidate fee rows and add breakdown sheet` - Fee consolidation 3. `refactor: Move Est. points row to end and use white text` - Final positioning and styling 4. `test: Add comprehensive tests for rewards and fee breakdown features` - Complete test coverage ## Related Issues/PRs - Related to rewards feature integration - Consistent with Swap/Bridge rewards display patterns ## Checklist - [x] Code follows project coding guidelines - [x] Code follows React Native UI development guidelines - [x] Used design system components (`@metamask/design-system-react-native`) - [x] Used Tailwind CSS with `useTailwind()` hook - [x] No StyleSheet.create() used - [x] Proper TypeScript types (no `any`) - [x] Comprehensive unit tests added - [x] All tests passing - [x] No linter errors - [x] Localization strings added - [x] Feature flag integrated - [x] Component reusability maintained - [x] Follows AAA test pattern - [x] No breaking changes <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds rewards point estimation and consolidates fee display with a tappable fees breakdown sheet in Predict Buy. > > - **Predict UI**: > - `PredictFeeSummary`: Replace separate fee rows with a single "Fees" row (info icon), display total fees, and add "Est. points" row using `RewardsAnimations`. > - `PredictBuyPreview`: Compute `estimatedPoints = Math.round(metamaskFee * 100)`, gate rewards by `selectRewardsEnabledFlag`, and open fee breakdown via `onFeesInfoPress`; pass rewards/fees props. > - **New Component**: > - `PredictFeeBreakdownSheet`: Bottom sheet showing per-fee breakdown (`Polymarket fee`, `MetaMask fee`), `shouldNavigateBack=false`, `onClose` support. > - **Localization**: > - Add strings for `predict.fee_summary.fees`, `provider_fee_label`, `estimated_points`, points tooltips/error content. > - **Tests**: > - Add tests for `PredictFeeBreakdownSheet` and rewards/fees behavior; update existing expectations from "Provider fee" to "Fees". > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 01962c5. 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**
Adds the Tron network to swaps/bridge.
<!--
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: added Tron network support in swaps
## **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]
> Adds Tron support to swaps and bridge, filters non‑tradable Tron
tokens, updates fee/status handling, defaults, and dependencies.
>
> - **Bridge/Swaps Integration**
> - Allow `TrxScope.Mainnet` in swaps (`isSwapsAllowed`) and bridge
(`ALLOWED_BRIDGE_CHAIN_IDS`, network name map).
> - Add Tron default swap token (`USDT` TRC20) in
`default-swap-dest-tokens.ts` and BIP44 pairs.
> - **Token Handling**
> - New `isTradableToken` utility to exclude Tron resource tokens
(`Energy`, `Bandwidth`, `Max Bandwidth`).
> - `useTokens` now filters non‑tradable tokens, normalizes non‑EVM
addresses, and improves deduping/exclusions.
> - **UI/Logic**
> - `TransactionDetails`: safer multichain fee sum (handles partially
fungible fees) and unified status selection.
> - Asset utils: mark Solana/Tron assets as swaps‑allowed.
> - **Tests**
> - Extensive tests for non‑EVM normalization, Tron token filtering,
deduplication, and edge cases.
> - **Dependencies**
> - Bump `@metamask/bridge-controller` and
`@metamask/bridge-status-controller` to `^60.1.0`;
`@metamask/tron-wallet-snap` to `^1.7.x` (lockfile updated).
> - **Docs**
> - Minor README fixes (overlay usage, sample E2E notes).
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b88a55b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: GeorgeGkas <georgegkas@gmail.com>
…#22173) ## **Description** Removed `Text` component wrappers from `BottomSheetHeader` children across the codebase to ensure consistency with the new API pattern where `BottomSheetHeader` handles text styling internally. This refactoring removes redundant `Text` components that were wrapping string content inside `BottomSheetHeader`. The `BottomSheetHeader` component now handles the text styling directly, ensuring a consistent appearance across all bottom sheet headers in the app. ## **Changelog** CHANGELOG entry: null ## **Related issues** Part of: https://consensyssoftware.atlassian.net/browse/MDP-343 ## **Manual testing steps** ```gherkin Feature: Bottom Sheet Headers Display Correctly Scenario: user views various bottom sheets with headers Given the app is running When user opens any bottom sheet modal with a header (e.g., network selector, payment method selector, region selector, account permissions, etc.) Then the header text should display correctly with proper styling And the header should be visually consistent with other bottom sheet headers ``` ## **Screenshots/Recordings** ### **Before** N/A - Internal refactoring, no visual changes. We can trust the component to handle styling correctly. ### **After** N/A - Internal refactoring, no visual changes. We can trust the component to handle styling correctly. ## **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. --- ### **Changes Summary** **11 component files updated:** - NetworkSettings/index.js (4 instances) - NetworkListBottomSheet.tsx - TooltipModal/index.tsx - AccountPermissionsConfirmRevokeAll.tsx - NetworkSelector/NetworkSelector.tsx - RpcSelectionModal/RpcSelectionModal.tsx - NetworkManager/index.tsx - PermittedNetworksInfoSheet.tsx - ConnectionDetails/ConnectionDetails.tsx - RegionSelectorModal/RegionSelectorModal.tsx - PaymentMethodSelectorModal.tsx **5 test snapshots updated:** - RegionSelectorModal (8 snapshots) - PaymentMethodSelectorModal (1 snapshot) - AccountPermissionsConfirmRevokeAll (1 snapshot) - ConnectionDetails (1 snapshot) - PermittedNetworksInfoSheet (1 snapshot) **Total:** 16 files changed, 54 insertions(+), 60 deletions(-) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Refactors BottomSheetHeader to take raw string children across modals/selectors and updates tests/snapshots and small header style expectations. > > - **UI/BottomSheetHeader refactor**: > - Replace `<Text>` wrappers with raw string children in `BottomSheetHeader` across: > - Bridge: `BlockaidModal`, `BridgeNetworkSelectorBase`, `BridgeTokenSelectorBase`, `QuoteExpiredModal`, `SlippageModal`, `TransactionDetails/BlockExplorersModal`. > - Ramp (Deposit): `PaymentMethodSelectorModal`, `RegionSelectorModal`. > - Account Permissions: `AccountPermissionsConfirmRevokeAll`, `ConnectionDetails`, `PermittedNetworksInfoSheet`. > - Networks: `NetworkManager`, `AddAsset/NetworkListBottomSheet`, `NetworkSelector`. > - Misc: `TooltipModal`. > - **Tests/Snapshots**: > - Update snapshots to new header structure: add `testID="header-title"`, center text, and expect fontSize 16. > - Adjust NetworkManager tests to assert `testID="header"` instead of mocked header ID; extend icon mocks. > - **Styles**: > - Remove unused `heading` style in `NetworkSettings` styles; align header typography via `BottomSheetHeader`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit ddcd7e7. 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 is to set up EAS updates. Same as: #17431. Trying to merge it in again. It was reverted due to Android e2e fails. I applied this expo patch to fix it: #22506 <!-- 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: Added EAS updates initial setup ## **Related issues** Fixes: ## **Manual testing steps** ## **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] > Adds EAS OTA updates: central version/config, build-time channel injection for iOS/Android, UI debug info, test mocks, and required deps/patches. > > - **OTA Infrastructure**: > - Add `ota.config.js` (single source for `OTA_VERSION`, `RUNTIME_VERSION`, `PROJECT_ID`, `UPDATE_URL`) and re-export via `app/constants/ota.ts` (adds `getFullVersion`). > - Configure Expo in `app.config.js` with `expo.updates.url`, runtime version, request headers; set Hermes on iOS. > - Import `expo-asset` in `index.js` to resolve OTA-bundled assets. > - **Build/CI**: > - New `scripts/update-expo-channel.js` injects channel/runtime/URL and enable flags into Android `AndroidManifest.xml` and iOS `ios/Expo.plist`; invoked from `scripts/build.sh`. > - Register `scripts/update-expo-channel.js` in `.github/CODEOWNERS` and add `EXPO_PROJECT_ID` to `.js.env.example`. > - **iOS**: > - Add `ios/Expo.plist` and include in Xcode project; enable Hermes in `Podfile` and properties; bring in `EXUpdates` (+ related pods) in `Podfile.lock`. > - **Android**: > - Apply Yarn patch to `expo-updates` (removes Android test preload hook) via `.yarn/patches/...`. > - **App UI**: > - Enhance Settings > App Information to display OTA status (enabled, project/update IDs, channel, runtime version, status) and show full version with OTA suffix. > - **Testing**: > - Add `app/__mocks__/expo-updates.ts` and Jest mapper for `expo-updates`. > - **Selectors**: > - Make `accounts` selectors null-safe with defaults. > - **Dependencies**: > - Add `expo-asset`, `expo-updates` (patched) and related Yarn/CocoaPods updates. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit c2b1284. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
# Predict GTM (Go-To-Market) Modal ## Overview This PR implements a marketing announcement modal for the Predict feature, similar to the existing Perps GTM Modal. The modal appears once after user login when both the Predict feature and the GTM modal feature flags are enabled. CHANGELOG entry: null ## Screenshots <img width="720" height="460" alt="image" src="https://github.com/user-attachments/assets/96ee0747-cd2e-4062-b210-f4fe283a8a5b" /> ## Changes ### New Components - **`PredictGTMModal`** (`app/components/UI/Predict/components/PredictGTMModal/`) - Full-screen modal with custom background image - Title: "PREDICT AND WIN" - Description: "Trade on the outcome of real-world events, like sports or elections." - Two action buttons: "Get started" (primary) and "Not now" (secondary) - Responsive styling with proper scaling across different screen sizes ### Navigation Updates - **`app/components/UI/Predict/routes/index.tsx`** - Added `PredictGTMModal` to the `PredictModalStack` - Integrated modal stack into `PredictScreenStack` at `Routes.PREDICT.MODALS.ROOT` - Follows the same pattern as Perps navigation structure - **`app/components/Views/Wallet/index.tsx`** - Added `checkAndNavigateToPredictGTM` function to trigger modal on login - Modal only shows once per app session (tracked via storage flag) - Conditionally triggered based on feature flags ### Storage & Analytics - **`app/constants/storage.ts`** - Added `PREDICT_GTM_MODAL_SHOWN` constant for persistence - **`app/components/UI/Predict/constants/eventNames.ts`** - Added analytics event constants: - `PREDICT_GTM_WHATS_NEW_MODAL` - `PREDICT_GTM_MODAL_ENGAGE` (for "Get started") - `PREDICT_GTM_MODAL_DECLINE` (for "Not now") ### Feature Flags - **`app/components/UI/Predict/selectors/featureFlags/index.ts`** - Added `selectPredictGtmOnboardingModalEnabledFlag` selector - Checks both local env var (`MM_PREDICT_GTM_MODAL_ENABLED`) and remote feature flag ### Localization - **`locales/languages/en.json`** - Added `predict.gtm_content` strings: - `title`: "PREDICT AND WIN" - `title_description`: "Trade on the outcome of real-world events, like sports or elections." - `get_started`: "Get started" - `not_now`: "Not now" ### Assets - **`app/images/predict-marketing.png`** - Background image for the modal - Full-screen background with character and "Yes/No" buttons design ## Design Details ### Colors - Title & Description: `theme.colors.accent02.light` (light purple #EAC2FF) - "Get started" button: White background with dark text - "Not now" button: Transparent background with white text ### Typography - **Title**: MM Poly font, 400 weight, 50px size, 100% line height, center aligned - **Description**: System default font, 500 weight, 16px size, 24px line height, center aligned ### Background Image - Sized proportionally to screen dimensions (1.07x width, 1.12x height) - Ensures full edge-to-edge coverage across all device sizes ## Navigation Flow ### Modal Trigger 1. User logs in to the app 2. Wallet screen checks if Predict and GTM modal flags are enabled 3. If flags are enabled and modal hasn't been shown before, navigate to modal ### User Actions **"Get started" button:** 1. Tracks analytics event (`PREDICT_GTM_MODAL_ENGAGE`) 2. Sets storage flag to prevent re-showing 3. Navigates to Wallet Home 4. Navigates to Predict Market List (feed) 5. Result: User lands on Predict feed with Wallet in back stack **"Not now" button:** 1. Tracks analytics event (`PREDICT_GTM_MODAL_DECLINE`) 2. Sets storage flag to prevent re-showing 3. Navigates back to Wallet Home ### Back Navigation - From Predict feed: Returns to Wallet (modal is dismissed) - Modal never reappears in the same app session (tracked via storage + useRef) ## Feature Flags ### Required Flags 1. **`selectPredictEnabledFlag`** - Enables the entire Predict feature 2. **`selectPredictGtmOnboardingModalEnabledFlag`** - Enables the GTM modal specifically ### Environment Variables - `MM_PREDICT_GTM_MODAL_ENABLED=true` - Local override for modal flag ## Testing ### Manual Testing 1. Enable feature flags (set both to `true` in selectors for testing) 2. Clear app storage or use a fresh install 3. Log in to the app 4. Modal should appear automatically 5. Test "Get started" → should navigate to Predict feed 6. Go back → should return to Wallet (not modal) 7. Restart app → modal should NOT appear again ### Test Different Screen Sizes The modal uses responsive scaling. Test on: - iPhone SE (small) - iPhone 14 (medium) - iPhone 14 Pro Max (large) ### Storage Reset (for testing) To reset and see the modal again during testing: ```javascript // In React Native Debugger console or via code import StorageWrapper from './store/storage-wrapper'; await StorageWrapper.removeItem('@MetaMask:predictGTMModalShown'); ``` ## Analytics Events All events use `MetaMetricsEvents.WHATS_NEW_LINK_CLICKED` with properties: - `feature`: `'predict-gtm-whats-new-modal'` - `action`: `'engage'` (Get started) or `'decline'` (Not now) - Device metadata included via `generateDeviceAnalyticsMetaData()` ## Files Changed ### New Files - `app/components/UI/Predict/components/PredictGTMModal/PredictGTMModal.tsx` - `app/components/UI/Predict/components/PredictGTMModal/PredictGTMModal.styles.ts` - `app/components/UI/Predict/components/PredictGTMModal/index.ts` - `app/images/predict-marketing.png` ### Modified Files - `app/components/UI/Predict/routes/index.tsx` - `app/components/Views/Wallet/index.tsx` - `app/constants/storage.ts` - `app/components/UI/Predict/constants/eventNames.ts` - `app/components/UI/Predict/selectors/featureFlags/index.ts` - `locales/languages/en.json` ## Architecture Notes ### Pattern Consistency This implementation follows the exact same pattern as the Perps GTM Modal: - Modal stack structure - Feature flag logic - Storage tracking - Analytics events - Navigation behavior ### One-Time Display Logic The modal shows only once per app session using: 1. **Storage flag** (`PREDICT_GTM_MODAL_SHOWN`) - Persists across app restarts 2. **useRef guard** in Wallet component - Prevents re-triggering during navigation ### Navigation Strategy Uses two separate `navigate()` calls (not `CommonActions.reset()`) to: - Preserve navigation history - Maintain tab state - Work correctly with deep links - Match Perps implementation ## Future Enhancements Potential improvements for future PRs: - Add unit tests for `PredictGTMModal` component - Add integration tests for navigation flow - Support for dynamic content via remote config - A/B testing variants - Localization for additional languages ## Related Issues _Link to related Jira tickets or GitHub issues_ ## Checklist - [x] Component follows MetaMask Mobile design system patterns - [x] Responsive design tested on multiple screen sizes - [x] Analytics events properly tracked - [x] Storage flag prevents re-showing - [x] Navigation behavior matches Perps pattern - [x] Feature flags implemented correctly - [x] Localization strings added - [x] No linter errors - [ ] Unit tests added (future enhancement) - [ ] Integration tests added (future enhancement) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Introduces a full-screen Predict GTM modal shown once via feature flags, wired into navigation, storage, analytics, and covered by unit tests. > > - **Predict GTM Modal**: > - Adds `PredictGTMModal` component with responsive styles and background image (`PredictGTMModal.tsx/.styles.ts`, `index.ts`). > - Tracks engage/decline with `MetaMetricsEvents.WHATS_NEW_LINK_CLICKED` and new constants. > - Sets `PREDICT_GTM_MODAL_SHOWN` to prevent re-showing; navigates to `Wallet` and Predict feed. > - **Navigation**: > - Registers modal in Predict modal stack (`routes/index.tsx`) and adds route `Routes.PREDICT.MODALS.GTM_MODAL`. > - **Wallet behavior**: > - Shows modal once after login when both Predict and GTM modal flags are enabled; checks storage and navigates (`Views/Wallet/index.tsx`). > - **Feature Flags**: > - Adds selector `selectPredictGtmOnboardingModalEnabledFlag` using remote or `MM_PREDICT_GTM_MODAL_ENABLED` (`selectors/featureFlags`). > - **Analytics**: > - Adds GTM modal event constants (`PREDICT_GTM_WHATS_NEW_MODAL`, `PREDICT_GTM_MODAL_ENGAGE`, `PREDICT_GTM_MODAL_DECLINE`). > - **Storage**: > - Adds `PREDICT_GTM_MODAL_SHOWN` key (`constants/storage.ts`). > - **Localization**: > - Adds `predict.gtm_content` strings (`en.json`). > - **Tests**: > - Unit tests for modal behavior and Wallet gating/mocks (`PredictGTMModal.test.tsx`, updates to `Views/Wallet/index.test.tsx`). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 9f219d1. 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** Scanning an invalid QR code, the invalid QR code alert is showing multiple times. The fix: when there is an error scanning QR code, in the parseDeeplink file we return true so it stops at line 257 in QRScanner: https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/9e507fa7-b997-40cc-831a-6f186aef992e builds for testing: https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/9e507fa7-b997-40cc-831a-6f186aef992e <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry:Fixed a bug that was causing invalid QR code alert showing multiple times ## **Related issues** Fixes: #12908 ## **Manual testing steps** ```gherkin Feature: QR Code Scanner - Invalid QR Code Handling Scenario: User scans an invalid QR code Given the user is on the QR code scanner screen When the user scans an invalid QR code "0xB8B4EE5B1b693971eB60bDa15211570df2dB221L" Then the user should be navigated back to the home screen And an alert should be displayed with title "This is not a valid address" And the alert should contain the message about unrecognized QR code When the user taps "OK" on the alert Then the alert should be dismissed And the user should remain on the home screen ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** Android  iOS  ### **After** Android  iOS  <!-- [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] > Ensures invalid QR scans navigate back, show a single specific alert, and return handled to stop repeat alerts. > > - **Deeplink parsing (`app/core/DeeplinkManager/ParseManager/parseDeeplink.ts`)**: > - On parse error from QR origin: > - Call `onHandled()` before alert to navigate back. > - Show QR-specific "unrecognized address" alert. > - Return `true` to mark as handled and prevent repeat alerts. > - Otherwise, show generic `Invalid URL` alert. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 6f3a038. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…22542) <!-- 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** Fixed a bug in the Predict feature where optimistic position updates were incorrectly applied when querying for claimable positions. Previously, when calling `getPositions({claimable: false})` after creating or updating a position optimistically, the API would return no results (as expected, since newly created/updated positions are not claimable), but the code would still inject the optimistic position into the results. This caused positions to incorrectly appear as claimable when they were not. The fix ensures that CREATE/UPDATE optimistic updates are only applied to non-claimable position queries, since it's impossible to create or update a position that is immediately claimable. ## **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: Predict optimistic position updates Scenario: user creates a position and queries claimable positions Given the user has created a new Predict position optimistically And the API has not yet returned the created position When user queries positions with claimable: false Then the optimistic position should not appear in the results ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- Optimistic positions would incorrectly appear when querying with claimable: false --> ### **After** <!-- Optimistic positions are correctly excluded from claimable queries --> ## **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] > Prevents optimistic CREATE/UPDATE positions from appearing in claimable queries and short-circuits updates for claimable API positions; minor withdraw param typing tweak. > > - **Predict/PolymarketProvider**: > - **Optimistic updates**: > - `applyOptimisticPositionUpdates` now accepts `claimable` and avoids adding optimistic positions when `claimable` is true. > - `isApiPositionUpdated` treats claimable API positions as already updated. > - `getPositions` passes `claimable` into `applyOptimisticPositionUpdates`. > - **Withdraw**: > - Use `callData` directly in transaction params (`prepareWithdraw`), removing unnecessary `Hex` cast. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 7b12627. 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 validates geo restriction for add funds. <!-- 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/MMQA-1139 ## **Manual testing steps** ``` https://github.com/MetaMask/metamask-mobile/actions/runs/19267849354/job/55088929298?pr=22490#step:13:209 https://github.com/MetaMask/metamask-mobile/actions/runs/19267849354/job/55090297847?pr=22490#step:13:254 ``` ## **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] > Adds e2e page object and selector for Predict “Add funds” and a test asserting geo-restriction modal when invoked from balance. > > - **E2E Tests**: > - Add new scenario in `e2e/specs/predict/predict-geo-restriction.spec.ts` verifying the geo-restriction modal appears when tapping `Add funds` from the Predictions balance and returns to the balance after dismissal. > - **Page Objects**: > - Introduce `e2e/pages/Predict/PredictAddFunds.ts` with `tapAddFunds()` using text-matching to trigger the action. > - **Selectors**: > - Add `PredictAddFundsSelectorText.ADD_FUNDS` in `e2e/selectors/Predict/Predict.selectors.ts` sourced from `enContent.predict.deposit.add_funds`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e2defb6. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** This PR isolates input-related fixes that were originally bundled in #21199 (which was reverted in #22342). These specific fixes did not cause any issues and should be preserved. The main changes include: 1. **Font weight fix for Input component** - Added explicit `fontWeight` property to ensure proper text rendering in TextField inputs 2. **ImportSRP modal overlay fix** - Fixed overlay style interpolation to prevent visual artifacts during the seed phrase import modal animation 3. **Card delegation improvements** - Enhanced delegation logic to properly handle zero-value delegations and checksum addresses for EVM networks These fixes improve the overall stability and user experience of input fields and related UI components across the app. ## **Changelog** CHANGELOG entry: null ## **Related issues** Related to #21199 (original PR with font preloader changes) Related to #22342 (revert of #21199) ## **Manual testing steps** ```gherkin Feature: Input component rendering and functionality Scenario: user enters text in TextField components Given user is on any screen with text input fields When user types text into input fields Then text should render correctly with proper font weight and styling Scenario: user imports wallet via seed phrase Given user is on the import wallet flow When user opens the seed phrase modal Then modal should display without overlay artifacts Scenario: user manages card delegation Given user has external wallet details configured When user sets a delegation amount of zero Then system should not call updateTokenPriority And delegation should complete successfully ``` ## **Screenshots/Recordings** N/A - These are fixes for existing functionality ## **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 - [ ] 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 consistent input lineHeight and applies Geist font styles to password-related views, updating snapshots accordingly. > > - **Frontend**: > - **Input/TextField**: Set explicit `lineHeight` in `components/Form/TextField/foundation/Input/Input.styles.ts` for consistent baseline alignment across platforms. > - **Password Screens**: > - `Views/EnterPasswordSimple/index.js`: Apply `fontStyles.normal` to prompt text. > - `Views/RevealPrivateCredential/styles.ts`: Apply `fontStyles.normal` to `input` style. > - **Tests**: > - Update snapshots across multiple views to reflect added `lineHeight` and `fontFamily` styling on inputs. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 7bb6459. 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 : )