release: 7.78.0#30207
Conversation
<!-- CURSOR_AGENT_PR_BODY_BEGIN --> ## **Description** This change updates the DeFi empty-state `Explore DeFi` CTA behavior so it no longer opens the external MetaMask Portfolio explore tokens URL in the in-app browser. Instead, pressing the CTA now navigates users to the in-app Explore flow and opens the Explore **Sites** section (`TrendingView -> SitesFullView`), matching the requested product direction and avoiding the blank page issue. ## **Changelog** CHANGELOG entry: Fixed the DeFi empty-state Explore button to open the in-app Explore sites screen instead of an external portfolio page. ## **Related issues** Fixes: #29471 https://consensyssoftware.atlassian.net/browse/ASSETS-3133 ## **Manual testing steps** ```gherkin Feature: DeFi empty-state Explore CTA navigation Scenario: user opens Explore from empty DeFi tab Given the user is on the DeFi tab with no open positions When user taps the "Explore DeFi" button Then the app navigates to the Explore Sites screen And the app does not open portfolio.metamask.io/explore/tokens ``` ## **Screenshots/Recordings** ### **Before** N/A ### **After** https://www.loom.com/share/04b68f115a2c44a190bd7049b5ee323e https://www.loom.com/share/88e42d07ee06480a90abde1d4771add2 ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - [ ] I've tested with a power user scenario - [ ] I've instrumented key operations with Sentry traces for production performance metrics ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_AGENT_PR_BODY_END --> <div><a href="https://cursor.com/agents/bc-9cac285f-d4ce-4156-a35e-004942245eb2"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a href="https://cursor.com/background-agent?bcId=bc-9cac285f-d4ce-4156-a35e-004942245eb2"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </div> --------- Co-authored-by: Prithpal Sooriya <prithpal@example.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.
-->
## **Description**
This cleans up some unintentional text issues when displaying Ondo
assets in the Rewards tab. This makes the Rewards tab match how Ondo
assets are displayed elsewhere in the app.
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: null
## **Related issues**
Fixes: n/a
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-05-06 at 15 10 33"
src="https://github.com/user-attachments/assets/6b266c71-e1db-4e72-a30c-d8bcaab36fee"
/>
<!-- [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`.
-->
- [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**
> Low risk UI/text-only changes in Rewards Ondo views plus removal of a
now-unused formatting helper; primary risk is minor regressions in how
token names/units are displayed and in i18n key usage.
>
> **Overview**
> Rewards Ondo screens now **preserve backend-provided token display
names** (including the `(Ondo Tokenized)` suffix) instead of
stripping/truncating branding via `sanitizeOndoTokenName`, and
navigation to swaps passes the same unmodified name.
>
> Ondo portfolio rows adjust layout to truncate long names and change
the units subtext from a localized `"{{units}} shares"` string to a
direct `${units} ${TOKEN_SYMBOL}` format (uppercased), removing the
`position_units` i18n key and associated tests.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
60550e0. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** <!-- 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? --> This updates the direct MetaMask design system dependencies used by mobile to the latest published releases: - `@metamask/design-system-react-native`: `^0.22.0` -> `^0.23.0` - `@metamask/design-tokens`: `^8.3.0` -> `^8.4.0` - `@metamask/design-system-twrnc-preset` remains at `^0.4.2` because it is already current I reviewed the upstream changelog and migration docs before upgrading. The main breaking change in the new React Native package is the `Toast` static API redesign, plus `Input` readonly naming alignment and shared `AvatarGroup` contract updates. No mobile code changes were required in this branch because the app does not directly consume those changed design-system APIs today. Release notes and migration references: - MMDS releases: https://github.com/MetaMask/metamask-design-system/releases - React Native 0.23.0 notes: https://github.com/MetaMask/metamask-design-system/releases/tag/v38.0.0 - React Native changelog: https://github.com/MetaMask/metamask-design-system/blob/main/packages/design-system-react-native/CHANGELOG.md#0230 - React Native migration guide: https://github.com/MetaMask/metamask-design-system/blob/main/packages/design-system-react-native/MIGRATION.md#from-version-0220-to-0230 - Design tokens changelog: https://github.com/MetaMask/metamask-design-system/blob/main/packages/design-tokens/CHANGELOG.md#840 - Design tokens migration guide: https://github.com/MetaMask/metamask-design-system/blob/main/packages/design-tokens/MIGRATION.md ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** No issue: dependency maintenance upgrade for the latest MetaMask design system releases. ## **Manual testing steps** N/A ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** N/A ### **After** N/A ## **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. <!-- Generated with the help of the pr-description AI skill --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk dependency-only change, but it may introduce subtle UI/behavior differences if any screens consume updated design-system components indirectly. > > **Overview** > Upgrades design-system dependencies used by the app: `@metamask/design-system-react-native` to `^0.23.0` and `@metamask/design-tokens` to `^8.4.0`. > > Updates `yarn.lock` accordingly, including bumping transitive `@metamask/design-system-shared` to `^0.16.0`, with no app code changes beyond dependency versions. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 03812e9. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This PR syncs the stable branch to main for version 7.75.1. *Synchronization Process:* - Fetches the latest changes from the remote repository - Resets the branch to match the stable branch - Attempts to merge changes from main into the branch - Handles merge conflicts if they occur *File Preservation:* Preserves specific files from the stable branch: - CHANGELOG.md - bitrise.yml - android/app/build.gradle - ios/MetaMask.xcodeproj/project.pbxproj - package.json Indicates the next version candidate of main to 7.75.1
…9298) <!-- 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** Phase 2 cleanup of the Runway workflow split. Removes the legacy per-platform Runway entry workflows now that Runway has been flipped to dispatch the combined OTA-only and build-only workflows introduced in phase 1, and `release/7.73.x` / `release/7.74.x` are no longer actively maintained. ### Context Phase 1 (previous PR) added 5 new workflow files without touching anything existing: - `runway-ota-resolve-context.yml` - `runway-production-builds.yml` - `runway-rc-builds.yml` - `runway-ota-production.yml` - `runway-ota-rc.yml` That PR intentionally deferred the cleanup so Runway could keep dispatching the old per-platform workflow names against `release/7.73.x` and `release/7.74.x` (which cannot receive cherry-picks). ### What this PR does - **Deletes** the 4 legacy per-platform Runway entry workflows: - `runway-ios-production-workflow.yml` - `runway-android-production-workflow.yml` - `runway-ios-rc-workflow.yml` - `runway-android-rc-workflow.yml` - **Renames** `runway-ota-build-core.yml` → `auto-rc-ota-build-core.yml` to reflect that its only remaining caller is `build-rc-auto.yml` (auto-RC on push), not Runway. - **Refactors** the renamed core to call the reusable `runway-ota-resolve-context.yml` from phase 1 instead of keeping the `decide` + `resolve-pr` logic inline. Behaviour is identical; the logic is now shared with the OTA-only Runway workflows. - **Updates** `build-rc-auto.yml` `uses:` paths (two call sites) and the header comment to point at the renamed core. ### What this PR does NOT change - No behaviour change for `build-rc-auto.yml` — same OTA-vs-build auto-detection, same parallel platform dispatch, same Slack notification. - No behaviour change for the 4 phase-1 Runway workflows. ### Precondition for merge Before merging this PR, verify that: 1. Runway has been reconfigured to dispatch the 4 new workflow names (`runway-production-builds.yml`, `runway-rc-builds.yml`, `runway-ota-production.yml`, `runway-ota-rc.yml`). 2. `release/7.73.x` and `release/7.74.x` are no longer being hotfixed via Runway dispatch (they can still receive direct pushes — `build-rc-auto.yml` on those branches uses the files present on that ref, which still include the legacy core until those branches are fully retired). ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [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** > Moderate risk because it changes GitHub Actions workflow entry points and reusable workflow wiring for OTA-vs-build detection, which could break release/RC automation if references or outputs diverge. > > **Overview** > Refactors the auto-RC release flow by replacing the legacy reusable `runway-ota-build-core.yml` with a new `auto-rc-ota-build-core.yml` that delegates OTA bump/PR resolution to `runway-ota-resolve-context.yml`, while keeping the same OTA-vs-build branching behavior. > > Cleans up CI by deleting the four per-platform Runway `workflow_dispatch` entry workflows (iOS/Android, RC/production) and updating `build-rc-auto.yml` to call the renamed core workflow for both iOS and Android RC triggers. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 54fc5ee. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…ar (#29645) ## **Description** Bundle of polish items on the Money Home screen. - **MUSD-741** migrates the "X% APY" pill in the Money Home header from a hand-rolled `Box + Text` to the MMDS `Tag` component (severity = success), and bumps the inner text from `BodySm` (14px) to `BodyMd` (16px) so yield reads as a primary value prop. - **MUSD-743** removes the back chevron from the Money Home header. With Money now a top-level tab destination, the back button was misleading; the kebab on the right naturally aligns with the title via `HeaderStandard`'s built-in layout. - **MUSD-744** renders the global wallet action bar at the bottom of Money Home so the screen functions as a proper tab destination instead of a dead-end. Concretely: - The Money `Tab.Screen` is registered as `Routes.MONEY.ROOT` (instead of `Routes.MONEY.HOME`) and wired to `MoneyScreenStack`. This matches the existing `TabBar` handler which navigates to `Routes.MONEY.ROOT, { screen: Routes.MONEY.HOME }` — so the tab mounts with its inner stack and the global tab bar stays visible. - The outer `Stack.Screen` for `Routes.MONEY.ROOT` (which was pushing above `HomeTabs` and hiding the tab bar) is removed from `MainNavigator`. - All changes are inside `app/components/Nav/Main/MainNavigator.js` — no design-system-owned files are touched. - `MoneyFooter` ("Add money" CTA) was unpinned from its sticky-bottom position and now flows inside the `ScrollView` content as a normal section (`px-4 py-3`), with a single Divider above it (matching the section rhythm) and `paddingBottom: 40` on the scroll content. MUSD-747 will reintroduce sticky behaviour with peek-and-hide based on the onboarding stepper's viewport state. No analytics changes, no copy changes, no behavioural changes outside the navigation rewiring described above. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: - https://consensyssoftware.atlassian.net/browse/MUSD-741 - https://consensyssoftware.atlassian.net/browse/MUSD-743 - https://consensyssoftware.atlassian.net/browse/MUSD-744 ## **Manual testing steps** ```gherkin Feature: Money Home header polish + tab bar visibility Scenario: user opens Money Home via the bottom tab Given the Money Account feature flag is enabled When the user taps the Money tab in the bottom navigation Then Money Home renders with the global tab bar visible at the bottom And the "Money" tab is shown as active And no back chevron is rendered in the Money Home header And the options (kebab) icon sits in the top-right And the "X% APY" pill is rendered as an MMDS Tag at 16px text Scenario: Add money button placement Given Money Home is open When the user scrolls to the bottom of the page Then the "Add money" button renders inside the scroll content as the last section And it is preceded by the standard section divider And it has visible breathing room before the global tab bar ``` ## **Screenshots/Recordings** ### **Before** <!-- to be added --> ### **After** <!-- to be added --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - [ ] I've tested with a power user scenario - [ ] I've instrumented key operations with Sentry traces for production performance metrics ## **Pre-merge reviewer checklist** - [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** > Moderate risk due to navigation rewiring (Money tab now routes to `Routes.MONEY.ROOT`/`MoneyScreenStack` and a stack-level screen is removed), which could affect tab routing and back-stack behavior. UI/layout changes are otherwise straightforward and covered by updated tests. > > **Overview** > Makes Money a first-class bottom-tab destination by switching the conditional tab registration from `Routes.MONEY.HOME` to `Routes.MONEY.ROOT` and mounting `MoneyScreenStack` directly, while removing the extra `Routes.MONEY.ROOT` stack screen that previously sat above `HomeTabs` (keeping the global tab bar visible). > > Polishes Money Home UI: replaces the APY pill with the design-system `Tag`, updates the header to a title+menu-only `HeaderBase` (removing the back button), and simplifies the “Add money” footer from an animated/sticky overlay to a normal scroll section with fixed bottom padding; associated peek/hide stepper logic and its unit tests are deleted and component tests are updated accordingly. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit a742e0d. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description**
Adds a new **Money balance card** to the wallet home screen, slotted
between the
wallet action bar (Buy/Swap/Send/Receive) and the Carousel/Tokens block.
The
card surfaces the user's Money Account balance, current vault APY, and a
direct CTA to add funds — replacing the chevron-style "Money" section
pattern
described in the Money Home Review (April 30, 2026) for users on the new
wallet home.
The card has two visual states sharing one component:
- **Empty** (MUSD-431) — balance `$0.00`, **Secondary** "Add" button.
- **Funded** (MUSD-752) — live `totalFiatFormatted` from
`useMoneyAccountBalance`,
**Secondary** "Add" button. Switches as soon as `totalFiatRaw > 0`.
Other behaviour:
- Tap card body → navigates to Money home (`Routes.MONEY.ROOT`)
- Tap "Add" → `Routes.MONEY.MODALS.ADD_MONEY_SHEET` (same flow as the
existing
Money home Add pill)
- Tap info icon → new `MoneyBalanceInfoSheet` modal (registered
alongside the
existing APY/Earnings info sheets)
- Skeleton placeholders while balance/APY are loading
- Render-gated by `selectMoneyHomeScreenEnabledFlag &&
isHomepageSectionsV1Enabled`
The legacy `MoneyAccountHomeRow` and `CashSection` are intentionally
untouched
in this PR — they continue to serve users without the Money home flag.
## **Changelog**
CHANGELOG entry: Added a new Money balance card to the wallet home
screen showing the user's Money Account balance, vault APY, and a quick
action to add funds.
## **Related issues**
Fixes: MUSD-431, MUSD-752
## **Manual testing steps**
```gherkin
Feature: Money balance card on wallet home
Scenario: user with no Money balance sees the empty state
Given the Money home feature flag is enabled
And the homepage sections v1 flag is enabled
And the user has no Money Account balance
When the user opens the wallet home screen
Then the Money balance card is visible between the action bar and the tokens
And the balance shows "$0.00"
And the "Add" button uses the Secondary variant
And the "4% APY" tag is visible
Scenario: user with a Money balance sees the funded state
Given the Money home feature flag is enabled
And the homepage sections v1 flag is enabled
And the user has a Money Account balance greater than $0.00
When the user opens the wallet home screen
Then the Money balance card shows the live USD balance
And the "Add" button uses the Secondary variant
Scenario: user taps the Money balance card body
Given the Money balance card is visible
When the user taps anywhere on the card outside of the Add button or info icon
Then the app navigates to the Money home screen
Scenario: user taps the info icon on the Money balance card
Given the Money balance card is visible
When the user taps the info icon next to "Money balance"
Then the Money balance info sheet opens
Scenario: feature flag is off
Given the Money home feature flag is disabled
When the user opens the wallet home screen
Then the Money balance card is not rendered
```
## **Screenshots/Recordings**
### **Before**
### **After**
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- [ ] I've tested with a power user scenario
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
## **Pre-merge reviewer checklist**
- [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**
> Adds new wallet-home UI and navigation paths (including a new modal
route) gated by feature flags; risk is mainly around routing/press
handlers and empty-state logic but is localized and well-covered by
tests.
>
> **Overview**
> Adds a new `MoneyBalanceCard` on the wallet home header area (shown
only when `selectMoneyHomeScreenEnabledFlag` is on) that displays Money
balance + APY with loading skeletons, and provides CTAs to open the Add
Money sheet, navigate to Money Home, or start the mUSD conversion
education flow for new users.
>
> Introduces a new `MoneyBalanceInfoSheet` bottom-sheet modal and
registers it in the Money modal stack via new route
`Routes.MONEY.MODALS.MONEY_BALANCE_INFO_SHEET`, along with new i18n
strings for the card label and sheet copy.
>
> Removes the legacy `MoneyAccountHomeRow` component/tests and updates
`CashSection` so the entire Cash section is not rendered when the Money
home flag is enabled; updates/extends unit tests (Wallet flag-gated
rendering, Cash section null behavior, Money modal registration)
accordingly.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
dea4013. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** Four small UI/UX fixes for the What's Happening feature: 1. Home carousel card date visibility 2. Detail-view header size 3. Expanded card height consistency 4. in Tokens row the Buy button switched to Trade button, and now users should always be directed to Perps trade. When a token asset has an hlPerpsMarket entry the row now shows a Trade button navigating to Perps market details; otherwise it falls back to the existing Buy/Ramp flow. <img height="790" alt="Simulator Screenshot - iPhone 17 Pro - 2026-05-06 at 12 23 11" src="https://github.com/user-attachments/assets/d3a91506-e9d0-4182-a9ea-47732834268a" /> <img height="790" alt="Simulator Screenshot - iPhone 17 Pro - 2026-05-06 at 12 23 02" src="https://github.com/user-attachments/assets/2c40b688-b91b-4da5-9e10-d69bfc8b6844" /> <img height="790" alt="Simulator Screenshot - iPhone 17 Pro - 2026-05-06 at 12 01 23" src="https://github.com/user-attachments/assets/9b7371c3-4306-4794-be88-2671d0e01836" /> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Medium risk because it changes navigation behavior for token action buttons (routing some assets to Perps) and alters carousel/card layout rendering based on runtime measurement, which could affect visibility/scroll positioning across devices. > > **Overview** > Polishes What’s Happening UI by slightly increasing home carousel card heights, reducing card title lines to preserve footer/date visibility, and resizing the “View more” card to match. > > Updates the detail view header to a custom, smaller layout and makes the expanded-card carousel use a fixed measured `cardHeight`, gating card rendering and initial scroll positioning until layout is known; tests now simulate `onLayout` to validate rendering. > > Changes related-asset actions so token rows show **Trade** (navigating to Perps market details) when `hlPerpsMarket` is present, via new `useTradeNavigation`; `PerpsRow` is simplified to reuse the same hook, and `AssetRow` migrates to the design-system `Button` component. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 7edb172. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
## **Description**
- Replaces confirmed EVM Activity transactions with data from accounts
v4 API via React Query
- Adds infinite pagination for confirmed EVM history
- Keep local pending EVM transactions and existing non-EVM activity
unchanged
Note: Due to the API requesting a bearer token, there is a current
bottleneck in that token retrieval, in particular in
`AuthenticationController.getPrimaryEntropySourceId`
## **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: feat: use accounts API v4 for transactions
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: Accounts API v4 Transactions
Scenario: user views EVM activity
Given the wallet has EVM confirmed on-chain activity
When user visits the Activity tab
Then confirmed onchain transactions returned by the Accounts v4 API is displayed on screen.
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Moderate risk because it rewires the Activity/UnifiedTransactionsView
data source and filtering/deduping logic, which can change what
transactions appear and when pagination/refresh occurs.
>
> **Overview**
> **Confirmed EVM Activity now comes from the Accounts v4 API** via a
new React Query `useTransactionsQuery` hook, while local pending EVM
transactions continue to come from controller state and are
merged/deduped with the API results.
>
> Adds a small transformation layer (`helpers/adapters` +
`helpers/transformations`) to normalize API responses into
`TransactionMeta`-compatible view models, filter out unwanted items
(e.g. spam/incoming transfers/zero-value self-sends), and handle
bridge-history matching/deduping (including case-insensitive hash
matching).
>
> Updates `UnifiedTransactionsView` to support infinite scrolling
pagination (prefetch near the end of confirmed EVM items), show
initial/next-page loading indicators, and refresh both local polling and
the query. Related selector additions (`selectLocalTransactions`,
`selectRequiredTransactionHashes/Ids`) support filtering required child
txs and nonce/hash collisions, and tests/smoke mocks were updated
accordingly.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
a3e6592. 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 Agent <cursoragent@cursor.com>
Co-authored-by: Copilot <copilot@github.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.
-->
## **Description**
> Removes the WDIO `generateTestId` helper and updates many UI
components to pass `testID` directly (dropping `Platform`-dependent
spreading) across buttons, toggles, list items, and modals.
>
> Introduces/standardizes colocated `*.testIds.ts` selector constants
for several screens/components (e.g., `Navbar`, `EthereumAddress`,
`AccountSelector`, `BrowserTab` options, `PhishingModal`,
`WebviewError`, `TermsAndConditions`, `ConnectQRHardware`) and updates
unit tests/components to import selectors from the new
`tests/selectors`/local testId modules instead of `wdio` paths.
>
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry:
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk refactor focused on test selectors: changes only how
`testID`s are assigned and referenced, with minimal runtime impact
beyond potential selector/name mismatches in tests/automation.
>
> **Overview**
> Removes the WDIO `generateTestId` utility and updates multiple UI
components to pass `testID` directly (dropping `Platform`-dependent
spreading) across buttons, toggles, list items, and modals.
>
> Introduces/standardizes co-located `*.testIds.ts` selector constants
(e.g., `Navbar`, `EthereumAddress`, `AccountSelector`, browser options,
phishing/webview error modals, terms, QR hardware connect) and updates
unit tests/components to import selectors from these modules (and from
`tests/selectors`) instead of `wdio` paths.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
7d696af. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…29548) ## **Description** Bundles six small Money Hub UX changes: - **MUSD-728** — Drop the inline **Learn more** CTA from `MoneyConvertStablecoins`. The Convert section ends after the feature tags / per-token rows; only the primary action remains. - **MUSD-729** — Money Hub balance heading reads **Your balance** (replacing the duplicate "Money" inline title; the page header still shows "Money"). Standalone "3% bonus" label removed from mUSD rows in the homepage token list — the row falls back to the standard percentage rail when there's no Convert CTA. - **MUSD-730** — `AssetOverviewClaimBonus` claim button switches from primary to **secondary** styling (no logic change). - **MUSD-731** — No code change required: the existing `MUSD_CONVERSION_APY` constant already drives every "3%" surface consistently. No outdated/conflicting variants remain. - **MUSD-732** — Five-item checklist (`Dollar-backed`, `No lockups`, `Daily bonus`, `MetaMask stablecoins`, `No MetaMask fee`) added to the **Get 3% on stablecoins** education splash with green checkmarks. - **MUSD-733** — Mounts the Convert section on the mUSD asset detail page via a new `AssetOverviewConvertSection` wrapper that reuses `MoneyConvertStablecoins`. The component already supports the three target states (no-mUSD informational, has-mUSD with stablecoins per-token rows, has-mUSD without stablecoins informational). The secondary claim CTA from MUSD-730 covers the claim-styling requirement. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: [MUSD-728](https://consensyssoftware.atlassian.net/browse/MUSD-728), [MUSD-729](https://consensyssoftware.atlassian.net/browse/MUSD-729), [MUSD-730](https://consensyssoftware.atlassian.net/browse/MUSD-730), [MUSD-731](https://consensyssoftware.atlassian.net/browse/MUSD-731), [MUSD-732](https://consensyssoftware.atlassian.net/browse/MUSD-732), [MUSD-733](https://consensyssoftware.atlassian.net/browse/MUSD-733) ## **Manual testing steps** ```gherkin Feature: Money Hub polish Scenario: Money Hub Convert section (MUSD-728) Given I open the Money Hub Then the Convert to mUSD section ends after the feature tags or per-token rows And no "Learn more" button is rendered Scenario: Money Hub balance heading (MUSD-729) Given I open the Money Hub Then the balance section heading reads "Your balance" Scenario: mUSD token row label (MUSD-729) Given I view the wallet token list with mUSD on Mainnet/Linea Then the mUSD row no longer renders the green "3% bonus" label And the row falls back to the standard percentage rail when no Convert CTA applies Scenario: Asset detail claim button (MUSD-730) Given I open the mUSD asset detail page with a claimable bonus Then the "Claim" button uses secondary button styling Scenario: Education splash checklist (MUSD-732) Given I view the "Get 3% on stablecoins" education splash Then I see a checklist with: Dollar-backed, No lockups, Daily bonus, MetaMask stablecoins, No MetaMask fee And each item shows a green check icon Scenario: Asset detail Convert module (MUSD-733) Given I open the mUSD asset detail page And mUSD conversion is enabled and I am geo-eligible Then a Convert section renders below the claim card And it shows per-token rows for any eligible stablecoins, or the empty/info layout otherwise ``` ## **Screenshots/Recordings** <img width="1206" height="2622" alt="image" src="https://github.com/user-attachments/assets/474cfcf1-d538-43c7-b798-4ca060fa1a88" /> <img width="1206" height="2622" alt="image" src="https://github.com/user-attachments/assets/82ee004e-40c1-4972-bf93-f6ca44822150" /> <img width="1206" height="2622" alt="image" src="https://github.com/user-attachments/assets/c7ae2bd0-cf04-4475-826a-806498a33a92" /> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - [ ] I've tested with a power user scenario - [ ] I've instrumented key operations with Sentry traces for production performance metrics ## **Pre-merge reviewer checklist** - [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. [MUSD-728]: https://consensyssoftware.atlassian.net/browse/MUSD-728?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Moderate risk: refactors conversion UI wiring and token list rendering paths (including a new compact mUSD layout and new analytics events/locations), which could affect navigation and tracking if misconfigured. > > **Overview** > **Money Hub UX polish for mUSD conversion and balances.** The Convert section (`MoneyConvertStablecoins`) is simplified by removing the inline *Learn more* CTA and now self-manages token fetching plus conversion initiation, emitting `MONEY_HUB_TOKEN_ROW_CONVERT_CLICKED` analytics with a passed-in `location`. > > **mUSD balance presentation is adjusted across Money surfaces.** `CashTokensFullView` adds a **"Your balance"** heading when Money Hub is enabled, introduces a new `MoneyMusdEmptyBalanceRow` for the zero-balance state, and passes a new `hideSecondaryPriceRow` flag through `Tokens`/`TokenList` to render a compact mUSD row without the price/percentage rail. Separately, mUSD token list items no longer show the standalone green `"3% bonus"` secondary label. > > **Other small UI/text tweaks.** `AssetOverviewClaimBonus` switches its CTA button to `Secondary` styling and removes the leading `+` from the estimated annual bonus display; the mUSD education screen is redesigned to use design-system components, adds a 5-item checklist, and removes the external “Terms apply” link while updating the education copy and i18n keys (cash → money, new checklist strings, new `money.your_balance`). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 6696fdc. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** This change replaces the temporary `HeaderCompactStandard` component with `HeaderStandard` from `@metamask/design-system-react-native` on Earn-related surfaces. **Reason:** Align Earn UI with the MetaMask design system and reduce reliance on `component-library/components-temp` for standard headers. **What changed:** `HeaderStandard` is used for the Lending “How it works” bottom sheet, the Earn input screen header (back button and end actions), and the Earn token list bottom sheet. Behavior is intended to match the previous header (title, back/close, analytics-related tests unchanged aside from naming). Unit test comments and a `describe` block name were updated to reference `HeaderStandard`. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-699 ## **Manual testing steps** ```gherkin Feature: Earn headers use design system HeaderStandard Scenario: Earn input screen header matches prior behavior Given the user is on the Earn flow and opens the amount/input screen (e.g. stake or supply) When the user views the screen header and uses the back control Then the header shows the expected title and navigation behaves as before Scenario: Lending “How it works” modal Given the user opens the Lending learn-more / “How it works” bottom sheet from Earn When the user views the header and taps close Then the sheet dismisses as before Scenario: Earn token selection bottom sheet Given the user opens the token list bottom sheet (e.g. select token to supply or withdraw) When the user views the header title and uses the close control Then the sheet closes as before and titles match the prior copy for the flow ``` ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk refactor that swaps a temporary header component for the design-system header on a few Earn screens; main regression risk is minor UI/interaction differences in back/close and end-icon rendering. > > **Overview** > Updates Earn surfaces to use the design-system `HeaderStandard` instead of the temporary `HeaderCompactStandard`, including the Lending “How it works” bottom sheet, the `EarnInputView` screen header (back + optional info icon), and the Earn token list bottom sheet (close button + title). > > Adjusts imports accordingly (including `IconName` usage from the design system) and updates unit test descriptions/comments to reference `HeaderStandard` while keeping behavioral assertions the same. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit c517a2e. 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>
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
## **Description**
This PR introduces two shared `NativeStackNavigationOptions` presets in
`clearStackNavigatorOptions.ts`:
Perps already uses `createNativeStackNavigator`, but several screens
repeated the same option blobs (`presentation: 'transparentModal'`,
transparent `contentStyle`, `animation: 'none'`, `headerShown: false`)
inline. That duplicated the JS-stack `clearStackNavigatorOptions` idea
without a typed, reusable native-stack equivalent.
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry:null
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Moderate risk because it changes React Navigation option presets for
native stacks, which can affect modal presentation, animations, and
header behavior across Perps flows.
>
> **Overview**
> Standardizes Perps native-stack overlay behavior by replacing inline
`presentation: 'transparentModal'`/transparent styling with shared
presets (`transparentModalScreenOptions`,
`clearNativeStackNavigatorOptions`).
>
> Adds native-stack equivalents of the existing clear JS-stack options
in `clearStackNavigatorOptions.ts`, and updates Perps screens (TP/SL,
close-position/bottom-sheet stacks, and pay-with modal) to use these
presets for consistent transparent modals without unwanted animations.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
3a0cec5. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** https://consensyssoftware.atlassian.net/browse/RWDS-1267 The Rewards crash likely came from an older persisted Rewards Redux state that did not have newer array fields, especially campaigns. On affected devices, selectCampaigns could return undefined. It was account/device dependent because persisted state differs per user/install. Fix Applied: hardened both the restore path and selector path to fallback to initial state (empty array or object instead of undefined) <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/RWDS-1267 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [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** > Low risk: changes are defensive fallbacks for missing/undefined persisted state and selector inputs, with added tests; behavior should only differ for legacy/partial states. > > **Overview** > Prevents Rewards tab crashes caused by older/partial persisted Redux/controller state by **defaulting missing fields to safe empty values**. > > Selectors and rehydrate logic now coalesce `undefined` arrays/objects (e.g., `campaigns`, season arrays, `benefits`, dismissed-toasts map, controller `accounts`/`subscriptions`) to empty defaults, and `RewardsController` default state was extracted into `defaultState.ts` and reused. Test coverage was expanded to lock in these upgrade/undefined-state behaviors. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit d7b351d. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…29813) ## **Description** Replaces the legacy `Bank` icon used by the Money tab in the bottom navigation bar with the new Dollar glyph from the Figma spec (MUSD-773), in both selected (filled) and unselected (outline) states. - Adds two new SVG assets: `dollar.svg` (outlined circle + dollar sign) and `dollar-filled.svg` (solid circle with dollar-sign cutout). - Both SVGs use `currentColor` for stroke and fill so the Icon component can tint them per theme — they pick up the correct active/inactive color in both light and dark mode, matching the convention used by the other tab bar icons (`Home`/`HomeFilled`, `MetamaskFoxOutline`/`MetamaskFoxFilled`). - The filled variant uses `fill-rule="evenodd"` so the dollar sign is a transparent cutout through the colored circle, showing the tab-bar background through it (avoids hardcoded light/dark color pairs). - Wires the new icons in `TabBar.constants.ts` (inactive → `IconName.Dollar`) and `TabBar.tsx` (`FILLED_ICONS` map → `IconName.DollarFilled`). - Adds `Dollar` and `DollarFilled` to the local `IconName` enum and asset map by hand to avoid the side-effect rewrite that `yarn generate-icons` would have done to the rest of the enum. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: [MUSD-773](https://consensyssoftware.atlassian.net/browse/MUSD-773) ## **Manual testing steps** ```gherkin Feature: Money tab uses the new Dollar icon in both states and themes Scenario: Money tab is unselected in light mode Given the app is in light mode And the user is not on the Money tab Then the Money tab icon is the outlined Dollar glyph And its stroke and dollar sign use the inactive icon tint Scenario: Money tab is unselected in dark mode Given the app is in dark mode And the user is not on the Money tab Then the Money tab icon is the outlined Dollar glyph And its stroke and dollar sign use the inactive icon tint Scenario: Money tab is selected in light mode Given the app is in light mode When the user taps the Money tab Then the Money tab icon switches to the filled Dollar glyph And the circle paints in the active icon tint And the dollar sign is transparent, showing the tab-bar background through it Scenario: Money tab is selected in dark mode Given the app is in dark mode When the user taps the Money tab Then the Money tab icon switches to the filled Dollar glyph And the circle paints in the active icon tint And the dollar sign is transparent, showing the tab-bar background through it ``` ## **Screenshots/Recordings** ### **Before** ### **After** <img width="1206" height="2622" alt="image" src="https://github.com/user-attachments/assets/74c25f60-fd6e-4b98-8645-aa7a1b907c92" /> <img width="1206" height="2622" alt="image" src="https://github.com/user-attachments/assets/2d54975e-87db-49ee-876a-266f60682deb" /> ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - [ ] I've tested with a power user scenario - [ ] I've instrumented key operations with Sentry traces for production performance metrics ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. [MUSD-773]: https://consensyssoftware.atlassian.net/browse/MUSD-773?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk UI-only change that swaps icon assets and enum entries; main risk is any missed references to the removed/renamed `IconName` values causing build-time errors. > > **Overview** > Updates the bottom navigation **Money** tab to use new `Musd`/`MusdFilled` icon assets instead of the legacy bank glyph, wiring them through the tab bar icon maps. > > Extends the icon system with new `IconName` entries and SVG assets, and updates Portfolio-related tab UI/tests to use `IconName.PieChart` in place of the removed `IconName.Portfolio` (including `HomepageDiscoveryTabs`). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit ee491bb. 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 Agent <cursoragent@cursor.com> Co-authored-by: Brian August Nguyen <brianacnguyen@gmail.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.
-->
## **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?
-->
OAuth client IDs for Google and Apple sign-in (`IOS_GOOGLE_CLIENT_ID`,
`IOS_GOOGLE_REDIRECT_URI`, `ANDROID_GOOGLE_CLIENT_ID`,
`ANDROID_GOOGLE_SERVER_CLIENT_ID`, `ANDROID_APPLE_CLIENT_ID`) were
previously sourced from `process.env`, requiring manual environment
variable configuration and risking misconfiguration across different
build types.
This PR moves those client IDs into the existing `OAUTH_CONFIG` object
in `config.ts`, keyed by build type (development, main_prod, main_uat,
main_dev, flask_prod, flask_uat, flask_dev). The constants in
`constants.ts` now read from `CURRENT_OAUTH_CONFIG` instead of
`process.env`, ensuring the correct client IDs are automatically
selected based on the build type. The corresponding environment variable
entries have been removed from `.js.env.example`.
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: null
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: Seedless onboarding OAuth login
Scenario: user signs in with Google on iOS
Given the app is built with a main production build type
When user taps "Sign in with Google" during onboarding
Then the Google OAuth flow uses the correct production client ID
And the user is authenticated successfully
Scenario: user signs in with Google on Android
Given the app is built with a main production build type
When user taps "Sign in with Google" during onboarding
Then the Google OAuth flow uses the correct production server client ID
And the user is authenticated successfully
Scenario: user signs in with Apple on Android
Given the app is built with a main production build type
When user taps "Sign in with Apple" during onboarding
Then the Apple OAuth flow uses the correct production Apple client ID
And the user is authenticated successfully
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Touches OAuth configuration used for Google/Apple login; incorrect
client IDs/redirect URIs could break authentication in specific build
targets despite being mostly a config refactor.
>
> **Overview**
> OAuth client IDs/redirect URIs are now **defined per build type** in
`OAuthLoginHandlers/config.ts` and consumed via `CURRENT_OAUTH_CONFIG`
in `constants.ts`, instead of being read from `process.env`.
>
> The example env file removes the seedless-onboarding client ID
entries, and unit tests are updated to assert against
`OAUTH_CONFIG.main_prod` values for Android and legacy iOS Google config
selection.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
fd46114. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**
The iOS production build in `build.yml` runs `pod install` without
caching `~/.cocoapods/repos` (the CocoaPods specs repository). Every run
downloads the full specs catalog from CDN, taking ~1m 36s.
This PR adds an `actions/cache@v4` step before `pod install` that caches
`~/.cocoapods/repos` keyed on `ios/Podfile.lock`. On cache hit, `pod
install` resolves specs locally instead of fetching from CDN. Uses
`continue-on-error: true` so cache failures never block the build.
This matches the existing pattern in
`.github/actions/setup-e2e-env/action.yml` (lines 382-391).
## **Changelog**
CHANGELOG entry: null
## **Related issues**
Fixes: MCWP-574
## **Manual testing steps**
```gherkin
Feature: CocoaPods specs caching in iOS production build
Scenario: First run populates the cache (cache miss)
Given a production iOS build is triggered via workflow_dispatch
And no prior CocoaPods specs cache exists for the current Podfile.lock
When the "Restore CocoaPods specs cache (iOS)" step runs
Then the step logs show "Cache not found"
And "Install CocoaPods dependencies (iOS)" completes successfully at baseline timing (~1m 36s)
Scenario: Subsequent run restores the cache (cache hit)
Given a production iOS build is triggered via workflow_dispatch
And a CocoaPods specs cache exists from a previous run
When the "Restore CocoaPods specs cache (iOS)" step runs
Then the step logs show "Cache restored"
And "Install CocoaPods dependencies (iOS)" completes faster (~30s-1m less)
And the build produces a valid IPA artifact
Scenario: Cache failure does not block the build
Given the cache action encounters an error (network issue, quota exceeded)
When the "Restore CocoaPods specs cache (iOS)" step fails
Then the step is marked as successful due to continue-on-error: true
And "Install CocoaPods dependencies (iOS)" proceeds normally with a full CDN fetch
```
## **Screenshots/Recordings**
N/A - CI workflow change only, no UI impact.
### **Before**
### **After**
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] 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.
## **Description**
The `prepare` and `emit-build-metadata` jobs in `build.yml` use
`fetch-depth: 0` (full git history clone), which takes ~1m 10s each
(median, n=21). Neither job performs any git history operations:
- `prepare`: reads `builds.yml` via `fs.readFileSync` and runs
`validate-build-config.js` (zero git commands)
- `emit-build-metadata`: runs `git rev-parse HEAD` (works on shallow
clones) and `get-build-metadata.sh` which only reads files (zero git
commands)
Removing `fetch-depth: 0` defaults to `fetch-depth: 1` (shallow clone),
reducing checkout from ~70s to ~10-15s per job.
**Expected saving:** ~1m 50s - 2m 10s per pipeline run across both jobs.
Also eliminates a tail-risk outlier where `emit-build-metadata` checkout
took 6m 45s.
Part of MCWP-574 (pipeline optimization series: PR 3 of 4).
## **Changelog**
CHANGELOG entry: null
## **Related issues**
Fixes: MCWP-574
## **Manual testing steps**
```gherkin
Feature: Shallow clone in build pipeline
Scenario: prepare job completes with shallow clone
Given a production build is triggered via workflow_dispatch on build.yml
And skip_version_bump is true
When the prepare job runs
Then the actions/checkout step completes in ~10-15s (down from ~70s)
And the prepare job outputs are identical to a full-clone run
Scenario: emit-build-metadata job completes with shallow clone
Given a production build completes successfully
When the emit-build-metadata job runs
Then the actions/checkout step completes in ~10-15s
And built_commit_sha, semantic_version, and version codes are output correctly
Scenario: version-bump commit ref works with shallow clone
Given a production build is triggered with skip_version_bump false
When the prepare job checks out the version-bump commit hash
Then actions/checkout fetches the specific commit successfully
And the prepare job completes without errors
```
## **Screenshots/Recordings**
### **Before**
Not applicable (CI pipeline change, no UI).
### **After**
Not applicable (CI pipeline change, no UI).
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->
## **Description**
This PR adds **component view tests (CVT)** for flows that were
previously covered by **smoke E2E** only, and **skips** those E2E cases
(eventually delete them). Smoke specs keep the original test bodies and
point to the CV file with `// Moved to cv tests (...)`.
Example: In network abstraction shard 1 we see a 4m reduction time
(android).
### E2E → component view test mapping
| File | Test Name | QA Comment | CV test file |
| --- | --- | --- | --- |
| view-defi-details.spec.ts | view DeFi position details | just checking
some data in the screen |
`app/components/UI/DeFiPositions/DeFiProtocolPositionDetails.view.test.tsx`
|
| view-market-insights.spec.ts | displays market insights content and
navigates to swap | |
`app/components/UI/MarketInsights/Views/MarketInsightsView/MarketInsightsView.view.test.tsx`
|
| view-market-insights.spec.ts | does not display entry card when API
returns no data | |
`app/components/UI/TokenDetails/components/AssetOverviewContent.view.test.tsx`
|
| view-market-insights.spec.ts | does not display entry card when
feature flag is disabled | |
`app/components/UI/TokenDetails/components/AssetOverviewContent.view.test.tsx`
|
| view-market-insights.spec.ts | navigates to buy screen when tapping
Buy button | |
`app/components/UI/MarketInsights/Views/MarketInsightsView/MarketInsightsView.view.test.tsx`
|
| view-market-insights.spec.ts | can tap thumbs up feedback button | |
`app/components/UI/MarketInsights/Views/MarketInsightsView/MarketInsightsView.view.test.tsx`
|
| send-btc-token.spec.ts | shows insufficient funds | This only does
validation on the input |
`app/components/Views/confirmations/components/send/send.non-evm.view.test.tsx`
|
| send-tron-token.spec.ts | shows insufficient funds | This only does
validation on the input |
`app/components/Views/confirmations/components/send/send.non-evm.view.test.tsx`
|
| send-erc20-token.spec.ts | should send USDC amount 50% to an address |
CV tests will handle these combinations |
`app/components/Views/confirmations/components/send/send.view.test.tsx`
|
| send-erc20-token.spec.ts | should send USDC send max to an address |
CV tests will handle these combinations |
`app/components/Views/confirmations/components/send/send.view.test.tsx`
|
| send-native-token.spec.ts | should send ETH to an address | PARTIALLY:
We should only cover ETH send, no need to cover 50% and Max |
`app/components/Views/confirmations/components/send/send.view.test.tsx`
|
| send-solana-token.spec.ts | should send solana to an address | This is
not actually sending anything, just checking that the text matches |
`app/components/Views/confirmations/components/send/send.non-evm.view.test.tsx`
|
| alert-system.spec.ts | should sign typed message | Moved to yes as per
team review |
`app/components/Views/confirmations/components/alert-banner/alert-system-typed-sign-blockaid.view.test.tsx`
|
| alert-system.spec.ts | should show security alert for malicious
request, acknowledge and confirm the signature | Moved to yes as per
team review |
`app/components/Views/confirmations/components/alert-banner/alert-system-typed-sign-blockaid.view.test.tsx`
|
| alert-system.spec.ts | should show security alert for error when
validating request fails | |
`app/components/Views/confirmations/components/alert-banner/alert-system-security-failed.view.test.tsx`
|
| alert-system.spec.ts | should show mismatch field alert, click the
alert, acknowledge and confirm the signature | As long as the component
is the same we can do this via CV test |
`app/components/Views/confirmations/components/alert-banner/alert-system-siwe-inline-mismatch.view.test.tsx`
|
| gas-fee-tokens-eip-7702-sponsored.spec.ts | fails transaction if error
occurs on API | |
`app/components/Views/confirmations/components/activity/eip-7702-sponsored-relay-api-failure.view.test.tsx`
|
| enable-notifications-after-onboarding.spec.ts | should enable
notifications and view feature announcements and wallet notifications |
Test is not doing what its title implies; skipped pending owner
discussion |
`app/components/Views/Notifications/NotificationsView.view.test.tsx` |
| notification-settings-flow.spec.ts | should enable notifications and
toggle feature announcements and account notifications | UI-only
validation, suitable for CV |
`app/components/Views/Settings/NotificationsSettings/NotificationsSettings.view.test.tsx`
|
| add-popular-networks.spec.ts | adds a popular network directly without
confirmation modal | This is not in prod anymore | *No matching
`*.view.test.tsx` on this branch* |
## **Changelog**
CHANGELOG entry: null
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: N/A
Scenario: Automated tests only
Given developer checks out this branch
When they run yarn test:view for the touched view test files
Then tests pass
```
## **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.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low product risk since changes are test-only, but moderate test-suite
risk due to new integration-style view tests, new engine/nock mocks, and
`jest.config.view.js` forcing `IS_TEST=true` for feature-gated code
paths.
>
> **Overview**
> Adds **component-view (CV) test coverage** for several flows
previously validated only by smoke E2E: DeFi protocol position details,
token Market Insights (including entry card gating + swap/buy navigation
+ sources sheet + feedback), notifications list/details and notification
settings toggles, confirmation alert-system (typed-sign Blockaid
benign/malicious + SIWE domain mismatch inline + validation-failed
banner), and EIP-7702 sponsored send (failed activity status + “Paid by
MetaMask” fee row).
>
> Extends CV test infrastructure with new presets/helpers and mocks
(notifications state seeding, Market Insights navigation
renderer/preset, SnapController request interceptor, Sentinel
`/networks` nock mock), adds/normalizes several `testId` constants (send
50% button, confirmation transfer loader, status-icon tooltip), and sets
`process.env.IS_TEST=true` at view-jest config load time to satisfy
env-inlined feature gates.
>
> Removes or skips corresponding smoke E2E specs (or individual cases)
and updates fixtures/assertions (e.g., SIWE signer address) to align
with the new CV coverage.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
6098045. 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>
…liquidation and bonus messages (#29779) <!-- 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** Turkish copy used `%{{variable}}` so a literal percent could sit before the interpolated value. **i18n-js** (used by `react-native-i18n`) treats `%` followed by `{` as the start of a `%{name}` placeholder, so `%{{...}}` was parsed as one invalid token and users saw messages like `[missing %{{apy}} value]` instead of the real value. All affected `tr.json` strings were updated to **`%%{variable}`**: a literal `%` plus the supported `%{variable}` interpolation, preserving “percent before number” wording while matching the same interpolation keys the app already passes (`apy`, `percentage`, `fee`, `distance`, etc.). No application code changes. ## **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 Turkish strings that showed broken i18n placeholders when a percent sign appeared before an interpolated value. ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: Turkish locale i18n placeholders Scenario: APY and bonus copy interpolate with a leading percent Given the app language is set to Türkçe (tr) And the user opens a surface that shows Money APY label, MetaMask Card APY bullet, earn/mUSD bonus copy, bridge fee disclaimer, swap slippage errors, or perps liquidation distance strings When those screens render Then no string should contain a substring like "[missing" or "value]" And percent-prefixed values should show as "%" immediately followed by the numeric or formatted value (e.g. "%4" for APY), not a raw placeholder token ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk translation-only change that adjusts placeholder formatting; main risk is minor copy/interpolation regressions if any key names are mismatched. > > **Overview** > Fixes broken Turkish (`tr.json`) interpolations where a leading percent sign caused i18n placeholders like `%{{percentage}}` to be parsed incorrectly. > > Updates affected strings (perps liquidation/fees, swap/bridge fee and slippage messages, earn/mUSD bonus and APY/cashback labels) to use `%%{...}` so the UI shows a literal `%` followed by the interpolated value. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 4a6b57e. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** ### Problem Android E2E runs are crashing with `Error: kill EPERM` in the "Set up E2E environment" step ([example](https://github.com/MetaMask/metamask-mobile/actions/runs/25337405885/job/74288509502?pr=29670)). This was introduced by #29236, which wrapped `sudo apt-get` inside `nick-fields/retry` with `timeout_minutes: 3`. **Root cause:** When the 3-minute timeout fires, `nick-fields/retry` calls `process.kill()` on the child process. But `sudo apt-get` runs as **root** while the Cirrus runner process runs as **admin** — Node.js gets `EPERM` (permission denied) on the kill syscall. This is a [known upstream bug](nick-fields/retry#124) (open since Oct 2023, 11 upvotes, unpatched). **Why the timeout fires:** `DPkg::Lock::Timeout=120` means `apt-get` can legitimately wait up to 120s for the dpkg lock on each of the two `sudo` calls (`update` + `install`). With slow Ubuntu mirrors on top, total time can approach or exceed 180s (3 min), triggering the timeout. The 3-minute value was tightened from the original 5-minute design in a follow-up commit on #29236, which didn't account for the double lock-wait scenario. ### Fix 1. **Restore `timeout_minutes` from 3 to 5** — gives 300s per attempt. Even worst-case (120s lock on update + 120s lock on install + 30s actual install = 270s) fits with 30s headroom. `apt-get` resolves on its own (success or dpkg lock timeout error) before the retry timeout fires, so the `process.kill()` path — and the EPERM bug — is never hit. 2. **Add `retry_on: error`** — only retry when `apt-get` exits with a non-zero code (mirror desync, lock timeout), not when `nick-fields/retry`'s own timeout fires. A timeout-triggered retry would crash with EPERM anyway, so this avoids a wasted attempt. ### Timing analysis | Scenario | Duration | Fits in 5 min? | |----------|----------|----------------| | Happy path (no lock, fast mirror) | 5-15s | Yes (295s margin) | | Lock on one call + normal mirror | 120s + 15s = 135s | Yes (165s margin) | | Lock on both calls + slow mirror | 240s + 30s = 270s | Yes (30s margin) | | Lock on both + very slow mirror | 240s + 60s = 300s | Boundary — but this is extremely unlikely | ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: INFRA-3580 Fixes regression from #29236 ## **Manual testing steps** N/A — CI infrastructure fix. Validated by any Android E2E workflow run. The timeout increase is transparent in the happy path (apt-get takes 5-15s). ## **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. ## **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** > Low risk CI-only change that adjusts retry behavior for Linux `apt-get` during Android E2E setup; primary impact is longer waits before failing and fewer timeout-triggered retries. > > **Overview** > Reduces flaky Android E2E setup failures by updating the `setup-e2e-env` composite action to **increase** the `nick-fields/retry` `apt-get` wrapper timeout from 3 to 5 minutes. > > The retry wrapper is also configured with `retry_on: error` so retries only happen on non-zero exits, avoiding retries triggered by the action's own timeout. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 8bcc995. 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>
<!-- CURSOR_AGENT_PR_BODY_BEGIN -->
## **Description**
This PR fixes token logo rendering for non-native assets when
`asset.image` is empty (the issue affecting mUSD/Money integration).
The `AssetLogo` component now:
- computes a fallback icon URL via `getAssetImageUrl` when the primary
image is missing,
- only attempts fallback generation for valid CAIP or strict-hex chain
IDs,
- passes `imageSource={{ uri: imageUri }}` so undefined URI values are
handled directly by `AvatarToken`.
It also adds unit tests to cover fallback behavior and unsupported
chain-id behavior.
## **Changelog**
CHANGELOG entry: fix: fixed token list items to use a fallback icon when
token image URLs are missing
## **Related issues**
Fixes: https://consensyssoftware.atlassian.net/browse/ASSETS-3156
## **Manual testing steps**
```gherkin
Feature: Token list item image fallback
Scenario: Token with missing image URL still shows an icon
Given a token list item where asset.image is empty
When the token list item renders
Then AssetLogo resolves and uses a fallback image URL for valid chain IDs
And the token icon is shown instead of an empty image
Scenario: Unsupported chain id does not crash icon rendering
Given a token list item where asset.image is empty and chainId is unsupported
When the token list item renders
Then AssetLogo does not attempt invalid fallback URL generation
And AvatarToken renders safely when uri is undefined
```
## **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.
<!-- CURSOR_AGENT_PR_BODY_END -->
<div><a
href="https://cursor.com/agents/bc-9a3458e2-b19c-40ef-b02b-feb8b7c2fa93"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a
href="https://cursor.com/background-agent?bcId=bc-9a3458e2-b19c-40ef-b02b-feb8b7c2fa93"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img
alt="Open in Cursor" width="131" height="28"
src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </div>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
…res that were disabled due to feature flag updates (#29154) <!-- 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`. --> ## **Description** Brings Predict E2E test feature flag mocks into parity with production values. Two remote feature flag overrides in predict smoke tests diverged from production after a feature flag registry sync ([PR #28444](#28444)). This PR aligns the mocks: - **`exploreSectionsOrder`**: Replaced the explicit section ordering arrays with `{}` in 4 predict smoke specs. On production this flag is empty; the app falls back to hardcoded defaults which produce the same layout. The Homepage component does not consume this flag at all — it only affects TrendingView/Explore, which these tests don't exercise. - **`predictLiveSports`**: Added `'nba'` to the leagues list (now `['nfl', 'nba']`) to match production. This causes NBA markets (Spurs vs. Pelicans) to render via `PredictGameDetailsContent`, which uses a different cash-out button test ID (`predict-picks-cash-out-button-{positionId}`). Updated the `PredictDetailsPage` page object with a new `tapGameCashOutButton(positionId)` method and updated `predict-cash-out.spec.ts` to use it. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: [MMQA-1711](https://consensyssoftware.atlassian.net/browse/MMQA-1711) ## **Manual testing steps** <!-- Gherkin scenarios for this change --> **Feature: Predict E2E prod parity** **Scenario: Cash out on NBA game market uses correct button** - Given the predict smoke tests use production-parity feature flag mocks - When the predict-cash-out test runs against Spurs vs. Pelicans - Then the test taps the game-details cash-out button (PredictPickItem testID) - And the cash-out flow completes successfully **Scenario: Predict tests work without explicit exploreSectionsOrder** - Given exploreSectionsOrder is set to `{}` in all predict smoke specs - When any predict smoke test runs (cash-out, open-position, geo-restriction, withdraw) - Then the Homepage renders with the default section order - And the test navigates to predictions by test ID without issue ## **Screenshots/Recordings** ### **Before** N/A — test-only changes, no UI impact. ### **After** N/A — test-only changes, no UI impact. ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. [MMQA-1711]: https://consensyssoftware.atlassian.net/browse/MMQA-1711?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Test-only changes that adjust feature-flag mocks and E2E selectors; low product risk, but could affect Predict smoke test stability if testIDs/position IDs drift. > > **Overview** > Aligns Predict E2E remote feature-flag mocks with current production defaults by removing the `predictLiveSports` override from `remoteFeatureFlagPredictEnabled`. > > Updates Predict smoke specs to interact with the *game-details* UI: adds a shared `SPURS_PELICANS_POSITION_ID`, introduces `PredictDetailsPage.tapGameCashOutButton(positionId)` and `tapGameBetYesButton()`, and switches cash-out/position-opening tests to use the new testIDs for NBA/game markets. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f452736. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!-- CURSOR_AGENT_PR_BODY_BEGIN --> ## **Description** Adds the missing collection name field to the NFT details screen. The data already existed on `collectible.collection.name`, but the screen did not render it. ## **Changelog** CHANGELOG entry: fix: NFT details did not show the collection name ## **Related issues** Fixes: #29362 https://consensyssoftware.atlassian.net/browse/ASSETS-3125 ## **Manual testing steps** ```gherkin Feature: NFT details collection metadata Scenario: User views an NFT details page Given the user has imported NFTs from a collection When user opens the details screen for one NFT Then the screen displays the collection name in the Collection section ``` ## **Screenshots/Recordings** ### **Before** ### **After** <img width="318" height="102" alt="Screenshot 2026-05-07 at 10 49 53" src="https://github.com/user-attachments/assets/6e3bd63d-e2db-46ab-990f-2e6d9f5193b7" /> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example <!-- CURSOR_AGENT_PR_BODY_END --> <div><a href="https://cursor.com/agents/bc-2131bb9a-ffff-464e-9da8-8a287e0d8b37"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a href="https://cursor.com/background-agent?bcId=bc-2131bb9a-ffff-464e-9da8-8a287e0d8b37"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </div> Co-authored-by: Cursor Agent <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. --> ## **Description** <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: Updated money account deposit. ## **Related issues** Depends on: #29561 Depends on: MetaMask/core#8687 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Updates Money Account deposit transaction construction and confirmation re-encoding, which can affect on-chain calldata and Pay gating via `requiredAssets`, though it is still using a zero-amount placeholder by default. > > **Overview** > Adds a Money Account deposit initiation path that submits an `addTransactionBatch` for approve+deposit with a **zero-amount placeholder**, navigates to the `CustomAmount` confirmation screen, and declares Pay `requiredAssets` using a shared deposit-asset helper. > > Implements real `updateMoneyAccountDepositTokenAmount` re-encoding: converts the user-entered human amount to USDC base units, calls `previewDeposit` to compute `minimumMint` (with slippage), and returns updated calldata for the nested approve/deposit calls; it no-ops when vault config/provider is unavailable. > > Refactors deposit asset handling into `getMoneyAccountDepositAssetAddress` (currently hardcoded USDC), skips the `previewDeposit` RPC for 0 amounts, updates/extends unit tests and confirmation mocks, and bumps `@metamask/transaction-controller` to `65.1.0`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 5ef8804. 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: Jyoti Puri <jyotipuri@gmail.com>
## **Description** INFRA-3592 Phase 0 — adds a `runner_provider` control input (`current` | `namespace`, default `current`) to the Phase 1-4 entry-point and reusable workflows, threads forwarding through every in-scope caller, and wraps each in-scope `runs-on:` in an additive ternary that selects between the existing runner and the matching `namespace-profile-*` label. **No job is migrated. No default is changed.** With `runner_provider: current` (the default on every existing trigger) every ternary collapses to its prior literal/expression, so behavior is byte-identical to `main`. The `namespace` branch is reachable only via manual `workflow_dispatch`. Branch is the long-lived working surface for Phases 1-4; do not merge. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: [INFRA-3592](https://consensyssoftware.atlassian.net/browse/INFRA-3592) (parent epic INFRA-3511) ## **Manual testing steps** ```gherkin Feature: runner_provider trial control plane Scenario: dispatch on the current default — byte-identical Given the trial branch namespace-runner-trial When user runs `gh workflow run ci.yml --ref namespace-runner-trial -f runner_provider=current` Then every job runs on its existing GitHub-hosted / Cirrus runner And required-check context names match origin/main exactly Scenario: dispatch on namespace — plumbing reaches Namespace Given the trial branch and the MetaMask Actions allowlist already updated When user runs `gh workflow run ci.yml --ref namespace-runner-trial -f runner_provider=namespace` Then jobs are picked up by the namespace-profile-metamask-* runner that maps to each existing class And end-to-end success is not required at Phase 0 — composite-action assumptions land in Phase 2-4 ``` ## **Verification evidence (already executed)** Both scenarios above were dispatched against this branch — results recorded: | Scenario | Run | Result | | --- | --- | --- | | `runner_provider=namespace` (Namespace path) | [25319648133](https://github.com/MetaMask/metamask-mobile/actions/runs/25319648133) | Linux, iOS, Android jobs all picked up by the matching `namespace-profile-metamask-*` runner; secrets resolved end-to-end (`secrets: inherit` flowing); job names + required-check contexts unchanged | | `runner_provider=current` (existing runners) | [25320925061](https://github.com/MetaMask/metamask-mobile/actions/runs/25320925061) | 0 Namespace instances spawned in the dispatch window; every job ran on its prior GitHub-hosted / Cirrus runner | | Implicit `current` via PR-trigger (no input) | [25174041735](https://github.com/MetaMask/metamask-mobile/actions/runs/25174041735), [25162883313](https://github.com/MetaMask/metamask-mobile/actions/runs/25162883313) | Both `pull_request` runs on the branch completed successfully on existing runners — proves the byte-identical contract holds without a manual dispatch | Required-check parity verified statically against the 3 contexts on `main`'s branch protection (`check-template-and-add-labels`, `Check all jobs pass`, `CLABot`) — none renamed in this diff. Detailed cross-reference in INFRA-3592 [comment 417866 §5](https://consensyssoftware.atlassian.net/browse/INFRA-3592). ## **Screenshots/Recordings** N/A — CI infrastructure PR, no UI surface. ## **Notes for reviewers** - 6 commits, organised so each is independently reviewable: actionlint label registration → `workflow_dispatch` inputs → `workflow_call` inputs → caller forwarding → `runs-on` ternary → placeholder→canonical-label replacement. - Phase 7 callers (`runway-*`, `nightly-build`, `build-and-upload-to-testflight`, `push-eas-update`, `build-rc-auto`) are intentionally **not** modified — they continue to call without forwarding, callees default to `current`. - Composite actions are inventoried only — Phase 2/3/4/5/7 own their migration. - `actionlint -config-file .github/actionlint.yaml` produces byte-identical output to `origin/main` (84 lines, exit 1 from pre-existing warnings only — no new findings introduced by this PR). - Inventories captured (composite actions, caller graph, secrets/environments, concurrency groups, required-check contexts) — full tables in INFRA-3592 [comment 417866](https://consensyssoftware.atlassian.net/browse/INFRA-3592). - Branch was rebased onto current `main` after a conflict with [#29431](#29431) (e2e label rename). Conflict resolution was mechanical — main's renamed jobs (swap-, stake-, money-) had `runner_provider:` re-applied; no semantic decision involved. ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (`team-dev-ops`, `size-M`) #### Performance checks (if applicable) N/A — workflow YAML only, no app code. ## **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. [INFRA-3592]: https://consensyssoftware.atlassian.net/browse/INFRA-3592?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches many GitHub Actions workflows and `runs-on` expressions, so miswiring could break CI execution or route jobs to the wrong runner. Default behavior remains `current`, but the new `namespace` path changes execution environment when manually dispatched. > > **Overview** > Introduces a new `runner_provider` input (default `current`, optional `namespace`) across in-scope entrypoint and reusable workflows, and forwards it through callers. > > Updates `runs-on` in `ci.yml`, `build.yml`, `setup-node-modules.yml`, and E2E build/test workflows to conditionally select between existing GitHub-hosted/Cirrus runners and new `namespace-profile-metamask-*` runner labels. > > Registers the new `namespace-profile-*` labels in `.github/actionlint.yaml`, and adds `workflow_dispatch` inputs to enable manual trial runs using the namespace provider. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit fffcc88. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
## **Description**
Wires 5 events for Whats Happening analytics:
Card Scrolled to View, emitted via `useViewportTracking` in
WhatsHappeningCard
Opened — emitted in `WhatsHappeningSection` on card press and View All
Viewed — emitted in `WhatsHappeningDetailView` on initial mount and on
each carousel scroll
Interaction — emitted in `TokenRow`
Closed — emitted in `WhatsHappeningDetailView` on back press
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: null
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Adds new analytics instrumentation across the Whats Happening homepage
section and detail flow, including new component props and
scroll/visibility hooks that could subtly affect rendering or event
duplication if indices/items drift.
>
> **Overview**
> Adds a full set of **MetaMetrics Whats Happening** events (new
constants in `MetaMetrics.events.ts`) and wires them through the
homepage section and detail experience.
>
> Homepage now tracks `WHATS_HAPPENING_OPENED` with an `entry_point` for
both card taps and *View more*, and cards emit
`WHATS_HAPPENING_CARD_SCROLLED_TO_VIEW` via `useViewportTracking`
(introducing a required `cardIndex` prop).
>
> Detail view now tracks `WHATS_HAPPENING_VIEWED` once on initial mount
and again when the carousel settles on a new index, and tracks
`WHATS_HAPPENING_CLOSED` on back. Token/perps CTAs and source link
presses now emit `WHATS_HAPPENING_INTERACTION` with standardized
properties via the new shared helper `getWhatsHappeningEventProps` (plus
`interaction_type` and asset/source fields).
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
9d3ed1a. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description** INFRA-3593 Phase 1 — adds Namespace Cache Volumes integration to the Linux CI jobs on the `namespace-runner-trial` branch. When `runner_provider: namespace` is dispatched, the 8 Linux CI jobs that install dependencies now: 1. Mount a Namespace Cache Volume via `nscloud-cache-action` covering `~/.cache/yarn`, `.metamask`, `node_modules`, `.yarn/cache`, and `.yarn/install-state.gz` 2. Skip `actions/setup-node` Yarn caching (set to empty string) to avoid duplicate network-backed cache traffic 3. Skip `actions/cache` for `node_modules` in `component-view-tests` and `merge-unit-and-component-view-tests` (Namespace cache already covers it) When `runner_provider: current` (the default on every existing trigger), all ternaries collapse to their prior values and behavior is byte-identical to the base branch. **No job is renamed. No default is changed.** This is an additive, opt-in change activated only via manual `workflow_dispatch` with `runner_provider: namespace`. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: INFRA-3593 (parent epic INFRA-3511) Refs: INFRA-3592 (Phase 0, PR #29557) ## **Manual testing steps** ```gherkin Feature: Namespace Cache Volumes on Linux CI Scenario: dispatch with namespace provider — cache volumes active Given the branch phase1-namespace-linux-cache When user runs `gh workflow run ci.yml --ref phase1-namespace-linux-cache -f runner_provider=namespace` Then all 8 Linux CI jobs with dependencies use nscloud-cache-action And actions/setup-node Yarn caching is disabled (no duplicate cache traffic) And all jobs pass across every matrix shard (unit-tests x10, component-view-tests x2, scripts x6) Scenario: dispatch with current provider — byte-identical to base Given the branch phase1-namespace-linux-cache When user runs `gh workflow run ci.yml --ref phase1-namespace-linux-cache -f runner_provider=current` Then nscloud-cache-action steps are skipped (if condition is false) And actions/setup-node uses cache: yarn as before And actions/cache for node_modules runs as before And all jobs pass on GitHub-hosted runners Scenario: implicit current via PR/push trigger Given a push or pull_request event (no workflow_dispatch) Then inputs.runner_provider is undefined/empty And all ternaries collapse to existing behavior ``` ## **Screenshots/Recordings** ### **Before** N/A ### **After** N/A — CI infrastructure PR, no UI surface. ## **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) N/A — workflow YAML only, no app code. ## **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] > **Medium Risk** > Touches many GitHub Actions workflows to optionally switch runner labels and caching behavior, which could break CI execution or cause cache-related flakiness when enabled. Default behavior remains unchanged unless `runner_provider=namespace` is explicitly selected. > > **Overview** > Introduces a `runner_provider` input (with `workflow_dispatch` choices where relevant) to route jobs between existing runners and new `namespace-profile-*` runner labels across `ci.yml`, reusable build workflows, and E2E smoke/regression workflows. > > When `runner_provider=namespace`, Linux CI jobs that install dependencies mount Namespace cache volumes via `namespacelabs/nscloud-cache-action`, disable `actions/setup-node` Yarn caching, and skip `actions/cache`-based `node_modules` restores in coverage-merge/component-view jobs; Node memory limits are also reduced on Namespace runners. > > Updates `actionlint` configuration to allow the new Namespace runner profile labels. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 3a52111. 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: Jose Luque <jose.luque@consensys.net> Co-authored-by: José Manuel <6741785+jluque0101@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com>
…r Android build (#29777) ## **Description** INFRA-3595 Phase 3 — adds Namespace Cache Volumes integration to the Android build and setup workflows, and fixes the GRADLE_USER_HOME path mismatch that blocked Android builds on Namespace runners. **Changes:** 1. **`build-android-e2e.yml`**: Make `GRADLE_USER_HOME` conditional on `runner_provider` (`/home/runner/_work/.gradle` on Namespace vs `/home/admin/_work/.gradle` on Cirrus). Add `nscloud-cache-action` covering yarn, .metamask, node_modules, .yarn/cache, and Gradle caches/wrapper. Gate all 4 `cirruslabs/cache` steps on `runner_provider != 'namespace'`. On Namespace, always run full build (no APK fingerprint cache since cirruslabs/cache is skipped). 2. **`setup-node-modules.yml`**: Add `nscloud-cache-action` before dependency install. Make `setup-node` `cache:` conditional (disabled on Namespace). Gate `.metamask` `actions/cache` on current path. **Both cache paths coexist for rollback safety.** When `runner_provider: current` (default on all triggers), all ternaries collapse to prior values — cirruslabs/cache runs, nscloud-cache-action is skipped. Behavior is byte-identical to the base branch. Builds on Phase 1 (PR #29716) and Phase 0 (PR #29557). ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: INFRA-3595 (parent epic INFRA-3511) Refs: INFRA-3592 (Phase 0, PR #29557), INFRA-3593 (Phase 1, PR #29716) ## **Manual testing steps** ```gherkin Feature: Android build on Namespace runners Scenario: dispatch with namespace provider — Android build succeeds Given the branch phase3-namespace-android When user runs `gh workflow run ci.yml --ref phase3-namespace-android -f runner_provider=namespace` Then Build Android E2E APKs succeeds on namespace-profile-metamask-android-build And GRADLE_USER_HOME resolves to /home/runner/_work/.gradle And nscloud-cache-action caches Gradle deps and yarn/node_modules And cirruslabs/cache steps are skipped Scenario: dispatch with current provider — byte-identical to base Given the branch phase3-namespace-android When user runs `gh workflow run ci.yml --ref phase3-namespace-android -f runner_provider=current` Then Build Android E2E APKs succeeds on Cirrus ubuntu-runner-amd64 And GRADLE_USER_HOME resolves to /home/admin/_work/.gradle And cirruslabs/cache steps run as before And nscloud-cache-action steps are skipped Scenario: implicit current via PR/push trigger Given a push or pull_request event (no workflow_dispatch) Then inputs.runner_provider is undefined/empty And all ternaries collapse to existing behavior ``` ## **Screenshots/Recordings** ### **Before** N/A ### **After** N/A — CI infrastructure PR, no UI surface. ## **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) N/A — workflow YAML only, no app code. ## **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] > **Medium Risk** > Moderate risk because it changes runner selection and caching behavior across core CI/build/E2E workflows, which can impact build determinism and job reliability. Default behavior remains `current`, but the new `namespace` path introduces new cache tooling and environment differences (e.g., Gradle home). > > **Overview** > Adds an opt-in `runner_provider` switch across CI, build, and E2E workflows to route jobs to Namespace runner profiles (new labels added to `actionlint.yaml`) instead of the existing GitHub/Cirrus runners. > > When `runner_provider=namespace`, enables `namespacelabs/nscloud-cache-action` for Yarn/`node_modules`/`.metamask` (and Gradle caches for Android), disables existing `actions/cache`/`cirruslabs/cache` steps where incompatible, and adjusts Android `GRADLE_USER_HOME` to the Namespace filesystem layout. Manual dispatch workflows (e.g., `ci.yml`, `build.yml`, Expo dev build, and E2E regression runs) now expose `runner_provider` as an input and forward it through reusable workflows. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 207bf39. 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: Jose Luque <jose.luque@consensys.net> Co-authored-by: José Manuel <6741785+jluque0101@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description** Add sort direction indicators to trending token filter buttons to improve UX by making the current sort order immediately visible. ## **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: Adds sort icons on filter bar in trending list ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/ASSETS-3152 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/2b7ac0c1-fe27-4ec8-bcd3-2bcd459ce306 ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk UI enhancement that only adds derived state and icon rendering for the sort button; minimal chance of regressions outside the Trending filter bar layout. > > **Overview** > Adds a sort-direction indicator to the Trending token list price-change filter. > > `FilterButton`/`FilterBar` now accept an optional `iconName`/`priceChangeIconName` and render that icon before the label. `useTokenListFilters` exposes a new `priceChangeSortDirectionIcon` (up/down) derived from `priceChangeSortDirection`, `TokenListPageLayout` wires it into the `FilterBar`, and tests cover the new icon mapping. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 0c6e926. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
|
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. |
|
Caution MetaMask internal reviewing guidelines:
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
…or available count cp-7.78.0 (#30211) - feat(rewards): benefits preview uses Tag for available count (#30196) <!-- 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** > **Section header spacing alignment:** [`CampaignsPreview.tsx`](app/components/UI/Rewards/components/Campaigns/CampaignsPreview.tsx) — the campaigns preview **header row** now uses **`gap-1`** instead of **`gap-2`** between the title row items (spinner when shown, heading, chevron), matching the **Benefits** preview header spacing on the Rewards dashboard. The Rewards dashboard **Benefits** preview header previously used a numeric `BadgeCount` beside the section title. This change replaces it with a design-system **`Tag`** (`TagSeverity.Neutral`) that shows how many benefits are available using the localized string `rewards.benefits.available_count` (e.g. `%{count} available` in English). Counts above 99 display as `99+`. The header row is full width with **`justifyContent: space-between`**: the title and chevron stay on the leading side; the tag sits on the **trailing** edge so it matches the intended layout. Spacing uses `gap-1` between the title and chevron. The empty-state header no longer renders a redundant null badge slot. **Motivation:** Align with design (muted pill copy and alignment) and keep copy in i18n for the translation pipeline (English source string only in `en.json`). **Automated tests:** `yarn jest app/components/UI/Rewards/components/Benefits/BenefitsPreview.test.tsx` ## **Changelog** CHANGELOG entry: Updated the Rewards benefits preview header to show how many benefits are available using a tag label next to the section title; aligned campaigns preview section header spacing with the benefits preview (`gap-1`). ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: Rewards benefits preview header Scenario: User sees benefits count when they have benefits Given the user is opted into Rewards and the benefits API returns at least one benefit When user opens the Rewards dashboard (home) and scrolls to the Benefits preview Then a neutral tag shows the correct count and available wording for the current locale And the tag is aligned to the far right of the header row with the title and chevron grouped on the left And tapping the header row still navigates to the full benefits view Scenario: User has no benefits Given the user has no benefits in the list When user opens the Rewards dashboard and views the Benefits preview Then the count tag is not shown and the empty state behaves as before Feature: Rewards campaigns preview header spacing Scenario: User compares section headers on Rewards home Given the user is on the Rewards dashboard home tab When user views the Campaigns preview section header Then the title row uses gap-1 between the title row elements, matching the Benefits preview header spacing ``` ## **Screenshots/Recordings** ### **Before** Numeric badge style (`BadgeCount`) adjacent to the Benefits title (previous implementation). ### **After** <img width="413" height="827" alt="image" src="https://github.com/user-attachments/assets/bd00ee97-2ae3-4ccb-b924-51ba6d0ca677" /> Neutral `Tag` with “{count} available” (per locale), title + chevron on the left, tag aligned to the trailing edge. (Screenshot also attached in an earlier PR update.) ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk UI/i18n change with unit test updates; primary risk is minor layout/regression in rewards preview headers and count formatting around the 99/99+ boundary. > > **Overview** > The Benefits preview header now replaces the numeric `BadgeCount` with a neutral design-system `Tag` that shows a localized `rewards.benefits.available_count` label (capped to `99+`), and adjusts header layout to keep the title+chevron grouped left with the tag right-aligned. > > Campaigns preview header spacing is tightened (`gap-1`), and tests were expanded to cover the new benefits count behavior (including empty state and 99/99+ cases) plus treating `undefined` campaigns as an empty list. Adds the new English i18n key `rewards.benefits.available_count`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 5ece706. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [f8f126d](f8f126d) Co-authored-by: Andrew Cohen <imandrewcohen@gmail.com>
…running perf builds (#30224) - fix: cp-7.78.0 add correct permissions to running perf builds (#30223) <!-- 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** > Updates the `run-performance-e2e-experimental.yml` and `run-performance-e2e-release.yml` GitHub Actions workflows to grant `permissions.contents: write` (instead of read-only) so they are at least as permissive as the reusable `run-performance-e2e.yml` workflow they call. > > Adds an inline comment documenting the transitive requirement (via the BrowserStack upload workflows). > ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk workflow-only change that broadens GitHub token permissions to match the called reusable workflow; main risk is over-permissioning if not actually required. > > **Overview** > Updates the `run-performance-e2e-experimental.yml` and `run-performance-e2e-release.yml` GitHub Actions workflows to grant `permissions.contents: write` (instead of read-only) so they are at least as permissive as the reusable `run-performance-e2e.yml` workflow they call. > > Adds an inline comment documenting the transitive requirement (via the BrowserStack upload workflows). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 54b2260. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [8fbb9a4](8fbb9a4) Co-authored-by: Curtis David <Curtis.David7@gmail.com>
This comment has been minimized.
This comment has been minimized.
…pay transactions in activity (#30217) - fix: cp-7.77.0 cp-7.78.0 missing metamask pay transactions in activity (#30145) ## **Description** The Activity tab had several bugs causing MetaMask Pay transactions to be missing, duplicated, or unreachable from the source chain. This PR addresses four root causes in production code plus a test alignment for the bridge smoke E2E: 1. **Source-chain visibility.** Submitted EVM transactions were filtered strictly by `tx.chainId`, so a MetaMask Pay parent was only visible on its destination chain. The source chain is recorded on `metamaskPay.chainId` (for gasless flows) or on linked child transactions via `requiredTransactionIds` (for non-gasless flows). A new `selectRelatedChainIdsByTransactionId` selector returns the full set of chain IDs a transaction relates to, and the Activity list now matches against that set. 2. **Dedupe fallback collapsed internal MetaMask Pay transactions.** When a transaction had no nonce, `selectLocalTransactions` fell back to `txParams.actionId` as the dedupe key. `actionId` is a top-level field on `TransactionMeta`, not on `txParams`, so for MetaMask Pay internal transactions (which have no nonce) every entry collapsed onto the same `undefined` key and all but one were dropped. The fallback now uses the top-level `id`, which is always present. 3. **Local transactions were scoped to the wrong account.** `selectLocalTransactions` gated on `selectEvmAddress` — the EVM address of the **currently selected internal account**. When the user picked a non-EVM account (e.g. Solana), this was `undefined` and the selector returned an empty list. Switching to "All popular networks" did not restore the address because that toggle changes enabled networks, not the selected account. It now uses `selectSelectedAccountGroupEvmInternalAccount`, the same source already used by the Activity tab's API query. 4. **Incoming-transaction duplicates.** The `TransactionController` incoming-transactions feature stores incoming transfers as separate `TransactionMeta` entries marked with `isTransfer !== undefined`. The accounts API also returns these transactions in its confirmed history, producing duplicate rows in the Activity tab. The dedupe step now skips entries with `isTransfer !== undefined`, leaving the accounts-API row as the canonical source. 5. **Bridge smoke E2E row alignment.** The Activity list merges pending smart transactions in alongside the real `TransactionMeta` row, producing a stale shell entry that lands at row 0. `bridge-action-smoke` was asserting on row 0 and timing out. The test now asserts on row 1, with a TODO to remove the STX-state merge from the Activity selectors and restore row 0. ## **Changelog** CHANGELOG entry: Fixed MetaMask Pay transactions appearing duplicated or missing from the Activity tab, including on the source chain and when the selected account is non-EVM. ## **Related issues** Fixes: [#30066](#30066) ## **Manual testing steps** ```gherkin Feature: MetaMask Pay Activity visibility Scenario: User views Activity on the chain that funded a MetaMask Pay transaction Given the user has completed a MetaMask Pay transaction funded by a token on chain X with destination chain Y And both chains X and Y are enabled networks When the user opens the Activity tab with chain X selected Then the MetaMask Pay transaction is visible in the list When the user opens the Activity tab with chain Y selected Then the MetaMask Pay transaction is also visible in the list Scenario: User views Activity after switching to a non-EVM account Given the user has pending MetaMask Pay transactions visible in the Activity tab When the user switches to a non-EVM account in the same account group And switches back to "All popular networks" Then the pending MetaMask Pay transactions remain visible Scenario: User views a single on-chain MetaMask Pay transaction Given the user has completed a single-chain MetaMask Pay transaction (for example an mUSD conversion) When the user opens the Activity tab Then the transaction appears exactly once ``` ## **Screenshots/Recordings** ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - [ ] I've tested with a power user scenario - [ ] I've instrumented key operations with Sentry traces for production performance metrics ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > <sup>[Cursor Bugbot](https://cursor.com/bugbot) is generating a summary for commit f45d17e. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [ff95f16](ff95f16) Co-authored-by: Matthew Walsh <matthew.walsh@consensys.net>
…essibility cp-7.78.0 (#30233) - chore: align carousel card heights for accessibility (#30201) <!-- 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** Use fluid heights on cards so large system text doesn’t clip. Problem before: fixed heights + large accessibility text scaling = content clipping inside cards. Now: cards and skeletons are fully fluid (no height prop needed). Only ViewMoreCard keeps a height, and only as a min-h directly inline in WhatsHappeningSection, so it sits at the same height as a typical card at normal font scale. How it looks now with huge font: <img height="800" alt="Simulator Screenshot - iPhone 17 Pro - 2026-05-14 at 18 39 46" src="https://github.com/user-attachments/assets/9097c9eb-c49a-45c4-b998-2392c06676dc" /> And normal/default font size: <img height="800" alt="Simulator Screenshot - iPhone 17 Pro - 2026-05-14 at 18 50 02" src="https://github.com/user-attachments/assets/e4a61f2b-425a-44d4-b650-677f288304e0" /> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk UI/layout change to remove fixed card heights; main risk is minor visual regression in carousel alignment across devices/font scales. > > **Overview** > Makes the What’s Happening carousel cards and loading skeletons **fluid-height** by removing the fixed Tailwind height prop (`twHeightClassName`) from `WhatsHappeningCard` and `WhatsHappeningCardSkeleton`, preventing content clipping with large accessibility text. > > Keeps the “View more” tile visually aligned by switching it to a `min-h-[230px]` constraint, and updates the skeleton test to assert the expected 2-line title and 3-line description placeholder configuration. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 00186c9. 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: Devin Stewart <49423028+Bigshmow@users.noreply.github.com> [a55aeb3](a55aeb3) Co-authored-by: António Regadas <antonio.regadas@consensys.net> Co-authored-by: Devin Stewart <49423028+Bigshmow@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
…ymarket withdraw (#30250) - feat: cp-7.78.0 support deposit-wallet polymarket withdraw (#29953) ## **Description** Adopts the new Polymarket deposit-wallet support landed in [@metamask/transaction-pay-controller@22.5.0](MetaMask/core#8754) so Polymarket users whose pUSD lives in a deposit wallet (a per-user batch contract on Polygon) can withdraw cross-chain through MetaMask Pay. Highlights: - Lets Polymarket deposit-wallet users withdraw cross-chain through MetaMask Pay. - Gated behind a new remote feature flag, with the existing "withdraw unavailable" sheet preserved when off. - Polishes Predict withdraw activity rendering. ## **Changelog** CHANGELOG entry: null ## **Related issues** <!-- Internal --> ## **Manual testing steps** ```gherkin Feature: Polymarket deposit-wallet withdraw Scenario: deposit-wallet user with the flag on Given enableDepositWalletWithdraw is on And the user has a Polymarket deposit wallet with pUSD balance on Polygon When the user taps Withdraw on the Predict balance Then the standard Pay confirmation opens And confirming submits via the Polymarket strategy with no Polygon gas Scenario: deposit-wallet user with the flag off Given enableDepositWalletWithdraw is off When the user taps Withdraw on the Predict balance Then the existing "Withdraw unavailable" sheet is shown ``` ## **Screenshots/Recordings** ### **Before** ### **After** <img width="300" alt="Activity" src="https://github.com/user-attachments/assets/13d5a0e9-a39d-4c0a-9fde-468c5a0a7743" /> ## **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) - [ ] I've tested on Android - [ ] I've tested with a power user scenario - [ ] I've instrumented key operations with Sentry traces for production performance metrics ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes withdrawal behavior and MetaMask Pay transaction configuration for Polymarket `predictWithdraw`, including new controller callbacks and retry logic; mistakes could impact withdraw routing/fees for affected users. Gated by a remote feature flag, limiting blast radius. > > **Overview** > Enables Polymarket *deposit-wallet* users to run `predictWithdraw` through MetaMask Pay when the new `confirmations_pay_extended.enableDepositWalletWithdraw` flag is on; when off, the existing “withdraw unavailable” handling remains. > > Updates Predict/Pay plumbing for deposit-wallet withdraws: `PredictController.prepareWithdraw` now omits `gasFeeToken` for deposit-wallet accounts, `useTransactionPayPostQuote` skips `refundTo` and marks `isPolymarketDepositWallet`, and Transaction Pay initialization wires new Polymarket callbacks that can derive deposit-wallet addresses and submit deposit-wallet batches (with “wallet busy” retries + keyring signing support). > > Polishes confirmations activity rendering for `predictWithdraw` by adding a dedicated `predict_withdraw` title and treating it as a receive-summary type using the source token/network metadata. Tests are added/updated accordingly, and `@metamask/transaction-pay-controller` is bumped to `22.5.0`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 054697c. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [4997055](4997055) Co-authored-by: Matthew Walsh <matthew.walsh@consensys.net>
…ase branch (#30262) - fix: cp-7.78.0 ensure perf e2e run on release branch (#30258) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: only adjusts GitHub Actions gating logic for when the performance E2E workflow runs, without touching app/runtime code. > > **Overview** > Ensures the `run-performance-e2e-release.yml` workflow runs for **all** pushes to `release/*` branches (in addition to `workflow_dispatch`), instead of only running on push when the commit was a `metamaskbot` version bump. > > Keeps the scheduled trigger behavior (checking for recent `metamaskbot` version bumps) but updates comments/logging to reflect the new push trigger conditions. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 3cdedbe. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [c1071c4](c1071c4) Co-authored-by: Curtis David <Curtis.David7@gmail.com>
This comment has been minimized.
This comment has been minimized.
…ake it theme-aware cp-7.78.0 (#30273) - fix(Rewards): Update theMiracle logo and make it theme-aware cp-7.78.0 (#30213) <!-- 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? --> The logo for theMiracle displayed at the bottom of the Benefits screen was incorrect and was hard to see in dark theme This uses the updated, correct logo as an SVG and swaps the color when in dark mode. ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/RWDS-1302 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <img width="1170" height="2532" alt="Simulator Screenshot - iPhone 16e - 2026-05-15 at 11 03 13" src="https://github.com/user-attachments/assets/9de0b304-234c-43b7-9cff-a20786909548" /> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk UI-only change: swaps an SVG asset and passes a theme-derived `color` prop to improve contrast; minimal logic impact covered by unit test updates. > > **Overview** > Updates the Rewards Benefits footer to render the TheMiracle logo using the current theme text color by wiring `useTheme()` into `TheMiracleFooter` and passing a `color` prop to the SVG component. > > Replaces `themiracle-logo.svg` with the corrected artwork and adjusts the unit test to mock/verify the new `color` prop is set to `colors.text.default`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 0ee0184. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [ea0f772](ea0f772) Co-authored-by: Christian Montoya <christian.montoya@consensys.net>
This comment has been minimized.
This comment has been minimized.
…e on first deposit cp-7.77.0 cp-7.78.0 (#30277) - fix(predict): fix unregistered wallet issue on first deposit cp-7.77.0 cp-7.78.0 (#30267) ## **Description** Fixes the first-deposit flow for new Predict users whose Polymarket deposit wallet has been created but is not fully registered yet. Polymarket advised that `STATE_MINED` can happen before the wallet is usable on their side, so the deposit wallet relayer polling now treats only `STATE_CONFIRMED` as a successful completion state. This keeps polling through mined responses until Polymarket confirms the wallet, preventing the follow-up batch transaction from failing with "wallet is not registered". ## **Changelog** CHANGELOG entry: Fixed a bug that caused a user's first Predict deposit to fail while their deposit wallet was still registering. ## **Related issues** Fixes: PRED-886 ## **Manual testing steps** ```gherkin Feature: Predict first deposit wallet registration Scenario: user makes their first Predict deposit Given a new Predict user does not have a registered Polymarket deposit wallet When user starts their first deposit Then the app creates the deposit wallet And waits until the relayer reports STATE_CONFIRMED And proceeds with the wallet batch transaction without a "wallet is not registered" error ``` ## **Screenshots/Recordings** N/A - logic-only relayer polling change. ### **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) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. ## Testing - `yarn jest app/components/UI/Predict/providers/polymarket/depositWallet.test.ts --runInBand` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes deposit-wallet relayer polling completion criteria, which can affect first-deposit transaction flow timing and success. Low code surface area but touches user-critical deposit execution behavior. > > **Overview** > Fixes Predict first-deposit failures by tightening Polymarket relayer success detection: `waitForDepositWalletTransaction` now treats only `STATE_CONFIRMED` (not `STATE_MINED`) as a completion state before proceeding. > > Updates the related unit test to expect continued polling through `STATE_MINED`/no-hash responses until a `STATE_CONFIRMED` transaction hash is returned. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit a36ba27. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [dafc42c](dafc42c) Co-authored-by: Luis Taniça <matallui@gmail.com>
🚀 RC Builds Ready for Testing
More Info
🛡️ Build Environment
API URLs & Details
Build Flags:
AI Test Plan
Executive SummaryRelease Focus: MetaMask Mobile 7.78.0 is a large-scale release introducing major architectural refactors across Bridge/Swaps, Money account, Predict (World Cup), QR hardware wallet scanning, and advanced charting, alongside significant dependency and native layer upgrades. Key Changes:
Critical Areas: Bridge/Swaps: BridgeView architectural refactor with new context provider, insufficient native reserve error, and batch sell token selection, QR Hardware Wallet: Completely reworked scanner error handling and analytics, Money Account: New onboarding, balance card, transfer sheet, and card linkage flows, React Native 0.81.5 upgrade: Native rendering, gesture handling, and third-party library compatibility, Ramp/Checkout: New headless session integration, analytics instrumentation, and URL history tracking Overall Risk: HIGH Recommendation: Conditional go — the breadth of architectural changes across Bridge, Money, QR Hardware, and the React Native upgrade introduces substantial regression risk. Full regression coverage of Bridge/Swaps, QR hardware wallet pairing, Money account flows, and Ramp checkout is required before release. All critical-path transaction flows must pass on both iOS and Android with the new RN 0.81.5 runtime. Release Scenarios (15)High Risk Scenarios (9)1. Bridge/SwapsRisk Level: HIGH Why This Matters: BridgeView was refactored into BridgeViewContent with latestSourceBalance passed as a prop, quote data moved to BridgeQuoteDataContext (breaking the previous direct useBridgeQuoteData call), and the loading state condition was changed. The InsufficientNativeReserveError is a new hook that can block submission. Any regression in context wiring or the new loading condition logic could silently prevent users from bridging or show incorrect error states. Preconditions:
Test Steps:
Expected Outcomes:
2. Bridge/Swaps - Batch Sell Token SelectRisk Level: HIGH Why This Matters: BatchSellTokenSelect is an entirely new screen (395 lines) with complex token filtering (removeStablecoinsFromSourceTokens), chain-based filtering, sort direction toggling, and multi-select with a cap. It integrates with new redux selectors (selectBatchSellDestStablecoinsByChain) and the useTokensWithBalance hook. As a new flow with no prior test coverage in production, any wiring issue could silently fail or crash. Preconditions:
Test Steps:
Expected Outcomes:
3. QR Hardware Wallet - Scanner Error HandlingRisk Level: HIGH Why This Matters: AnimatedQRScanner was substantially rewritten (284 lines added, 44 removed) with new error state management (scanError, scanErrorActiveRef, lastForwardedScanErrorRef), a new error UI overlay with multiple button actions, analytics instrumentation via buildQrHardwareWalletErrorAnalyticsProperties, and the URRegistryDecoder initialization changed from 'new URRegistryDecoder()' to '() => new URRegistryDecoder()'. Any regression could leave users unable to pair or sign with QR hardware wallets. Preconditions:
Test Steps:
Expected Outcomes:
4. Ramp/Checkout - Headless Session and AnalyticsRisk Level: HIGH Why This Matters: Checkout.tsx was significantly expanded (295 lines added) with a new headless session integration (getSession, closeSession, failSession), comprehensive analytics instrumentation (RAMPS_CHECKOUT_OPENED event with new properties), URL history tracking via urlHistoryRef, step index tracking, and a new checkoutSessionId via uuidv4. The previousUrlRef was replaced with a more complex urlHistoryRef object. Regressions here could break the buy flow or cause session leaks. Preconditions:
Test Steps:
Expected Outcomes:
5. Money Account - Onboarding and Balance CardRisk Level: HIGH Why This Matters: MoneyPotentialEarnings.tsx was completely rewritten (229 lines removed, 105 added) replacing the gradient/masked view with a simpler layout using PotentialEarningsTokenRow and useProjectedEarnings. MoneyMetaMaskCard gained a new 'manage' mode and changed the cashback display from Text to Tag. Multiple new components were added (MoneyBalanceCard, MoneyApyInfoSheet, MoneyBalanceInfoSheet, MoneyEarnCryptoInfoSheet, MoneyTransferSheet, MoneyMoreSheet). Any wiring issue in the refactored components could break the Money home screen. Preconditions:
Test Steps:
Expected Outcomes:
6. Money Account - Deposit Transaction BuildingRisk Level: HIGH Why This Matters: moneyAccountTransactions.ts removed the hardcoded USDC address ('0xaf88d065e77c8cC2239327C5EDb3A432268e5831') and replaced it with getMoneyAccountDepositAssetAddress using MUSD_TOKEN_ADDRESS_BY_CHAIN. The minimumMint calculation now skips the RPC call for zero amounts. A regression here could cause deposits to fail silently or use the wrong token address, resulting in lost funds. Preconditions:
Test Steps:
Expected Outcomes:
7. React Native 0.81.5 Upgrade - Core Navigation and RenderingRisk Level: HIGH Why This Matters: React Native was upgraded from 0.76.9 to 0.81.5 (a major version jump), the old react-native patch (564 lines) was removed and replaced with a new 35-line patch. Yarn was upgraded from 4.10.3 to 4.14.1. Multiple native dependency patches were added or replaced (react-native-webview, react-native-payments, react-native-acm, react-native-button, react-native-sensors, react-native-fast-crypto, react-native-aes-crypto). This is the highest-risk change in the release as it affects the entire app runtime. Preconditions:
Test Steps:
Expected Outcomes:
8. Perps - Home View and Market ListRisk Level: HIGH Why This Matters: PerpsHomeView gained 88 lines of new logic, PerpsMarketRowItem was completely restructured (60 lines in/out), PerpsRowSkeleton was simplified (55→33 lines), PerpsStreamManager gained 42 lines of new provider logic, and multiple hooks were refactored (usePerpsOrderForm +190 lines, usePerpsCloseAllCalculations +44 lines, usePerpsDepositStatus refactored). These changes affect the core trading UI and data streaming. Preconditions:
Test Steps:
Expected Outcomes:
9. App Navigation - MainNavigator and App.tsxRisk Level: HIGH Why This Matters: App.tsx and MainNavigator.js both had significant changes (47+43 lines added respectively), new TabsIconBar and TabsIconList components were added (183+117 lines), TabBar gained new constants and types, and the useTabsBarLayout hook was added (254 lines). Navigation is the backbone of the app — any regression here affects all user flows. Preconditions:
Test Steps:
Expected Outcomes:
Medium Risk Scenarios (6)1. Predict - World Cup Feature (UI Rendering Only)Risk Level: MEDIUM Why This Matters: The Predict section received extensive changes for World Cup support (402-line usePredictWorldCup hook, 327-line PredictWorldCup view, new queries, services, and utils) even though the flag is disabled. The existing Predict components (PredictFeed, PredictMarketDetails, PredictBuyWithAnyToken) were also refactored. The usePredictBuyError hook was significantly rewritten with new error source tracking and payment token key logic that could affect existing buy flows. Preconditions:
Test Steps:
Expected Outcomes:
2. Advanced Chart - LivelineChart and OHLCVRisk Level: MEDIUM Why This Matters: LivelineChart.tsx was significantly refactored (235 lines added, 163 removed) with forwardRef and useImperativeHandle added, Logger imported, and the component signature changed. The theme-switch reset logic comment explicitly warns about a potential deadlock if only isChartReady is reset. The LivelineChartTemplate.ts also gained 92 lines. Any regression in the WebView message handling or state reset could break price charts for all tokens. Preconditions:
Test Steps:
Expected Outcomes:
3. Card - MoneyAccountCardLinkage and Spending LimitRisk Level: MEDIUM Why This Matters: useCardDelegation.ts was significantly simplified (97 lines removed, 46 added), useAssetBalances.tsx was refactored (28 lines removed, 19 added), SpendingLimitProgressBar gained new logic (27 lines), and the new useMoneyAccountCardLinkage hook (217 lines) was added. The card delegation simplification is particularly risky as it could remove important state management logic. Preconditions:
Test Steps:
Expected Outcomes:
4. Earn - mUSD Conversion FlowRisk Level: MEDIUM Why This Matters: The MusdQuickConvertView (385 lines) was completely removed along with ConvertTokenRow (172 lines), MusdBalanceCard (83 lines), and related components. The new MusdConversionAssetRow (175 lines) replaces ConvertTokenRow. useMusdConversion.ts was significantly simplified (39 lines removed). The removal of MusdQuickConvertView and its replacement with new components could break the mUSD conversion user journey if any navigation routes or state management was missed. Preconditions:
Test Steps:
Expected Outcomes:
5. Multichain Transaction DetailsRisk Level: MEDIUM Why This Matters: MultichainTransactionDetailsSheet.tsx was refactored (21 lines added, 16 removed) and a new 258-line test file was added indicating significant behavioral changes. MultichainTransactionListItem and MultichainBridgeTransactionListItem both received 4-line additions. These changes affect how users view their cross-chain transaction history. Preconditions:
Test Steps:
Expected Outcomes:
6. Braze Banner IntegrationRisk Level: MEDIUM Why This Matters: BrazeBanner is an entirely new integration (90-line component, 243-line hook, 63-line deep link filter, 66-line properties utility, 105-line README) adding a third-party marketing SDK. Even with the flag disabled, the SDK initialization code runs and the isAllowedBrazeDeeplink function is in the deep link handling path. Any SDK initialization error or deep link filter regression could affect all users. Preconditions:
Test Steps:
Expected Outcomes:
Teams Sign-off Status (0/23)Awaiting sign-off (23): Accounts, Assets, BE Trade, Bots Team, Card, Confirmations, Core Platform, Delegation, Design System, Earn, LavaMoat, Mobile Platform, Mobile UX, Money Movement, Networks, Onboarding, Perps, Predict, Rewards, Social & AI, Swaps and Bridge, team-mobile-delivery, Transactions Excluded Features - Feature Flags Disabled (59)The following features are disabled via feature flags and should NOT be tested:
Generated by AI Test Plan Analyzer (claude-sonnet-4-6) at 2026-05-16T09:37:24.754Z AI generated test plan (JSON): Available as artifact |
🚀 v7.78.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
Conduct regression and exploratory testing for your functional areas, including automated and manual tests for critical workflows.
Focus on exploratory testing across the wallet, prioritize high-impact areas, and triage any Sentry errors found during testing.
Validate new functionalities and provide feedback to support release monitoring.
GitHub Signoff
Issue Resolution
Cherry-Picking Criteria
🗓️ Timeline and Milestones
✅ Signoff Checklist
Each team is responsible for signing off via GitHub. Use the checkbox below to track signoff completion:
Team sign-off checklist
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