[pull] main from MetaMask:main#410
Merged
Merged
Conversation
## **Description**
This PR refactors the `HeaderBase` component to use
`@metamask/design-system-react-native` components and Tailwind CSS
styling.
**Reason for change:**
- The existing `HeaderBase` component uses custom StyleSheet-based
styling which doesn't align with the design system migration goals
- The component API could be simplified for common use cases like adding
back/close buttons
**Improvements:**
- Migrates to design system components (`Box`, `Text`, `ButtonIcon`) and
Tailwind CSS (`twClassName`)
- Adds new simplified APIs: `startButtonIconProps` and
`endButtonIconProps[]` for common icon button use cases without needing
to create custom accessories
- Adds `twClassName` prop for Tailwind-based customization
- Adds optional `testID` prop for better test flexibility
- Removes `HeaderBase.styles.ts` in favor of inline Tailwind-based
layout
- Updates text variants to use design system variants
(`HeadingSm`/`HeadingLg`)
- Re-exports test IDs and types from `index.ts` for easier imports
## **Changelog**
CHANGELOG entry: null
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: HeaderBase component
Scenario: user views a header with Compact variant (default)
Given the app is open
When user navigates to a screen using HeaderBase with Compact variant
Then the title should be center-aligned with HeadingSm text
Scenario: user views a header with Display variant
Given the app is open
When user navigates to a screen using HeaderBase with Display variant
Then the title should be left-aligned with HeadingLg text
Scenario: user taps header icon buttons
Given a screen has HeaderBase with startButtonIconProps and endButtonIconProps
When user taps the back icon
Then the associated onPress handler should be called
```
## **Screenshots/Recordings**
### **Before**
<!-- [screenshots/recordings] -->
### **After**
https://github.com/user-attachments/assets/c99e5a85-c96e-48a2-b245-0205480f413c
Existing usages is still functional
https://github.com/user-attachments/assets/4cffee2c-9fb5-4a50-a459-1c4062eec004
<!-- [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]
> Refactors `HeaderBase` to use design-system components with Tailwind
styling, adds simplified icon-button APIs, removes legacy styles, and
updates tests/snapshots and usages across the app.
>
> - **Component Library — HeaderBase**:
> - Migrate to `@metamask/design-system-react-native` (`Box`, `Text`,
`ButtonIcon`) and Tailwind via `twClassName`.
> - Add `startButtonIconProps` and `endButtonIconProps[]`; prioritize
custom accessories when both provided.
> - Add `testID` and `twClassName` props; re-export test IDs and types
from `index.ts`.
> - Map variants to design-system text (`HeadingSm`/`HeadingLg`); remove
`HeaderBase.styles.ts` in favor of inline Tailwind.
> - Implement equal-width accessory wrappers for centered titles;
support multiple end buttons (reversed render order).
> - **Stories/Docs**:
> - Rewrite stories showcasing variants, Tailwind usage, button-prop
variants, and custom children.
> - Update README with new props, usage, and defaults.
> - **Tests**:
> - Overhaul `HeaderBase.test.tsx` to new API/behavior; remove obsolete
alignment tests in `BottomSheetHeader`.
> - Update mocks for Tailwind and design-system variants; export test
IDs for easier querying.
> - **Consumers/Styling**:
> - Apply `twClassName="h-auto"` or header tweaks in `Navbar`,
`TokensFullView`, `UpdateNeeded`, and clean up redundant header styles.
> - **Snapshots**:
> - Widespread snapshot updates reflecting new layout/typography
(center/left alignment, `height: 48`, padding separation, fontWeight
700, flex wrappers).
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b995e9e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…3771) ## **Description** It updates the [previous](#23364) GitHub workflow file with these things: - Cursor CLI - Creating a GitHub comment with a Cursor response When there is a new issue that's either (sev1 or sev2), it's assigned to the `team-confirmations` and it's not from an external contributor, it will trigger a Cursor issue analysis. ## **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** ## **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] > Updates the issue-analysis workflow to run Cursor CLI on qualifying issues with stricter label gating, a read-only permissions allowlist, safe data handling, and automatic posting of a formatted analysis comment; also cleans up the prompt template. > > - **GitHub Actions Workflow (`.github/workflows/cursor-issue-analysis.yml`)**: > - **Trigger/Gating**: Adds exclusion for `external-contributor`; retains `team-confirmations` and (`Sev1-high` or `Sev2-normal`). > - **Idempotency**: Checks for existing comment containing `## Cursor Analysis` before running. > - **Cursor Integration**: > - Configures strict `.cursor/permissions.json` allow/deny lists (read-only paths; deny secrets/shell/write). > - Installs and invokes `cursor-agent` with a composed prompt and security notice. > - **Data Handling**: Fetches issue via `gh`, base64-encodes/decodes payloads to pass between steps safely. > - **Output**: Posts a formatted comment with header, caution note, analysis body, and footer. > - **Misc**: Removes sparse checkout; renames steps for clarity. > - **Prompt Template (`.github/cursorPrompts/issue-analysis.md`)**: > - Removes leading `@cursor` directive; retains structured analysis instructions. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit a56620f. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** It was found on main branch that quote details are empty for swaps on Solana network. This does not exist on any RC or production release. After investigating the issue we pinpointed the root cause to be introduced in commit . For non-EVM chains (e.g., Solana), destAsset.address is in raw format (e.g., "EPj...") or zero address for native tokens, while destToken.address uses CAIP format e.g., "solana:.../token:EPj..."). We should use destAsset.assetId (CAIP format) for comparison and for EVM chains, use the original address comparison. <!-- 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: fixes empty quote card details issue when swapping on Solana network ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/SWAPS-3580 ## **Manual testing steps** ```gherkin Ensure that details for quotes are filled correctly. ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <img width="487" height="920" alt="Screenshot 2025-12-11 at 1 42 30 PM" src="https://github.com/user-attachments/assets/79528e5c-fa7f-4835-b389-962e060acb08" /> <!-- [screenshots/recordings] --> ### **After** <img width="487" height="920" alt="Screenshot 2025-12-11 at 2 00 27 PM" src="https://github.com/user-attachments/assets/63d33ad5-9cf8-4260-8e98-366601451291" /> <!-- [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] > Fixes Solana quote details by comparing non-EVM destination tokens via CAIP `assetId` (with `isNonEvmChainId`) and updates tests to use CAIP-formatted addresses. > > - **Bridge Quote Data**: > - Use `isNonEvmChainId` and compare non-EVM dest assets via CAIP `destAsset.assetId` (fallback to `address`), keeping address comparison for EVM. > - Ensure `destTokenAmount` is computed only when selected dest token matches the quote’s dest asset (prevents stale/incorrect decimals). > - **Tests**: > - Update Solana cases to use CAIP-formatted `destToken.address` matching quote `assetId`. > - Adjust expectations and comments; add coverage for validation flows and unchanged loading/error states. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 27809dc. 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** After profiling the mobile app I found out that the detectNfts function triggers a call to the NFTs API in a loop while the cursor/continuation is defined. This is good when trying to detect all NFTs for a given user but has two big limitations: - What if the user has thousands of NFTs and navigates to the NFT view and then goes back to a different view? These API calls will continue running on the background endlessly without a reason - What if we just want to fetch the first page of the NFTs? On mobile when the user navigates to the NFTs tab we just display 18 NFTs, we just need 1 single API call to fetch these and no endless loop to retrieve the rest This is why I have added firstPageOnly and signal options to NftDetectionController.detectNfts() method to allow fetching only the first page of NFTs and aborting detection operations in [Core](MetaMask/core#7436) Now I am making use of these new properties on Mobile which will reduce number of API calls and improve the overall performance of the app for user with a lot of NFTs <!-- 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: NFTs allow fetching one page and aborting fetch when navigating away ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/ASSETS-2106 & https://consensyssoftware.atlassian.net/browse/ASSETS-2105 ## **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** As you can see: - When we navigate to the NFTs tab we fetch NFTs in a loop until there is no cursor/continuation - When we navigate away from the NFTs tab we keep fetching NFTs in a loop until there is no cursor/continuation https://github.com/user-attachments/assets/d089b358-8cbf-45bf-a71f-51e9f09ee402 ### **After** As you can see: - When we navigate to the NFTs tab we make a single API call to the NFTs API since we do not need more NFTs for that view - When we navigate to the list of all NFTs we fetch NFTs in a loop until the user navigates away or the is not cursor/continuation https://github.com/user-attachments/assets/beb53910-0f2d-42cc-a5f0-a5837f91bd3f <!-- [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] > Makes NFT detection abortable with an AbortController and adds a firstPageOnly option; full view triggers full detection on mount and aborts on unmount, with tests updated accordingly. > > - **Hooks (`useNftDetection`)**: > - Add `AbortController` support and `abortDetection()` to cancel in-progress detection. > - Extend `detectNfts` to accept `firstPageOnly` (default `true`) and pass `{ firstPageOnly, signal }` to `NftDetectionController.detectNfts`. > - Abort previous detection before starting a new one; return updated API `{ detectNfts, abortDetection, chainIdsToDetectNftsFor }`. > - **UI (`UI/NftGrid/NftGrid.tsx`)**: > - Replace focus-based trigger with mount-based `useEffect` for full view: call `detectNfts(false)` and cleanup with `abortDetection` on unmount. > - Wire `abortDetection` from `useNftDetection`. > - **Tests**: > - Update `useNftDetection.test.ts` to cover `firstPageOnly` default/false, abort-on-reinvoke, and `abortDetection` behavior. > - Update `NftGrid.test.tsx` to assert `detectNfts(false)` on full view mount and `abortDetection` on unmount; ensure non-full view does not call them. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit f1e76cd. 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** * feat: update optin metrics screen changes. * Jira: https://consensyssoftware.atlassian.net/browse/SL-406 <!-- 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: Update optin metrics screen ui changes ## **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** <img width="319" height="722" alt="Screenshot 2025-12-15 at 3 17 13 PM" src="https://github.com/user-attachments/assets/c7205498-a61a-458e-96c6-f91db02a5237" /> <!-- [screenshots/recordings] --> ### **After** <img width="324" height="728" alt="Screenshot 2025-12-15 at 1 51 41 PM" src="https://github.com/user-attachments/assets/e5f4adb0-b0a6-4ab6-b8b2-9b27293ff33f" /> <img width="270" height="570" alt="Screenshot 2025-12-15 at 6 20 54 PM" src="https://github.com/user-attachments/assets/a69225f5-71c6-4460-aab4-1567d1dff499" /> <!-- [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] > Updates the OptinMetrics screen layout (image above title, larger illustration, right-aligned checkboxes, adjusted paddings) and changes title copy to “Improve MetaMask.” > > - **UI (OptinMetrics)** > - **Layout**: Moves illustration above title; increases illustration height to 180; adjusts container paddings (`paddingTop: 40`, split action padding to `paddingHorizontal`/`paddingTop`). > - **Checkbox Rows**: Switches to `justifyContent: space-between`; places text on left and `Checkbox` on right; removes extra right margin; maintains disabled styling logic. > - **Button Bar**: Replaces uniform `padding` with `paddingHorizontal` and `paddingTop`. > - **Copy/i18n** > - Updates `privacy_policy.description_title` from `Help improve MetaMask` to `Improve MetaMask`. > - **Tests** > - Snapshot updates reflecting new layout, paddings, image size, and title text. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 7ec03fd. 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 : )