chore: sync stable into release/7.82.0#31674
Open
metamaskbotv2[bot] wants to merge 55 commits into
Open
Conversation
…Android cp-7.81.0 (#31106) - fix: wallet home onboarding Rive crash on Android cp-7.81.0 (#31042) ## **Description** Fixes a fatal native crash on Android originating in `rive-react-native`'s checklist Rive animation on the wallet home onboarding screen. Affects ~2.3K production users Root cause was in the `.riv` asset not being fully aligned with the code. The wallet home checklist Rive `onboard_checklist_v05.riv` had inconsistent State Machine inputs across its three artboards: - `01_Add_Funds` and `02_First_Trade` were missing the `Main` trigger input that the code fires via `fireState('State Machine 1', 'Main')`. When the code fired a name that didn't match, Rive threw `StateMachineInputException`. `rive-react-native`'s native code doesn't clear the pending Java exception before its next JNI call, violating ART's JNI rules and aborting the process (`SIGABRT` / `SIGSEGV` depending on device). Fix: - Added missing `Main` trigger inputs to `01_Add_Funds` and `02_First_Trade`, wired to the `Intro → Main` transition. - Renamed `"Outro "` to `"Outro"` on `03_Notifications`. - Re-exported as `onboard_checklist_v06.riv`. - Bumped the import in `WalletHomeOnboardingSteps.tsx` from v05 to v06. Verified locally: previously-crashing flows on emulator and arm64 physical device no longer crash, and the ~0.25s animation flicker observed on flagship devices is also gone. ## **Changelog** CHANGELOG entry: Fixed a native crash on Android affecting users on the wallet home onboarding screen. ## **Related issues** Fixes: #31103 #31103 ## **Manual testing steps** ```gherkin Feature: Wallet home onboarding checklist Rive animation Scenario: User steps through the onboarding checklist Given the user has completed primary onboarding on a fresh install And the wallet home onboarding checklist is visible When the user taps Skip or Continue through fund / trade / notifications steps Then the checklist animation plays intro → main → outro on each step And the app does not crash Scenario: User navigates away from a step and returns Given the user is on the trade or notifications step When the user taps the Primary button and navigates to the destination screen And the user returns to the wallet home screen Then the checklist Rive resumes correctly And the app does not crash ``` ## **Screenshots/Recordings** https://github.com/user-attachments/assets/0d84b394-10f3-485f-8689-ad847111ee65 ### **Before** https://github.com/user-attachments/assets/bc562dc8-305c-4e61-a1be-472d68e675aa ### **After** https://github.com/user-attachments/assets/0d84b394-10f3-485f-8689-ad847111ee65 ## **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. #### Performance checks (if applicable) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] 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 - [x] 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** > Binary animation asset plus a single import path change; no auth, payments, or business-logic changes beyond fixing Rive input names. > > **Overview** > Fixes a **production Android native crash** on wallet home post-onboarding when the checklist Rive animation runs. The app already drives **`Main`** and **`Outro`** on **`State Machine 1`** via `fireState`; **`onboard_checklist_v05.riv`** was out of sync (missing **`Main`** on the fund and trade artboards, and a mismatched outro input name on notifications), which led to `StateMachineInputException` and a fatal JNI abort in `rive-react-native`. > > The change **re-exports the animation as `onboard_checklist_v06.riv`** with aligned triggers and transitions, and **points `WalletHomeOnboardingSteps` at v06** instead of v05. No change to the checklist flow logic beyond the asset swap. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 1945d4f. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [bdce2e9](bdce2e9) Co-authored-by: Vince Howard <vincenguyenhoward@gmail.com>
…o crypto up/down markets cp-7.81.0 (#31112) - feat(predict): add Ethereum accent color to crypto up/down markets cp-7.81.0 (#31029) ## **Description** Maps the `ETH` symbol to `#5E6DB7` in both the series card (`PredictCryptoUpDownMarketCard`) and the details screen (`PredictCryptoUpDownDetails`) so Ethereum up/down markets render with a distinct accent — chart line, sparkline, badge, and current-price text — instead of falling back to the default amber. Symbol resolution was already in place via `getCryptoSymbol()` (`ethereum` tag + `eth-` slug prefix), so only the two color lookup tables (`CRYPTO_SYMBOL_TO_ACCENT_COLOR` on the details screen, `CRYPTO_ACCENT_BY_SYMBOL` on the card) needed extending. BTC keeps its orange accent and any unmapped symbol continues to fall back to the default amber. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: PRED-941 ## **Manual testing steps** ```gherkin Feature: Predict Ethereum up/down accent color Scenario: user views an Ethereum up/down market card on the feed Given the predict up/down feature flag is enabled And an Ethereum up/down market is available in the feed When the user scrolls to the Ethereum market card Then the card's sparkline and accent elements render in the Ethereum accent (#5E6DB7) And BTC up/down cards continue to render in the BTC orange accent And any unmapped crypto up/down card falls back to the default amber accent Scenario: user opens the Ethereum up/down details screen Given the predict up/down feature flag is enabled And an Ethereum up/down market is available When the user taps the Ethereum market card and opens the details screen Then the chart line, "Current price" label, and current price value render in the Ethereum accent (#5E6DB7) And opening a BTC up/down market still renders in the BTC orange accent ``` ## **Screenshots/Recordings** ### **Before** <!-- Not provided — Ethereum up/down markets previously fell back to the default amber accent (`rgb(245, 158, 11)`), identical to any unmapped symbol. --> ### **After** <img width="370" height="308" alt="Screenshot 2026-06-03 at 8 42 17 PM" src="https://github.com/user-attachments/assets/20ccd606-46d2-4b46-9ade-e3314f4dc6a7" /> ## **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. #### Performance checks (if applicable) Not applicable; static color constant addition only. - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] 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 - [x] 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** > Static UI color constants and unit tests only; no auth, data, or trading logic changes. > > **Overview** > Adds **Ethereum** (`rgb(94, 109, 183)` / `#5E6DB7`) to the crypto up/down accent color maps on the **feed card** (`CRYPTO_ACCENT_BY_SYMBOL`) and **details screen** (`CRYPTO_SYMBOL_TO_ACCENT_COLOR`), so ETH markets use a distinct purple accent instead of the default amber. **BTC** orange and the **default** fallback are unchanged. > > Details tests now assert the chart receives the correct `color` for BTC, ETH, and unmapped symbols (mock chart exposes `color` in `accessibilityLabel`; target-price parsing was adjusted for the extra label segment). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 2290913. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [02bdd66](02bdd66) Co-authored-by: hunty <hunter.goodreau@consensys.net>
…tifications to prevent large preview images (#31121) - fix: disable link unfurling in Slack RC notifications to prevent large preview images (#31116) <!-- 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. --> <!-- mms-check directive vocabulary — read by .github/scripts/shared/pr-template-checks.ts at module load to build the validation plan. Directives are invisible in rendered markdown and must NOT be removed or edited without updating the validator registry. type=text Section must contain non-placeholder prose. type=changelog Section must have a valid CHANGELOG entry: line. type=issue-link Section must have a Fixes:/Closes:/Refs: line with a value. type=manual-testing Section must have real testing steps or an explicit N/A. type=screenshot Section must have evidence (image/URL) or an explicit N/A. type=checklist Section must have all checkboxes consciously checked. required=true|false Whether a missing/invalid section blocks the PR check. Sections without a directive are checked for structural presence only. --> ## **Description** <!-- mms-check: type=text required=true --> Disable link unfurling in Slack RC notifications to prevent large preview images <!-- 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** <!-- mms-check: type=changelog required=true --> <!-- 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** <!-- mms-check: type=issue-link required=true --> TestFlight link preview with large image displayed in the Slack RC build notification. Fixes: disables unfurl ## **Manual testing steps** <!-- mms-check: type=manual-testing required=true --> N/A — <reason> ## **Screenshots/Recordings** <!-- mms-check: type=screenshot required=true --> <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** N/A <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- mms-check: type=checklist required=true --> <!-- 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 - [x] 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 - [x] 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). - [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** > Single optional API flags on an internal release-notification script with no app or security impact. > > **Overview** > RC build Slack notifications now pass **`unfurl_links: false`** and **`unfurl_media: false`** on `chat.postMessage`, so Slack stops expanding download, GitHub, and pipeline URLs into large link previews in release channels. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 3448f28. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [1bc6039](1bc6039) Co-authored-by: sleepytanya <104780023+sleepytanya@users.noreply.github.com>
…y without iOS modal presentation (#31152) chore(runway): cherry-pick fix(card): cp-7.81.0 restore slide-up entry without iOS modal presentation
…-7.81.0 (#31158) - chore: cleanup perps top movers buttons cp-7.81.0 (#31147) ## **Description** Makes Gainers/Loser buttons larger and more accessible ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: css bug ## **Manual testing steps** N/A ## **Screenshots/Recordings** <img width="428" height="260" alt="Screenshot 2026-06-05 at 6 54 09 AM" src="https://github.com/user-attachments/assets/a9f4a656-a388-4ba5-8bc9-870bbe369fc7" /> ## **Pre-merge author checklist** <!-- mms-check: type=checklist required=true --> <!-- 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 - [x] 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 - [x] 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** > Cosmetic Tailwind class changes on a Perps home UI toggle with no logic, data, or auth impact. > > **Overview** > Updates the **Gainers / Losers** toggle styling in `PerpsTopMoversSection` so the pills are easier to tap and read. > > `TogglePill` now uses **`rounded-lg`** instead of **`rounded-xl`**, adds **`justify-center`** and **`py-1`** for vertical padding and centered label alignment—matching the PR goal of larger, more accessible buttons. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 52ad854. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [b400262](b400262) Co-authored-by: Nick Gambino <nicholas.gambino@consensys.net>
… user-enabled networks (#31154) - feat: scope QuickBuy networks to user-enabled networks (#31092) ## **Description** QuickBuy's "Pay with" / "Receive" screen was showing network pills (and token rows) for **every** candidate network, including ones the user never enabled (e.g. HyperEVM, Sei, Tempo). Some of those also rendered as **"Unknown network"** because they aren't present in the user's `NetworkController` state. This PR scopes QuickBuy to the networks the user has actually enabled and makes popular network names resolve to a readable label: 1. **Filter by enabled networks.** A new self-contained `useNetworkEnabledPredicate` hook returns a `(chainId) => boolean` predicate backed by `selectEVMEnabledNetworks` (hex) and `selectNonEVMEnabledNetworks` (CAIP), branching on `isNonEvmChainId`. It's applied at the token-options layer (`useSourceTokenOptions` and `useSellDestTokenOptions`) so pills, token rows, and default selection all stay consistent — disabled networks can't be implicitly selected. 2. **Readable fallback names.** `resolveNetworkDisplayName` now falls back to the curated `NETWORK_TO_NAME_MAP` for EVM hex and `eip155` CAIP chain IDs, so known popular networks (MegaETH, HyperEVM, …) show their real name instead of "Unknown network". The filtering lives in the hooks rather than the UI component, keeping the existing `useIsNetworkEnabled` per-chain hook untouched. ## **Changelog** CHANGELOG entry: Fixed QuickBuy showing networks the user hasn't enabled and labeling some networks as "Unknown network". ## **Related issues** Fixes: [TSA-617](https://consensyssoftware.atlassian.net/browse/TSA-617) and [TSA-620](https://consensyssoftware.atlassian.net/browse/TSA-620) ## **Manual testing steps** ```gherkin Feature: QuickBuy network scoping Scenario: Receive screen hides disabled networks Given a network such as Sei is not enabled When the user opens QuickBuy and views the "Receive" screen Then no pill or token row is shown for Sei Scenario: Enabling a network reveals it in QuickBuy Given the user enables Sei via the network selector When the user re-opens the QuickBuy "Receive" screen Then a pill and token rows for Sei are shown Scenario: Popular networks show a readable name Given MegaETH/HyperEVM are not configured in NetworkController When their pill is rendered Then the curated network name is shown instead of "Unknown network" ``` ## **Screenshots/Recordings** ### **Before** <img width="1170" height="2532" alt="image" src="https://github.com/user-attachments/assets/73a6afd1-4c20-46ff-bfb7-5d3796252d45" /> ### **After** <img width="392" height="414" alt="image" src="https://github.com/user-attachments/assets/bb4ff5b7-98fd-487f-b7cc-a0f62ab9fee5" /> ## **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. #### Performance checks (if applicable) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] 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 - [x] 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. Made with [Cursor](https://cursor.com) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > UI filtering and display-name fallbacks only; no auth, transactions, or persistence changes beyond existing enablement selectors. > > **Overview** > QuickBuy **Pay with** / **Receive** lists now only include tokens on networks the user has enabled, via a new `useNetworkEnabledPredicate` hook wired into `useSourceTokenOptions` and `useSellDestTokenOptions` so pills, rows, and defaults stay aligned. > > **Network labels:** `resolveNetworkDisplayName` falls back to curated `NETWORK_TO_NAME_MAP` (e.g. MegaETH, HyperEVM) when a chain isn’t in `NetworkController` state, including `eip155` CAIP IDs. `NETWORK_TO_NAME_MAP` build is guarded when `NETWORK_CHAIN_ID` is undefined in tests so UI imports don’t throw at module load. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit ba0104a. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [TSA-617]: https://consensyssoftware.atlassian.net/browse/TSA-617?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --------- Co-authored-by: Cursor <cursoragent@cursor.com> [ec2914b](ec2914b) [TSA-617]: https://consensyssoftware.atlassian.net/browse/TSA-617?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ Co-authored-by: Xavier Brochard <xavier.brochard@consensys.net> Co-authored-by: Cursor <cursoragent@cursor.com>
…ctMarketHighlights cp-7.81.0 (#31161) - feat(predict): support series ids in predictMarketHighlights cp-7.81.0 (#31044) <!-- 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? --> Extends the `predictMarketHighlights` remote feature flag to accept series IDs in addition to market IDs, and renders series-resolved crypto up/down highlights in horizontally-scrolling carousels via a new compact card variant. **Why** Recurring crypto up/down markets (e.g. "BTC Up or Down — 5 Minutes") expose a new market every N minutes. A market-ID pin in `predictMarketHighlights` therefore goes stale within a single time slot — once the market resolves, the pin disappears, and there is no way to express "always pin the currently-live BTC Up/Down 5m market." Resolving from a series at request time fixes this: the pin automatically rotates to whatever slot is live when the feed is fetched. **Schema change (additive, backward compatible)** ```ts export interface PredictMarketHighlight { category: string; markets?: string[]; // was required, now optional series?: string[]; // NEW } ``` - Existing LD flag values that only use `markets` continue to work unchanged. Both fields are now optional; entries with neither are skipped. - The controller's highlight block fetches `getMarketsByIds(markets)` and `getMarketSeries(seriesId)` in parallel via `Promise.all`, then resolves each series response to its currently-live market via the existing `findLiveMarket()` (with `findNearestMarket()` as a fallback when no future market is in the fetch window). - Resolved series markets pass through the same `status === 'open'` filter and are marked with `isHighlighted: true`, identical to the market-ID path. - Order: market-ID highlights are prepended first, then series-resolved highlights, then the regular feed. Existing flag values that only use `markets` keep their original ordering. Dedupe is unified across both paths so a market reachable via both `markets` and `series` appears exactly once. **Compact carousel variant** `PredictCryptoUpDownMarketCard` now has two render variants, keyed off the existing `isCarousel` prop that `PredictMarket` forwards to its sibling cards (`PredictMarketSingle`, `PredictMarketMultiple`, `PredictMarketSportCard`): - **Full** (`isCarousel=false`, the default) — the existing sparkline + target-line / target-price treatment used on `PredictFeed`, `PredictHome`, the wallet home carousel, and search. - **Compact** (`isCarousel=true`) — drops the sparkline and target labels and switches to a `height: 100%` + flex-column + `justifyContent: 'space-between'` layout that mirrors `PredictMarketSingle` / `PredictMarketMultiple` so the card sits flush with its neighbours in `HorizontalCarousel`. This is the variant the 5 TrendingView carousel tabs (Now, Macro, RWAs, Crypto, Sports) render for series-resolved highlights. The compact path also gates `useCryptoUpDownChartData` and `useCryptoTargetPrice` with `enabled: !isCompact`, so the chart historical fetch and live-price websocket subscription don't run for cards that never display them. **Resilience** - Per-series fetch failures are caught locally with a `DevLogger.log`, so one unhealthy series entry can't take down a healthy batch. - The series fetch reuses the canonical `SERIES_MAX_EVENTS` (50) for `limit`. The provider returns markets in `endDate ASC` order, and a fast recurrence (5m) can produce ~12 past events inside the past buffer alone — too low a limit would clip the live slot. - `getMarketsByIds` keeps its existing fail-hard contract; the previously misleading test `"handles getMarketsByIds failure gracefully"` (which actually only tested an empty-array result) was renamed accordingly, and a real rejection-propagation test was added. **Test coverage** - 8 new tests in `PredictController.test.ts` (live-market resolution, mixed markets+series ordering, nearest-market fallback, empty-series skip, closed-market status filter, throw-silent on single series, partial-batch failure, dedupe across paths) - 1 shape-passthrough test in `resolvePredictFeatureFlags.test.ts` - 4 new tests in `PredictCryptoUpDownMarketCard.test.tsx` covering the compact variant (sparkline not rendered, both chart queries gated with `enabled: false`, compact skeleton renders, buy sheet still opens) - All tests in the touched suites pass. ## **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 support for pinning the currently-live market of a recurring series (e.g. BTC Up/Down 5m) via the `predictMarketHighlights` remote feature flag. ## **Related issues** Fixes: PRED-950 ## **Manual testing steps** Both scenarios assume the `predictMarketHighlights` LaunchDarkly variation is updated to the new shape. The series ID `10684` corresponds to the Polymarket Gamma `BTC Up/Down 5m` series (also hardcoded as `BTC_UP_DOWN_5M_SERIES_ID` in `app/components/UI/Predict/constants/btcUpDown5mSeries.ts`). ```gherkin Feature: Series-id highlights in predictMarketHighlights Scenario: A series-id highlight resolves to the currently-live market on PredictFeed Given the predictMarketHighlights flag is set to """ { "enabled": true, "minimumVersion": "7.63.0", "highlights": [ { "category": "crypto", "series": ["10684"] } ] } """ When the user opens the Predict tab and switches to the "Crypto" feed tab Then the currently-live BTC Up/Down 5m market is pinned at the top of the feed And the pin auto-rotates to the next live slot when the current one resolves And the card renders in the full variant (with sparkline + target labels) Scenario: A series-id highlight renders the compact variant in TrendingView carousels Given the same flag configuration as above When the user opens the Explore page and views the "Crypto" or "Now" tab carousel Then the BTC Up/Down series card IS pinned in the Explore carousel And it renders as the compact variant (no sparkline, same height as its neighbours) And no chart-history fetch or live-price websocket subscription is opened for that card Scenario: Existing market-id highlights are unaffected Given the predictMarketHighlights flag is set to """ { "enabled": true, "highlights": [ { "category": "trending", "markets": ["451614"] } ] } """ When the user opens PredictFeed → Trending and Explore → Now Then market 451614 is pinned at the top on both surfaces (market-id path is unchanged) ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** N/A <!-- [screenshots/recordings] --> ### **After** N/A <!-- [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 - [x] 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 - [x] 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] > **Medium Risk** > Feed ordering and highlight resolution now depend on series API behavior and remote flag shape; carousel gating changes which data loads on Explore surfaces. > > **Overview** > Adds optional **`series`** IDs to **`predictMarketHighlights`** so recurring crypto up/down pins resolve to the **currently live** market via **`getMarketSeries`** + **`findLiveMarket`** / **`findNearestMarket`**, merged with existing market-ID highlights (parallel fetch, dedupe, open-only, market IDs first). > > **`PredictCryptoUpDownMarketCard`** now honors **`isCarousel`**: a **compact** layout (no sparkline/target UI, full-height flex) and **`enabled: false`** on chart/target hooks to avoid unused network work in Explore carousels; full feed cards unchanged with **`enabled: true`** on chart data. > > Controller tests cover series resolution edge cases; **`getMarketsByIds`** failures now **reject** instead of being mislabeled as graceful handling. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 83f5c75. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [c32e24f](c32e24f) Co-authored-by: hunty <hunter.goodreau@consensys.net>
…d purge seeded orders (#31229) - fix(ramps): remove Navigation Dev Panel and purge seeded orders cp-7.81.0 (#31188) <!-- 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. --> <!-- mms-check directive vocabulary — read by .github/scripts/shared/pr-template-checks.ts at module load to build the validation plan. Directives are invisible in rendered markdown and must NOT be removed or edited without updating the validator registry. type=text Section must contain non-placeholder prose. type=changelog Section must have a valid CHANGELOG entry: line. type=issue-link Section must have a Fixes:/Closes:/Refs: line with a value. type=manual-testing Section must have real testing steps or an explicit N/A.
… with quote loader (#31238) - fix(quick-buy): enable Buy CTA in lockstep with quote loader (#31218) ## **Description** In the QuickBuy bottom sheet, the **Buy** button sometimes took longer to become enabled than the amount-section quote loader took to disappear. The user expects the CTA to become tappable as soon as the quote completes. **Reason for the change:** the loader and the Buy button were gated by two conditions that drifted out of sync for one render. The loader is driven by `isBlockingQuoteLoad` (gated by `isQuoteLoading`), which clears the instant the fetch resolves. The button is gated by `isConfirmDisabled`, which includes `isPendingQuoteRefresh` — and that value was derived from `settledSourceTokenAmountRef`, a ref updated only inside a post-commit `useEffect`. On the render where the quote arrived, the loader hid but the ref had not caught up, and ref writes do not schedule a re-render, so the CTA only re-enabled on the next unrelated render (a redux tick, gas-estimate update, quote countdown, etc.) — producing the variable lag. **Solution:** replace the timing/effect-based "settled amount" tracking with a synchronous derivation. A displayed quote is for the current amount when the quote's own `srcTokenAmount` equals the requested amount (the request is built with `calcTokenValue(sourceTokenAmount, decimals).toFixed(0)` and the bridge echoes that exact value back). `isPendingQuoteRefresh` now derives from this synchronous check, so `isBlockingQuoteLoad` and `isConfirmDisabled` settle on the **same render** the matching quote lands. Background refreshes of the same amount keep `srcTokenAmount` unchanged, so the CTA stays enabled as before. ## **Changelog** CHANGELOG entry: Fixed the QuickBuy Buy button sometimes staying disabled briefly after the quote finished loading. ## **Related issues** Fixes: An issue where he QuickBuy Buy button sometimes staying disabled briefly after the quote finished loading. ## **Manual testing steps** ```gherkin Feature: QuickBuy Buy button enablement Scenario: Buy button enables as soon as the quote loads Given I open the QuickBuy bottom sheet for a token When I enter or select an amount and the quote loader spins Then the loader disappears when the quote completes And the Buy button becomes enabled on the same frame (no lag) Scenario: Buy button stays disabled while a new amount is being quoted Given a quote is already displayed for an amount When I change the amount so a new quote is fetched Then the Buy button is disabled until the quote for the new amount arrives ``` ## **Screenshots/Recordings** ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] 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 - [x] 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. Made with [Cursor](https://cursor.com) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Localized QuickBuy confirm/disable logic with added unit tests; no auth, submission, or bridge API changes beyond when the button enables. > > **Overview** > Fixes QuickBuy **Buy** staying disabled briefly after the quote loader finishes by replacing post-commit ref tracking of the “settled” amount with a synchronous **`isActiveQuoteForCurrentAmount`** check. > > **`isPendingQuoteRefresh`** now derives from whether the on-screen quote matches the committed amount: atomic units from **`calcTokenValue`** on the requested **`sourceTokenAmount`** are compared to **`activeQuote.sentAmount`** (full wallet deduction), not **`quote.srcTokenAmount`**, so gas-included/sponsored quotes still enable the CTA when the displayed quote is valid. > > Tests add default **`sentAmount`** on quote fixtures plus cases for same-render loader/CTA sync and post-fee **`srcTokenAmount`** with matching **`sentAmount`**. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 4124eb2. 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: Cursor <cursoragent@cursor.com> [c09f43c](c09f43c) Co-authored-by: Xavier Brochard <xavier.brochard@consensys.net> Co-authored-by: Cursor <cursoragent@cursor.com>
…y with and split Pay with/Receive flows (#31237) - fix(quick-buy): show all held tokens in Pay with and split Pay with/Receive flows (#31195) ## **Description** In the QuickBuy bottom sheet, the **Pay with** picker only listed a curated allowlist of native tokens and stablecoins. Tokens the user actually held (e.g. CAKE, UP, dogwifhat) were missing, so they couldn't pay with them. This PR: 1. **Fixes the missing tokens bug.** `usePayWithTokens` now sources every tradable token the user holds across the bridge-enabled source chains (same `useTokensWithBalance` source the Bridge/Swap pickers use), instead of a hardcoded candidate list. 2. **Cleanly splits the two flows.** The previously combined screen branched internally on `tradeMode`. It is now split into `QuickBuyPayWithScreen` (buy / "Pay with") and `QuickBuyReceiveScreen` (sell / "Receive"), both rendering a shared presentational `QuickBuyTokenSelectList`, routed by a small `QuickBuyTokenSelectScreen` dispatcher. 3. **Extracts shared logic.** Token balance/fiat/exchange-rate enrichment moved into a pure `enrichTokenBalance` helper reused by both the "Pay with" and "Receive" hooks, plus a shared `tokenKey` util. 4. **Fixes fiat display for non-USD users.** QuickBuy is USD-first (`currencyExchangeRate` is USD-per-token and the amount entry renders `$`). The balance fiat was computed from `usdConversionRate` but formatted with the user's selected currency, mislabeling a USD value as e.g. `€2000.00`. Fiat fields are now formatted as USD to match the value and the rest of the flow. ## **Changelog** CHANGELOG entry: Fixed QuickBuy "Pay with" not showing all tokens the user holds, and corrected the fiat amount currency shown for non-USD users. ## **Related issues** Fixes: [TSA-609](https://consensyssoftware.atlassian.net/browse/TSA-609) ## **Manual testing steps** ```gherkin Feature: QuickBuy Pay with held tokens Scenario: user pays with an arbitrary held token Given I hold tokens that are not stablecoins or natives (e.g. CAKE, UP, dogwifhat) When I open the QuickBuy bottom sheet and tap "Pay with" Then I see all of my held, tradable tokens listed And I can select one and continue to the amount screen Scenario: user on a non-USD currency sees correct fiat Given my display currency is set to EUR When I open the "Pay with" picker Then each token's fiat value is shown in USD ($), matching the amount screen Scenario: user selling a position picks a stablecoin to receive Given I open QuickBuy in sell mode When I tap "Receive" Then I see the stablecoin options with the position chain offered first ``` ## **Screenshots/Recordings** ### **Before** <img width="333" height="699" alt="image" src="https://github.com/user-attachments/assets/27e60e40-5121-46ef-b267-fc4abc8bb14f" /> ### **After** <img width="565" height="699" alt="image" src="https://github.com/user-attachments/assets/d6583b51-7aa4-4079-9ad0-a96c0f490306" /> ## **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. #### Performance checks (if applicable) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] 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 - [x] 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. Made with [Cursor](https://cursor.com) [TSA-609]: https://consensyssoftware.atlassian.net/browse/TSA-609?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes which tokens can fund trades and how USD rates are computed for amount entry; sell receive stables behavior is preserved but enrichment rules (no stable $1 fallback on Pay with) differ from the old hook. > > **Overview** > Fixes QuickBuy **Pay with** so users see **all held, tradable tokens** (via Bridge’s `useTokensWithBalance`) instead of a hardcoded native/stable allowlist, with strict pricing so only tokens with a resolvable USD rate appear. > > **Pay with** and **Receive** are split: buy uses `QuickBuyPayWithScreen`, sell uses `QuickBuyReceiveScreen`, both backed by shared `QuickBuyTokenSelectList` and routed by `QuickBuyTokenSelectScreen` on the existing `payWith` screen. > > Token balance/fiat/exchange-rate logic moves into pure `enrichTokenBalance` (used by new `usePayWithTokens` and `useReceiveTokens`); `sourceTokenCandidates` / `useSourceTokenOptions` are removed. Fiat labels in the picker are formatted as **USD** to match QuickBuy’s USD-first amount flow (fixes wrong currency symbol for non-USD display settings). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f31322e. 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: Cursor <cursoragent@cursor.com> [24729e4](24729e4) [TSA-609]: https://consensyssoftware.atlassian.net/browse/TSA-609?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ Co-authored-by: Xavier Brochard <xavier.brochard@consensys.net> Co-authored-by: Cursor <cursoragent@cursor.com>
<!-- 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. --> <!-- mms-check directive vocabulary — read by .github/scripts/shared/pr-template-checks.ts at module load to build the validation plan. Directives are invisible in rendered markdown and must NOT be removed or edited without updating the validator registry. type=text Section must contain non-placeholder prose. type=changelog Section must have a valid CHANGELOG entry: line. type=issue-link Section must have a Fixes:/Closes:/Refs: line with a value. type=manual-testing Section must have real testing steps or an explicit N/A. type=screenshot Section must have evidence (image/URL) or an explicit N/A. type=checklist Section must have all checkboxes consciously checked. required=true|false Whether a missing/invalid section blocks the PR check. Sections without a directive are checked for structural presence only. --> ## **Description** sync stable into 7.81.0 <!-- mms-check: type=text required=true --> <!-- 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** <!-- mms-check: type=changelog required=true --> <!-- 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: N/A ## **Related issues** <!-- mms-check: type=issue-link required=true --> Fixes: N/A ## **Manual testing steps** <!-- mms-check: type=manual-testing required=true --> N/A ## **Screenshots/Recordings** <!-- mms-check: type=screenshot required=true --> N/A <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** N/A <!-- [screenshots/recordings] --> ### **After** N/A <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- mms-check: type=checklist required=true --> <!-- 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 - [x] 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 - [x] 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** > Documentation-only CHANGELOG and release-link updates; no application or runtime code changes. > > **Overview** > **Updates `CHANGELOG.md` for a stable-branch release sync** by publishing a new **`[7.80.0]`** section and refreshing compare links at the bottom of the file. > > The **`7.80.0`** block documents shipped work under **Added** (e.g. explore swap conversion tracking, explore search V2 metrics, batch sell quotes setup, World Cup Predict tab), **Changed** (explore v2 simplification, Android 16KB page-size native dep patches, assets controller bump, pure-black dark mode flag, Tron snap bump), and **Fixed** (pure-black sheet surfaces, zero APY on money home, prediction markets no longer accepting bets). > > The **`[7.78.1]`** section is **expanded** beyond the existing WebSocket `CloseEvent` crash fix to include a large set of **Added** and **Fixed** bullets (Money Account, Card, Predict, Explore, Rewards, swaps/bridge, onboarding, etc.) that are now grouped under that patch version. > > **Link footer:** `[Unreleased]` now points at `v7.80.0...HEAD`, and a new **`[7.80.0]`** compare URL (`v7.78.0...v7.80.0`) is added. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit d6e1e8f. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…ick buy when only viewed token held (#31403) - fix(token-details): cp-7.81.0 show swap/quick buy when only viewed token held (#31393) ## **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? --> On the Token Details screen, the Swap button and the QuickBuy (lightning/flash) icon were both gated on `selectHasEligibleSwapSource`, which the footer called with the currently-viewed token **excluded**. As a result, **a user whose only funded asset was the token they were viewing (e.g. holding only ETH, on the ETH page) saw neither control, and only the fiat Buy fallback was shown**. This is incorrect: the swap handler (`useHandleOnSwap`) already swaps the held token *away* when the user holds it, and QuickBuy's sell mode operates on the position token. So holding only the viewed token is a perfectly valid reason to surface Swap and QuickBuy. The fix calls the selector with no exclusion args in `useStickyTokenActions`, so the viewed token counts as a fundable/swappable asset. The selector's optional `excludedChainId` / `excludedAddress` parameters are intentionally retained for any future caller that genuinely needs "any funded asset except X". Behavioral delta: for a held token that is not fiat-buyable and with no other holdings, the Buy on-ramp fallback no longer shows; Swap is shown instead. For buyable tokens (e.g. ETH) both still show. ## **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 the Swap and Quick Buy buttons not appearing on the token details screen when the only funded asset was the token being viewed. ## **Related issues** Fixes: Issue where the Swap button wouldn't show, preventing me from swapping a token I actually hold. ## **Manual testing steps** ```gherkin Feature: Token details trade actions for a single-asset wallet Scenario: User holding only the viewed token sees Swap and Quick Buy Given my wallet holds a positive balance of only one token (e.g. ETH) And I have no other funded assets When I open the Token Details screen for that token Then the Swap button is visible And the Quick Buy (lightning) icon is visible And tapping Quick Buy opens the QuickBuy sheet where I can sell the token ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <img width="1440" height="805" alt="image" src="https://github.com/user-attachments/assets/4e58144c-218a-473c-ad91-88c06c01499a" /> ### **After** <img width="694" height="919" alt="image" src="https://github.com/user-attachments/assets/b095e246-7584-41c1-a19f-01492669cd16" /> ## **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. #### Performance checks (if applicable) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] 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 - [x] 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** > Localized change to swap-eligibility gating and footer visibility on Token Details; no auth, payments, or data-layer changes. > > **Overview** > Fixes Token Details **Swap** and **Quick Buy** staying hidden when the user’s only funded asset is the token on screen. > > `useStickyTokenActions` no longer passes the viewed token into `selectHasEligibleSwapSource` as an exclusion. **`selectHasEligibleSwapSource`** is simplified to a state-only check: any asset with positive fiat balance counts, including the current token, since that balance is a valid swap source. > > Tests now assert the hook uses the selector without exclusions and that a single funded “viewed” token yields eligibility **true**. For wallets with only one non–fiat-buyable holding, the footer may show **Swap** instead of the Buy on-ramp fallback when swap eligibility is true. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 5722fd1. 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: Cursor <cursoragent@cursor.com> [5edcc2c](5edcc2c) Co-authored-by: Xavier Brochard <xavier.brochard@consensys.net> Co-authored-by: Cursor <cursoragent@cursor.com>
This PR updates the change log for 7.81.0. (Hotfix - no test plan generated.) --------- Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com> Co-authored-by: tommasini <tommasini15@gmail.com> Co-authored-by: tommasini <46944231+tommasini@users.noreply.github.com>
…ial carousel Rive animations cp-7.81.0 (#31557) - fix(perps): prevent Android crash in tutorial carousel Rive animations cp-7.81.0 (#31547) ## **Description** The Perps "Learn the basics" tutorial carousel crashes on Android when navigating through the screens. **Root cause:** `ScrollableTabView` renders all child tabs simultaneously, which means 4–5 `<Rive>` components (one per tutorial screen with an animation) are all mounted with `autoplay={true}` at the same time. On Android, the Rive native renderer cannot handle multiple concurrent GPU-accelerated animation instances and crashes. **Fix:** Only mount the `<Rive>` component for the currently visible tab (`currentTab === index`). This ensures a single native Rive renderer instance exists at any time. When the user swipes or taps Continue, the previous instance is unmounted and the next one takes its place. iOS is unaffected because its Metal rendering pipeline handles concurrent Rive instances more gracefully. ## **Changelog** CHANGELOG entry: Fixed a crash on Android when navigating through the Perps tutorial carousel ## **Related issues** Fixes: #31540 ## **Manual testing steps** ```gherkin Feature: Perps tutorial carousel stability on Android Scenario: user completes the full tutorial without crash Given the user has not completed the Perps tutorial When user taps Perps and goes through "Learn the Basics of Perps" Then the app does not crash And all tutorial screens display their Rive animations correctly Scenario: user re-enters tutorial from Perps home Given the user is on the Perps home screen When user scrolls down and taps "Learn the Basics of Perps" And user taps Continue through all screens Then the app does not crash And the user reaches the final screen successfully ``` ## **Screenshots/Recordings** N/A — no visual change; this is a crash fix. The tutorial screens render identically, only one Rive animation is mounted at a time instead of all simultaneously. ### **Before** App crashes on Android when navigating through tutorial carousel screens. ### **After** Tutorial carousel completes without crash on Android. ## **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. #### Performance checks (if applicable) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] 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 - [x] 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** > Single conditional around Rive mounting in the tutorial carousel; behavior is unchanged except avoiding concurrent animations on Android. > > **Overview** > Fixes an **Android crash** in the Perps “Learn the basics” tutorial by ensuring only one native **Rive** animation is mounted at a time. > > `ScrollableTabView` keeps every tab’s children in the tree, so every screen with `riveArtboardName` used to mount `<Rive autoplay>` together. The change adds `index` in the screen map and renders the animation only when **`currentTab === index`**, so swiping or tapping Continue unmounts the previous instance before the next one loads. No intended UI change on iOS. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 17b73bc. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [fe7877a](fe7877a) Co-authored-by: Michal Szorad <michal.szorad@consensys.net>
… and related components (7.81.0) (#31568) ## Summary Cherry-pick of one merged PR from `main` into `release/7.81.0`: - #31465 - feat: update World Cup event count in PredictionsSection and related components ## Related - Cherry-pick of b54fda6 from main CHANGELOG entry: null <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Read-only homepage UI and a lightweight Polymarket fetch; no auth or payment paths. Main risk is wrong/missing subtitle if the pagination API fails. > > **Overview** > The homepage Predict World Cup discovery row now shows **total event count from Polymarket’s `/events/pagination` API** (via new `useHomepagePredictWorldCupEventCount`) instead of inferring it from how many markets were loaded and `hasMore`. > > `PredictionsSection` loads and refetches that count with the World Cup/NBA discovery feeds, includes it in loading state, and passes `worldCupEventCount` into the discovery UI. **`HomepagePredictWorldCupDiscovery`** always uses the overflow copy (e.g. `48+ events in total`) when a numeric total exists, and **`MensWorldCupRow`** hides the subtitle until the count is available. Tests and React Query mocks were updated for the new hook and label behavior. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit b54fda6. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
) - chore: bump `network-controller` and `controller-utils` cp-7.81.0 (#31128) <!-- 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. --> <!-- mms-check directive vocabulary — read by .github/scripts/shared/pr-template-checks.ts at module load to build the validation plan. Directives are invisible in rendered markdown and must NOT be removed or edited without updating the validator registry. type=text Section must contain non-placeholder prose. type=changelog Section must have a valid CHANGELOG entry: line. type=issue-link Section must have a Fixes:/Closes:/Refs: line with a value. type=manual-testing Section must have real testing steps or an explicit N/A. type=screenshot Section must have evidence (image/URL) or an explicit N/A. type=checklist Section must have all checkboxes consciously checked. required=true|false Whether a missing/invalid section blocks the PR check. Sections without a directive are checked for structural presence only. --> ## **Description** <!-- mms-check: type=text required=true --> <!-- 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? --> Bumping `@metamask/network-controller` to `^32.0.0` and `@metamask/controller-utils` to `^12.1.0`: ```markdown ## [32.0.0] ### Changed - **BREAKING:** Remove Sei, MegaETH, Avalanche, and ZKSync from list of default networks ([#8767](MetaMask/core#8767)) - You will need to add them as network configurations first before switching to them. - Bump `@metamask/controller-utils` from `^12.0.0` to `^12.1.0` ([#8774](MetaMask/core#8774)) ``` ## **Changelog** <!-- mms-check: type=changelog required=true --> <!-- 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** <!-- mms-check: type=issue-link required=true --> Closes: https://consensyssoftware.atlassian.net/browse/WPN-1239 ## **Manual testing steps** <!-- mms-check: type=manual-testing required=true --> - Onboard as new user on a fresh install - Observe that zkSync, Avalanche, and MegaETH are not enabled by default ## **Screenshots/Recordings** <!-- mms-check: type=screenshot required=true --> <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** N/A <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> N/A ## **Pre-merge author checklist** <!-- mms-check: type=checklist required=true --> <!-- 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 - [x] 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 - [x] 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] > **Medium Risk** > The breaking default-network removal can affect users or flows that relied on Avalanche, ZKSync, MegaETH, or Sei being preconfigured; otherwise this is primarily a dependency and test-fixture alignment change. > > **Overview** > Bumps **`@metamask/network-controller`** to **32.0.0** and **`@metamask/controller-utils`** to **12.1.0** (including `package.json` resolutions and `yarn.lock`). > > That **breaking** network-controller release drops **Sei, MegaETH, Avalanche, and ZKSync** from built-in default EVM networks, so fresh installs no longer ship those chain configs unless users add them manually. > > Test fixtures are aligned: **`initial-background-state.json`** no longer seeds MegaETH, ZKSync, or Avalanche mainnet entries, and **`AddressSelector.test.tsx`** updates the expected EVM-only network list to match. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit a8aa9b6. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [6d27922](6d27922) Co-authored-by: Michele Esposito <34438276+mikesposito@users.noreply.github.com>
) - fix(predict): keep time-slot scroll anchored left when live slot expires cp-7.81.0 (#31231) ## **Description** This PR bundles four UI/behavior fixes on the Predict **crypto up/down** details screen (plus one shared positions tweak). All changes are confined to `app/components/UI/Predict/`. **1. Time-slot picker loses its left anchor when the live slot expires (primary fix)** When the live time slot expired and rolled to the next window, the horizontal `TimeSlotPicker` no longer kept the live/selected pill anchored at the left. Root cause: the auto-scroll read pill x-coordinates from a cached `pillPositions` map that (1) retained stale entries for markets that had been filtered out, and (2) was read by a fixed 50ms settle timer that raced ahead of React Native's async re-layout — so `scrollTo` used the pre-shift offset and over-scrolled. - Prune `pillPositions` to only currently-rendered markets whenever `markets` changes. - Re-run the settle-delay anchor on the ordered `marketsKey` so a left shift re-anchors even when the resolved selection is unchanged. - Re-anchor immediately when the selected pill reports a new layout `x`, beating the timer/layout race. - Adds a regression test that reproduces the expiry race (verified failing pre-fix, passing post-fix). **2. Even spacing around the time-slot picker** The picker is a flush `h-11` container with no vertical padding of its own, so the gap above (title `pb-3` = 12px) and below (price summary `pt-5` = 20px) were uneven. Changed the price-summary top padding `pt-5 → pt-3` so the picker has equal 12px above and below. **3. Centered separator dot in positions rows** The `Up/Down · entry` separator dot was baseline-glued to the entry label via a `' · '` string, so it sat slightly off-center. Split it into its own `Text` node so it aligns optically in the center-aligned row. **4. Remove the `$100 → $X` payout preview from the up/down CTA + grow the chart** Removed the payout estimate under the buy buttons on the crypto up/down details page by no longer passing `showPayoutEstimate` to the shared `PredictMarketDetailsActions`. The prop, formatter, and gated rendering remain intact on that component for any other surface that wants the preview (none currently enable it), so the change is regression-safe. The freed vertical space is reclaimed by growing the with-positions chart height (ratio `0.4 → 0.44`, max `380 → 430`) so the chart fills the gap above the sticky actions while keeping the first position row visible and the rest scrollable. ## **Changelog** CHANGELOG entry: Fixed the Predict crypto up/down time-slot selector so the live slot stays anchored to the left when it rolls to the next window, evened out the spacing around the selector, and removed the payout estimate from the buy buttons to give the price chart more room. ## **Related issues** Refs: No external ticket — incremental UX polish on the Predict crypto up/down details screen reported during QA review (live-slot scroll anchoring regression, uneven selector spacing, off-center separator dot, payout-preview removal + chart sizing). ## **Manual testing steps** ```gherkin Feature: Predict crypto up/down details screen Scenario: Live time slot stays anchored left when it expires Given I am on a crypto up/down market details screen And the live time slot is the left-most pill in the selector When the live slot expires and the next slot becomes live Then the new live slot is anchored to the left edge of the selector And the selector is not over-scrolled or visually shifted Scenario: Time-slot selector is evenly spaced Given I am on a crypto up/down market details screen Then the vertical space above and below the time-slot selector is equal Scenario: Separator dot is centered in a position row Given I am on a crypto up/down market details screen And I hold at least one position in the series Then the dot between the outcome label and the entry price is vertically centered Scenario: No payout preview under the buy buttons and chart fills the space Given I am on a crypto up/down market details screen Then no "$100 -> $..." payout estimate is shown under the Up and Down buttons And the price chart uses the freed space above the sticky action buttons Scenario: First position visible and the rest scroll Given I am on a crypto up/down market details screen And I hold more positions than fit on screen Then the first position row is visible above the sticky action buttons And the remaining position rows are reachable by scrolling ``` ## **Screenshots/Recordings** ### **Before** N/A — author to attach device capture before marking Ready for review (changes are visual layout tweaks on the crypto up/down details screen that need a simulator/device to record). ### **After** N/A — author to attach device capture before marking Ready for review. ## **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. #### Performance checks (if applicable) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] 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 - [x] 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** > Predict UI-only changes in TimeSlotPicker and crypto up/down details; scroll logic is covered by new tests with no auth or data-path impact. > > **Overview** > Fixes **Predict crypto up/down** layout and **TimeSlotPicker** scroll behavior when a live slot rolls off. > > **Time slot picker:** When the live pill disappears and the list shifts left, horizontal scroll no longer drifts off the left edge. Stale `pillPositions` entries are pruned, anchoring re-runs on `marketsKey` changes, and the selected pill’s `onLayout` re-scrolls immediately so a 50ms timer doesn’t win a race against re-layout. Regression tests cover initial anchor and post-expiry re-anchor. > > **Details screen polish:** Price-summary top padding is tightened (`pt-5` → `pt-3`) so spacing above/below the picker matches. With positions, the chart grows (ratio **0.44**, max **430px**) after dropping the buy-button payout estimate (`showPayoutEstimate` no longer passed). **Position rows:** the `·` separator is its own `Text` node for better vertical alignment with the outcome/entry labels. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 8308aa7. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [a41a3ca](a41a3ca) Co-authored-by: hunty <hunter.goodreau@consensys.net>
…nt count in English localization cp-7.81.0 (#31582) - fix(locales): update overflow text for event count in English localization cp-7.81.0 (#31566) <!-- 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. --> <!-- mms-check directive vocabulary — read by .github/scripts/shared/pr-template-checks.ts at module load to build the validation plan. Directives are invisible in rendered markdown and must NOT be removed or edited without updating the validator registry. type=text Section must contain non-placeholder prose. type=changelog Section must have a valid CHANGELOG entry: line. type=issue-link Section must have a Fixes:/Closes:/Refs: line with a value. type=manual-testing Section must have real testing steps or an explicit N/A. type=screenshot Section must have evidence (image/URL) or an explicit N/A. type=checklist Section must have all checkboxes consciously checked. required=true|false Whether a missing/invalid section runs the validator at all. blocking=true|false Whether a failure of this check fails the CI workflow. Default: false — failures are shown as warnings in the sticky comment but do not block the PR. Sections without a directive are checked for structural presence only. --> ## **Description** <!-- mms-check: type=text required=true --> <!-- 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? --> Updates the World Cup homepage discovery overflow copy from “events in total” to “markets in total”. This matches the product language for the overflowing World Cup market count while leaving the normal non-overflow event count unchanged. ## **Changelog** <!-- mms-check: type=changelog required=true blocking=true --> <!-- 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: Updated World Cup discovery copy to say markets instead of events for overflowing counts. ## **Related issues** <!-- mms-check: type=issue-link required=true --> Fixes: ## **Manual testing steps** <!-- mms-check: type=manual-testing required=true --> ```gherkin Feature: World Cup discovery card copy Scenario: user sees overflowing World Cup market count Given the Predictions homepage discovery card has more World Cup items than the display limit When the user views the World Cup discovery row Then the overflow count says "{{count}}+ markets in total" ``` ## **Screenshots/Recordings** <!-- mms-check: type=screenshot required=true --> <!-- 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** <!-- mms-check: type=checklist required=true --> <!-- 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-only English localization and test assertion change with no logic or data-handling impact. > > **Overview** > Updates World Cup homepage discovery **overflow** copy from “events” to **markets** so overflowing counts match product terminology. > > The English string `predict.homepage_discovery.events_in_total_overflow` now renders `{{count}}+ markets in total` instead of `{{count}}+ events in total`. The non-overflow key `events_in_total` is unchanged. The `PredictionsSection` test expectation for the discovery row was aligned with the new copy. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f19f028. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [c101846](c101846) Co-authored-by: Patryk Łucka <5708018+PatrykLucka@users.noreply.github.com>
) - fix(locales): update overflow text for event count in English localization cp-7.81.0 (#31566) <!-- 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. --> <!-- mms-check directive vocabulary — read by .github/scripts/shared/pr-template-checks.ts at module load to build the validation plan. Directives are invisible in rendered markdown and must NOT be removed or edited without updating the validator registry. type=text Section must contain non-placeholder prose. type=changelog Section must have a valid CHANGELOG entry: line. type=issue-link Section must have a Fixes:/Closes:/Refs: line with a value. type=manual-testing Section must have real testing steps or an explicit N/A. type=screenshot Section must have evidence (image/URL) or an explicit N/A. type=checklist Section must have all checkboxes consciously checked. required=true|false Whether a missing/invalid section runs the validator at all. blocking=true|false Whether a failure of this check fails the CI workflow. Default: false — failures are shown as warnings in the sticky comment but do not block the PR. Sections without a directive are checked for structural presence only. --> ## **Description** <!-- mms-check: type=text required=true --> <!-- 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? --> Updates the World Cup homepage discovery overflow copy from “events in total” to “markets in total”. This matches the product language for the overflowing World Cup market count while leaving the normal non-overflow event count unchanged. ## **Changelog** <!-- mms-check: type=changelog required=true blocking=true --> <!-- 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: Updated World Cup discovery copy to say markets instead of events for overflowing counts. ## **Related issues** <!-- mms-check: type=issue-link required=true --> Fixes: ## **Manual testing steps** <!-- mms-check: type=manual-testing required=true --> ```gherkin Feature: World Cup discovery card copy Scenario: user sees overflowing World Cup market count Given the Predictions homepage discovery card has more World Cup items than the display limit When the user views the World Cup discovery row Then the overflow count says "{{count}}+ markets in total" ``` ## **Screenshots/Recordings** <!-- mms-check: type=screenshot required=true --> <!-- 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** <!-- mms-check: type=checklist required=true --> <!-- 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-only English localization and test assertion change with no logic or data-handling impact. > > **Overview** > Updates World Cup homepage discovery **overflow** copy from “events” to **markets** so overflowing counts match product terminology. > > The English string `predict.homepage_discovery.events_in_total_overflow` now renders `{{count}}+ markets in total` instead of `{{count}}+ events in total`. The non-overflow key `events_in_total` is unchanged. The `PredictionsSection` test expectation for the discovery row was aligned with the new copy. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f19f028. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [c101846](c101846) Co-authored-by: Patryk Łucka <5708018+PatrykLucka@users.noreply.github.com>
…anvas override on Android to prevent Earn onboarding crash (#31586) - fix: remove RiveRenderer.defaultRenderer Canvas override on Android to prevent Earn onboarding crash (#31475) <!-- 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. --> <!-- mms-check directive vocabulary — read by .github/scripts/shared/pr-template-checks.ts at module load to build the validation plan. Directives are invisible in rendered markdown and must NOT be removed or edited without updating the validator registry. type=text Section must contain non-placeholder prose. type=changelog Section must have a valid CHANGELOG entry: line. type=issue-link Section must have a Fixes:/Closes:/Refs: line with a value. type=manual-testing Section must have real testing steps or an explicit N/A. type=screenshot Section must have evidence (image/URL) or an explicit N/A. type=checklist Section must have all checkboxes consciously checked. required=true|false Whether a missing/invalid section blocks the PR check. Sections without a directive are checked for structural presence only. --> ## **Description** <!-- mms-check: type=text required=true --> Removed the global `RiveRenderer.defaultRenderer(..., RiveRendererAndroid.Canvas)` call in `FoxLoader` during app init. Although this lived in the splash-screen loader, `defaultRenderer` is a process-wide setting that forced every Rive view in the app onto Android's Canvas renderer `Surface.lockCanvas path`. This caused the Money/Earn onboarding stepper to hard-crash `SIGABRT`/`SIGSEGV` on Android when the Rive view tore down during tab navigation, the worker thread called `lockCanvas` on an already-released Surface, leaving a pending JNI exception that ART aborted on. Tombstone confirmed on Pixel 6a / Android 16. Reverting to the default Rive GPU renderer removes the `lockCanvas` code path entirely. iOS is unaffected (already uses the GPU renderer). <!-- 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** <!-- mms-check: type=changelog required=true --> <!-- 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 an Android crash when entering Earn onboarding caused by the Rive Canvas renderer being forced app-wide. ## **Related issues** <!-- mms-check: type=issue-link required=true --> Fixes: #31166 #31167 ## **Manual testing steps** <!-- mms-check: type=manual-testing required=true --> ```gherkin Feature: Earn onboarding no longer crashes on Android Scenario: User enters Earn onboarding on Android after fresh install Given the app is built in release mode on a Pixel 6a (or equivalent) running Android 16 And the user has completed initial app load (FoxLoader splash animation plays) When the user taps the Money/Earn tab And the Rive onboarding stepper mounts Then the app does not crash And the onboarding animation renders and steps through normally Scenario: Splash animation still plays on Android Given a fresh launch on Android When the FoxLoader splash screen appears Then the fox Rive animation plays to completion without visual regressions ``` ## **Screenshots/Recordings** <!-- mms-check: type=screenshot required=true --> https://github.com/user-attachments/assets/32c75ebd-8a93-4afb-ae8b-250fe4540b4f ### **Before** ### Crash on open https://github.com/user-attachments/assets/75339490-e41f-4c42-9853-c6bce7baaffc ### Crash on close https://github.com/user-attachments/assets/8fe061e9-6e5d-4c21-8d46-06082783de90 ### **After** https://github.com/user-attachments/assets/32c75ebd-8a93-4afb-ae8b-250fe4540b4f ## **Pre-merge author checklist** <!-- mms-check: type=checklist required=true --> <!-- 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 - [x] 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 - [x] 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] > **Medium Risk** > Small splash-only change with process-wide rendering impact on Android; fixes a production crash but may reintroduce any original Canvas-renderer motivation (e.g. splash geometry). > > **Overview** > Removes the **Android-only** `RiveRenderer.defaultRenderer(..., RiveRendererAndroid.Canvas)` setup from `FoxLoader` so Rive is no longer forced app-wide onto the Canvas renderer during splash init. > > That global override affected every Rive view (not just the fox splash), which led to **SIGABRT/SIGSEGV** when Earn/Money onboarding Rive UI tore down during tab navigation (`lockCanvas` on a released Surface). **iOS is unchanged**; Android again uses Rive’s default GPU renderer. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit a212356. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [7929023](7929023) Co-authored-by: Vince Howard <vincenguyenhoward@gmail.com>
# 🚀 v7.81.0 Testing & Release Quality Process Hi Team, As part of our new **MetaMask Release Quality Process**, here’s a quick overview of the key processes, testing strategies, and milestones to ensure a smooth and high-quality deployment. --- ## 📋 Key Processes ### Testing Strategy - **Developer Teams:** Conduct regression and exploratory testing for your functional areas, including automated and manual tests for critical workflows. - **QA Team:** Focus on exploratory testing across the wallet, prioritize high-impact areas, and triage any Sentry errors found during testing. - **Customer Success Team:** Validate new functionalities and provide feedback to support release monitoring. ### GitHub Signoff - Each team must **sign off on the Release Candidate (RC)** via GitHub by the end of the validation timeline (**Tuesday EOD PT**). - Ensure all tests outlined in the Testing Plan are executed, and any identified issues are addressed. ### Issue Resolution - **Resolve all Release Blockers** (Sev0 and Sev1) by **Tuesday EOD PT**. - For unresolved blockers, PRs may be reverted, or feature flags disabled to maintain release quality and timelines. ### Cherry-Picking Criteria - Only **critical fixes** meeting outlined criteria will be cherry-picked. - Developers must ensure these fixes are thoroughly reviewed, tested, and merged by **Tuesday EOD PT**. --- ## 🗓️ Timeline and Milestones 1. **Today (Friday):** Begin Release Candidate validation. 2. **Tuesday EOD PT:** Finalize RC with all fixes and cherry-picks. 3. **Wednesday:** Buffer day for final checks. 4. **Thursday:** Submit release to app stores and begin rollout to 1% of users. 5. **Monday:** Scale deployment to 10%. 6. **Tuesday:** Full rollout to 100%. --- ## ✅ Signoff Checklist Each team is responsible for signing off via GitHub. Use the checkbox below to track signoff completion: # Team sign-off checklist - [x] Accounts - [x] Assets - [x] Bots Team - [x] Card - [x] Confirmations - [x] Core Platform - [x] Design System - [x] Earn - [x] Engagement - [x] MetaMask Product Operations - [x] Mobile Platform - [x] Mobile UX - [x] Money Movement - [x] Networks - [x] Onboarding - [x] Perps - [x] Predict - [x] Rewards - [x] Social & AI - [x] Swaps and Bridge - [x] team-release - [x] Transactions - [x] Wallet Integrations This process is a major step forward in ensuring release stability and quality. Let’s stay aligned and make this release a success! 🚀 Feel free to reach out if you have questions or need clarification. Many thanks in advance # Reference - Testing plan sheet - https://docs.google.com/spreadsheets/d/1tsoodlAlyvEUpkkcNcbZ4PM9HuC9cEM80RZeoVv5OCQ/edit?gid=404070372#gid=404070372
Contributor
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
This PR syncs the latest changes from
stableintorelease/7.82.0.Why is this needed?
A release branch (
release/7.81.0) was merged intostable. This PR brings those changes (hotfixes, etc.) intorelease/7.82.0.Action Required
Please review and resolve any merge conflicts manually.
If there are conflicts, they will appear in this PR. Resolve them to ensure the release branch has all the latest fixes from stable.