[pull] main from MetaMask:main#790
Merged
Merged
Conversation
…tor c… (#29128) …omponents - BridgeTokenSelector, TokenButton, TokenSelectorItem: Pressable → TouchableOpacity <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **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: ## **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** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [ ] 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. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > UI-only changes to Bridge token list rendering and accessibility; no auth, transactions, or API contract changes. > > **Overview** > Improves **Bridge token selector** scrolling performance and **iOS VoiceOver** behavior without changing selection or balance logic. > > **`BridgeTokenSelector`** tunes the token list: `ESTIMATED_ITEM_HEIGHT` is **68** (documented from padding/avatar sizes), and the `FlatList` gets **`initialNumToRender`**, **`maxToRenderPerBatch`**, **`windowSize`**, and **`removeClippedSubviews`** to cut over-rendering on long lists. > > **`TokenSelectorItem`** wraps the row in **`React.memo`**, hoists shared balance text styles, and sets **`accessible={false}`** on inner `Box` layouts so the row’s **`TouchableOpacity`** stays the single focusable control on iOS. Balance rows pass explicit `textVariant` / `textColor` instead of spreading style objects. > > **`TokenButton`** drops the `Box` wrapper: layout moves onto **`TouchableOpacity`**’s `pillContainer` style so the pill is one simpler touch target. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 7185cac. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…-7.79.0 (#30699) ## **Description** Fixes World Cup/sports game cards that could show only two outcomes for draw-capable moneyline games when one outcome had very low odds. The shared market staleness filter removes outcomes priced at or below 5% or at or above 95%. That behavior is useful for multi-outcome non-game cards, but it breaks game cards that need the complete moneyline set. For example, Germany vs. Curacao has Germany, Draw, and Curacao outcomes, but Curacao can be priced below 5%. Once that outcome is filtered out, the card falls back to a binary path and the away-team button can open the `No` token for the favorite instead of the underdog moneyline. This change skips stale-price outcome filtering and stale-price ranking penalties for game markets. Closed markets and ended games are still filtered out as before. ## **Changelog** CHANGELOG entry: Fixed a bug where sports game cards could hide low-probability outcomes and open the wrong prediction. ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/PRED-934?atlOrigin=eyJpIjoiZjVmNDJkY2I3NzBjNGQ4MjgwZWY5MjQ5ZjcyOTlkYWMiLCJwIjoiaiJ9 ## **Manual testing steps** ```gherkin Feature: World Cup game card outcomes Scenario: user opens a draw-capable World Cup game card with a low-probability away team Given the World Cup feed includes a game with home, draw, and away moneyline outcomes And one of the moneyline outcomes is priced at or below 5% When user views the game card Then the card shows all available moneyline outcomes When user taps the away-team prediction button Then the buy sheet opens for the away-team outcome, not the favorite team's No token ``` ## **Screenshots/Recordings** ### **Before** <img width="420" height="861" alt="Screenshot 2026-05-27 at 14 27 35" src="https://github.com/user-attachments/assets/6ec940a0-5db6-4323-a7aa-58cb422c00a8" /> ### **After** <img width="420" height="875" alt="Screenshot 2026-05-27 at 14 27 49" src="https://github.com/user-attachments/assets/6f277b93-5d88-4353-87e0-68588e88f944" /> ## **Testing** - `node .yarn/releases/yarn-4.14.1.cjs jest app/components/UI/Predict/utils/marketStaleness.test.ts` ## **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. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Scoped to Predict visibility/ranking utilities; closed and ended games remain hidden; non-game staleness behavior unchanged. > > **Overview** > **Game markets** with a `game` attachment are now exempt from Predict’s stale-price outcome filtering (≤5% / ≥95%) and from staleness-based feed ranking penalties, matching the existing **highlighted** market behavior. > > `getVisiblePredictMarket` returns the full market for open game markets after the usual closed/expired checks, so moneyline sets (e.g. home / draw / away) stay intact when an underdog is priced very low. Non-game cards still drop “dead” outcomes and can be deprioritized in the list. > > Tests cover full outcome preservation on game cards and unchanged ordering when a game market would otherwise be penalized. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 2ead89a. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…ive for first-level sheets (#30696) ## **Description** Corrects the elevated surface token used across bottom sheets and action list surfaces for the pure black dark mode initiative. The initial implementation used `background.section` as the elevated surface color when `MM_PURE_BLACK_PREVIEW` is enabled. This was incorrect — the design token elevation hierarchy is `default > alternative > section > subsection`, so bottom sheets (the first level above the screen background) should use `background.alternative`, not `background.section`. Updated `getElevatedSurfaceColor` and `useElevatedSurface` in `app/util/theme/themeUtils.ts` to return `background.alternative` / `bg-alternative` in dark mode when pure black is active. All callsites (sheet containers and list rows inside sheets) are correctly covered by this single correction. ## **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:nuill ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TMCU-798 ## **Manual testing steps** ```gherkin Feature: Pure black elevated surface token correction Scenario: user opens bottom sheets with pure black flag enabled Given the app is in dark mode with MM_PURE_BLACK_PREVIEW=true When user opens Trade, Buy/Sell, Network, Fund, or Money sheets Then each sheet surface renders at background.alternative (#1a1a1a) And sheet surfaces are visibly elevated above the pure black background And light mode appearance is unchanged ``` ## **Screenshots/Recordings** https://github.com/user-attachments/assets/88edab80-ed64-499e-b9f5-3717b0d4eae0 ### **Before** https://github.com/user-attachments/assets/5a581895-bfac-40c3-bdc1-e8e243778896 ### **After** https://github.com/user-attachments/assets/88edab80-ed64-499e-b9f5-3717b0d4eae0 ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [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. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Two-token swap behind an existing feature flag with no auth, data, or API impact. > > **Overview** > When **`MM_PURE_BLACK_PREVIEW`** is on, pure-black dark mode now treats **first-level elevated surfaces** (bottom sheets, action list rows, etc.) as **`background.alternative`** / **`bg-alternative`** instead of **`background.section`** / **`bg-section`**. > > **`getElevatedSurfaceColor`** and **`useElevatedSurface`** in `app/util/theme/themeUtils.ts` are the only code changes; existing callers pick up the corrected token without further edits. Light mode and non–pure-black behavior are unchanged. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 6c8cf7f. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…I components (#30679) ## **Description** Adds the reusable Predict portfolio UI components for PRED-899. This PR is stacked on top of `predict/PRED-902-create-shared-predict-portfolio-data-hook-and-derived-model`, which introduces the shared `usePredictPortfolio` data/model hook used by these components. Included components: - `PredictPortfolioModule` for the homepage balance/portfolio surface - `PredictPortfolioSummary` for primary portfolio value and optional P&L/available balance display - `PredictPortfolioActions` and `PredictPortfolioAction` for Positions, Add funds, and Withdraw actions - `PredictPortfolio` test IDs and barrel exports The module supports first-time, returning, loading, privacy mode, claimable winnings, positions badge count, guarded deposit/withdraw/claim flows, and amount-only P&L display when the portfolio model omits a percent. This PR intentionally does **not** wire the portfolio module into `PredictFeed`, feature flag rendering, or confirmation navigation. That integration will be handled in a follow-up stacked branch. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/PRED-899 Depends on: https://consensyssoftware.atlassian.net/browse/PRED-902 ## **Manual testing steps** ```gherkin Feature: Predict portfolio UI components Scenario: reusable portfolio module renders portfolio states Given the shared Predict portfolio hook returns first-time, returning, claimable, loading, or privacy-mode data When the Predict portfolio module is rendered Then it displays the expected value, optional P&L line, action row, positions badge, and claim CTA for that state ``` Manual app QA: N/A for this stacked PR because the components are not integrated into the Predict feed in this branch. ## **Screenshots/Recordings** N/A. This branch adds reusable components only; feed integration and visual QA screenshots will be covered by the follow-up integration branch. ### **Before** N/A ### **After** https://github.com/user-attachments/assets/b725df1e-4584-4aeb-b517-b71be9c5905c ## **Testing** - `NODE_OPTIONS=--max-old-space-size=8192 node .yarn/releases/yarn-4.14.1.cjs jest app/components/UI/Predict/components/PredictPortfolio/PredictPortfolioModule.test.tsx app/components/UI/Predict/components/PredictPortfolio/PredictPortfolioSummary.test.tsx --runInBand --watchman=false --forceExit --silent --coverage=false` - `node .yarn/releases/yarn-4.14.1.cjs lint:tsc` - `git diff --check` ## **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. #### Performance checks (if applicable) - [ ] I've tested on Android - [ ] I've tested with a power user scenario - [ ] I've instrumented key operations with Sentry traces for production performance metrics ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > New UI and hook tweaks only; deposit/withdraw/claim reuse existing guarded flows and the module is not yet integrated into the Predict feed. > > **Overview** > Introduces reusable **Predict portfolio** UI for the homepage balance surface: `PredictPortfolioModule` composes summary, Positions / Add funds / Withdraw actions, and an optional claim CTA, wired through `usePredictPortfolio`, privacy mode, `usePredictActionGuard`, and deposit-wallet withdraw feature flags. **PredictPortfolioSummary** shows portfolio value with optional unrealized P&L and available balance (amount-only P&L when percent is omitted), loading skeletons, and masked values in privacy mode. > > **usePredictPortfolio** now enables account state when **portfolio value** is positive (not only cash balance), and account state failures no longer surface on the aggregate `error` field. New `predict.portfolio.*` strings and test IDs support automation. Feed integration is explicitly out of scope for this branch. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 781b9ca. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…rd (#30663) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** Migrate Card onboarding screens from navigator-rendered headers to in-screen HeaderStandard (from @metamask/design-system-react-native). **Why**: This is a prerequisite for migrating the Card navigation stack from @react-navigation/stack (JS stack) to @react-navigation/native-stack. Native stack on iOS 26 / iPhone 17 Pro Max renders the system "liquid glass" navigation bar, which doesn't match the Card screens' flat bg-background-default and breaks visual consistency. By moving the header into each screen body, header styling becomes navigator-type-agnostic — the follow-up native-stack PR can then be a small, mechanical swap with no further header rework. **What changed**: 1. All 9 Card onboarding screens now hide the navigator header (headerShown: false, gestureEnabled: false) and render HeaderStandard in-screen via OnboardingStep. 2. New useCardOnboardingNavigationHandlers hook centralizes the three header behaviors: - back — back arrow → goBack() (SignUp, ConfirmEmail, Complete) - close-with-confirmation — close (X) → exit-confirmation Alert → WALLET.HOME (SetPhoneNumber, ConfirmPhoneNumber, VerifyIdentity, PersonalDetails, PhysicalAddress) - close-direct — close (X) → straight to WALLET.HOME (VerifyingVeriffKYC) 3. OnboardingNavigator simplified: removed cardDefaultNavigationOptions, PostEmailNavigationOptions, KYCStatusNavigationOptions, HeaderlessNavigationOptions factories. Replaced 11 per-screen options with a single shared screenOptions={{ headerShown: false, gestureEnabled: false }}. 4. KYCFailed and KYCPending are unchanged — they already used the in-screen header pattern with their custom purple/dark backgrounds. 5. The exit-onboarding-button testID is preserved on the close button (passed via closeButtonProps) so existing E2E selectors continue to work. 6. Tests for the removed navigation-options factories were dropped; equivalent coverage now lives in useCardOnboardingNavigationHandlers.test.tsx. ## **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: Card Onboarding in-screen header Scenario: User taps back from SignUp / ConfirmEmail / Complete Given the user is on a Card Onboarding screen with a back-only header When user taps the back arrow in the header Then the user is returned to the previous screen Scenario: User taps close from a post-email screen Given the user is on SetPhoneNumber, ConfirmPhoneNumber, VerifyIdentity, PersonalDetails, or PhysicalAddress When user taps the close (X) icon in the header Then an exit confirmation Alert is displayed When user taps the destructive "Exit" action in the Alert Then the user is navigated to Wallet Home Scenario: User taps close on VerifyingVeriffKYC Given the user is on the VerifyingVeriffKYC screen When user taps the close (X) icon in the header Then the user is navigated directly to Wallet Home with no confirmation Scenario: KYC status screens render their own header Given the user reaches KYCFailed or KYCPending Then the screen renders with its custom purple / dark header (unchanged from main) Scenario: Returning user resumes onboarding Given the user has an in-progress onboarding session and returns to the Card flow When OnboardingNavigator mounts Then the "Keep going" modal is shown over the resolved initial route Scenario: Header background matches screen background Given the user is on any Card Onboarding screen with HeaderStandard Then the header background matches the screen body (no glass / material navigation bar) And the back / close icons sit inside the screen body, not the navigator chrome ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <img width="392" height="768" alt="Card Before" src="https://github.com/user-attachments/assets/7fd3beac-07e2-4bc2-b780-a758b8ac99b1" /> ### **After** <img width="392" height="768" alt="Card Header After" src="https://github.com/user-attachments/assets/2806a648-50fb-433e-b04a-1abc6d67bb8b" /> Android test: https://github.com/user-attachments/assets/97923e40-38ea-4dbe-90f7-aa21ed46aacf <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [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. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > UI and navigation chrome refactor with preserved exit flows and E2E testIDs; no auth, payment, or data-model changes. > > **Overview** > Card onboarding moves header chrome from the stack navigator into each screen via **`OnboardingStep`** and design-system **`HeaderStandard`**, so headers match the flat onboarding background and are ready for a future native-stack swap. > > **`OnboardingNavigator`** drops per-screen header factories (`PostEmailNavigationOptions`, `KYCStatusNavigationOptions`, etc.) in favor of shared **`headerShown: false`** / **`gestureEnabled: false`**. A new **`useCardOnboardingNavigationHandlers`** hook centralizes **back**, **close with exit alert → wallet home**, and **close direct → wallet home**; each step passes a **`headerMode`**. The **`exit-onboarding-button`** testID is kept on close actions. Navigator option tests were removed in favor of hook unit tests; sticky-step layout no longer sets a fixed iOS **`keyboardVerticalOffset`**. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f6623ab. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** This attempts to fix what was intended to be fixed in PR #30419 but for some reason that PR did not work - to ensure that a source token is used when opening an Ondo swap from Rewards. It also updates the button text to say "Trade now" instead of "Open Position." ## **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: n/a ## **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** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [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. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Copy and Rewards swap prefill logic only; changes are localized with new unit tests and no auth or payment impact. > > **Overview** > Renames the opted-in, no-positions Ondo campaign CTA from **Open Position** to **Trade now** via `rewards.campaign_details.open_position` in `en.json`, with matching test and comment updates. > > Fixes **open position** swaps from Rewards by resolving default source tokens through a new `getOndoOpenPositionSourceToken` helper: chain defaults are keyed by hex (`0x1` → USDC, `0x38` → USDT) instead of CAIP-only map lookups, and the helper accepts hex or `eip155:` chain IDs (including after-hours confirm). USDY balance preference is unchanged; tests cover BNB/USDT and the helper edge cases. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit be88b88. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description**
Migrate the Card Onboarding flow off the JS stack navigator and
react-navigation header in favor of native stack:
- `app/components/UI/Card/routes/OnboardingNavigator.tsx` now uses
`createNativeStackNavigator` from `@react-navigation/native-stack`
instead of `createStackNavigator`. The navigator-level header is hidden
for every screen (`headerShown: false`, `gestureEnabled: false`), so
screens own their own header chrome.
## **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: Card Onboarding header & navigation
Scenario: Back navigation on early onboarding screens
Given I am on the Card Onboarding "Sign Up", "Confirm Email", or "Complete" screen
When I tap the back arrow in the header
Then the navigator goes back to the previous screen
Scenario: Exit with confirmation on post-email screens
Given I am on "Set Phone Number", "Confirm Phone Number", "Verify Identity", "Personal Details", or "Physical Address"
When I tap the close button in the header
Then a confirmation alert appears asking me to confirm exiting onboarding
When I confirm exit
Then I am navigated to Wallet Home
Scenario: Exit directly from KYC status screen
Given I am on the "Verifying Veriff KYC" screen
When I tap the close button in the header
Then I am navigated directly to Wallet Home without a confirmation alert
Scenario: Keyboard does not obscure inputs
Given I am on any onboarding screen with a text input
When I focus the input and the keyboard opens
Then the input remains visible and the sticky action button (if any) stays above the keyboard
Scenario: Resume incomplete onboarding (regression)
Given I am a returning user with incomplete onboarding
When I re-enter the Card flow
Then the "Keep going" modal is shown and routes me to the correct resume step
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<img width="328" height="676" alt="card onboarding before"
src="https://github.com/user-attachments/assets/81f6ec2d-e3a8-439a-9bf0-52ce4b47ae2b"
/>
### **After**
<img width="342" height="744" alt="Card Onboarding Navigation after"
src="https://github.com/user-attachments/assets/26c198bb-d39c-40b0-ace0-3de1c467965e"
/>
Android
https://github.com/user-attachments/assets/d85c4de6-514d-4186-a792-309a0e4452a2
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [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.
#### Performance checks (if applicable)
- [x] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [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]
> <sup>[Cursor Bugbot](https://cursor.com/bugbot) is generating a
summary for commit 1dc693e. Configure
[here](https://www.cursor.com/dashboard/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 : )