release: 7.76.0#29584
Conversation
<!-- 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 draft PR stacks the **Headless Buy** proof-of-concept work through **Phase 4** on top of `main`. It continues the incremental sequence started by [#29144](#29144) (Phases 1–3 + 3.1) and is intended for incremental review and CI validation before follow-up phases (Headless Host, skip-BuildQuote, routing callbacks). ### Scope vs `main` (full branch) - **Phases 1–3 + 3.1** — unchanged from [#29144](#29144) (playground, `useHeadlessBuy`, `sessionRegistry`, `startHeadlessBuy`, BuildQuote `headlessSessionId` plumbing). - **Phase 4 — this PR** — pure refactor of the post-quote continuation logic. Extract `handleWidgetProviderContinue` (~111 lines) and `handleNativeProviderContinue` (~60 lines) plus the local `navigateAfterExternalBrowser` helper out of `BuildQuote.tsx` into a new `useContinueWithQuote(quote, ctx)` hook so both BuildQuote and the upcoming Headless Host (Phase 5) can drive the post-quote flow without copy-paste. **No user-visible change** and no new public surface — the hook is internal to `app/components/UI/Ramp`. ### Diff vs previous POC branches (incremental) | Compare | Stat (approx.) | What it adds | | --- | --- | --- | | [`main...poc/headless-buy-phase-1`](https://github.com/MetaMask/metamask-mobile/compare/main...poc/headless-buy-phase-1?expand=0) | Phase 1 only | Playground screen, route, Settings row, `PLAN.md` scaffold. | | [`poc/headless-buy-phase-1...poc/headless-buy-phase-2`](https://github.com/MetaMask/metamask-mobile/compare/poc/headless-buy-phase-1...poc/headless-buy-phase-2?expand=0) | +~2.3k lines | `useHeadlessBuy`, `types`, barrel, playground wiring to hook (`getQuotes`, amount, quotes UI, sandbox, i18n). | | [`poc/headless-buy-phase-2...poc/headless-buy-phase-3`](https://github.com/MetaMask/metamask-mobile/compare/poc/headless-buy-phase-2...poc/headless-buy-phase-3?expand=0) | +~1k lines | `sessionRegistry` + tests, `startHeadlessBuy` + tests, BuildQuote param + nav test, playground session lifecycle UI + tests, `PLAN.md` updates. | | [`poc/headless-buy-phase-3...poc/headless-buy-phase-4`](https://github.com/MetaMask/metamask-mobile/compare/poc/headless-buy-phase-3...poc/headless-buy-phase-4?expand=0) | +314/−251 (net −228 in `BuildQuote.tsx`; +465 in hook + tests) | `useContinueWithQuote.ts` + `useContinueWithQuote.test.ts`, BuildQuote refactor to consume it, BuildQuote.test.tsx trim to wiring, `PLAN.md` Phase 4 ticked. | Full branch vs `main`: [`main...poc/headless-buy-phase-4`](https://github.com/MetaMask/metamask-mobile/compare/main...poc/headless-buy-phase-4?expand=0). ### What Phase 4 actually does - **New** `app/components/UI/Ramp/hooks/useContinueWithQuote.ts`: - Signature: `useContinueWithQuote(): { continueWithQuote: (quote: Quote, ctx: { amount: number; assetId: string }) => Promise<void> }`. - Internally dispatches via `isNativeProvider(quote)` to a private native path (Transak: `checkExistingToken` → `getBuyQuote` → `routeAfterAuthentication`, or EnterEmail / VerifyIdentity when unauthenticated) or widget path (fetch widget URL via `getBuyWidgetData`, then either in-app Checkout or external browser via `Linking` / `InAppBrowser` with a `navigateAfterExternalBrowser` reset). - **Error contract**: on failure the hook calls `reportRampsError` (preserves Logger/Sentry side effect) **exactly once per failure** and throws an `Error` whose `message` is a user-facing string. Widget path uses two sequential try/catch blocks (fetch, then use) so the no-URL branch can report with its own context without the outer catch double-reporting. Callers `catch` to drive their own UI. - **Not managed by the hook**: `isContinueLoading`, `rampsError`, and `RAMPS_CONTINUE_BUTTON_CLICKED` analytics. Those stay with the caller. - **Refactored** `app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx`: - Drops the two handlers, `navigateAfterExternalBrowser`, and the now-unused `useTransakController` / `useTransakRouting` / `selectHasAgreedTransakNativePolicy` / `getBuyWidgetData` / `addPrecreatedOrder` wiring (~18 imports removed). - `handleContinuePress` is now a thin wrapper: fires `RAMPS_CONTINUE_BUTTON_CLICKED` analytics, then awaits `continueWithQuote(selectedQuote, { amount, assetId })` inside `try/catch/finally` around `isContinueLoading` and `rampsError`. - **Tests**: - Three behavior describes migrated verbatim from `BuildQuote.test.tsx` into `useContinueWithQuote.test.ts` (native provider, widget provider, `navigateAfterExternalBrowser`), plus a new `error contract` describe asserting the thrown `Error.message` matches `reportRampsError`'s return value and that reporting fires exactly once. - `BuildQuote.test.tsx` gets a slim `handleContinuePress wiring` describe that mocks `useContinueWithQuote` and asserts (a) correct args, (b) analytics fires before the hook call, (c) rejection surfaces in the rampsError banner, (d) no call when `selectedProvider` is null. - **`PLAN.md`**: Phase 4 checkbox ticked. No body edits. ### Intentionally out of scope for this PR (follow-up phases) - **Phase 4b** — Headless Host screen + parameterized `useTransakRouting` reset base. The hook still reads `currency` / `selectedToken.chainId` / `selectedPaymentMethod.id` / `selectedProvider.name` from `useRampsController` — these will return null for headless callers who don't pre-seed the controller (Phase 3.1). A `// TODO(phase-5)` comment in the hook flags the debt. - **Phase 5** — Skip BuildQuote in headless mode; Headless Host consumes the hook directly. - **Phase 6** — Bypass order-processing redirect + fire `onOrderCreated`. ## **Changelog** CHANGELOG entry: (Internal) Extracted post-quote continuation logic from BuildQuote into a new `useContinueWithQuote` hook — no user-visible change. ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: Buy flow regression (Phase 4 is a pure refactor — behavior must match main) Scenario: Aggregator widget provider (in-app Checkout) Given the user is on BuildQuote with a valid amount and an aggregator provider (e.g. MoonPay) selected When the user taps Continue Then the in-app Checkout WebView opens with the widget URL and correct provider branding And no rampsError banner is shown Scenario: Aggregator widget provider (external browser / PayPal custom action) Given the user is on BuildQuote with a valid amount and a widget provider with useExternalBrowser=true When the user taps Continue Then the widget URL opens in the external browser (or in-app browser when available) And on success the app resets to the order-details screen with the callback URL And on cancel the app resets back to BuildQuote Scenario: Native provider (Transak), authenticated Given the user is on BuildQuote with a valid amount and Transak selected And the user already has a valid Transak token When the user taps Continue Then a fresh Transak buy quote is fetched and the post-authentication flow advances (KYC / webview / bank details) Scenario: Native provider (Transak), unauthenticated — first time Given the user is on BuildQuote with a valid amount and Transak selected And the user has NOT agreed to the Transak native policy When the user taps Continue Then the VerifyIdentity screen opens with amount / currency / assetId Scenario: Native provider (Transak), unauthenticated — returning Given the user is on BuildQuote with a valid amount and Transak selected And the user has previously agreed to the Transak native policy When the user taps Continue Then the EnterEmail screen opens with amount / currency / assetId Scenario: Widget fetch error surfaces the same banner as before Given the user is on BuildQuote with a valid amount and a widget provider selected And the widget-data endpoint fails (e.g. network error, missing URL) When the user taps Continue Then the rampsError banner shows the same user-facing message as on main And the continue button becomes enabled again (spinner stops) Scenario: Headless Playground flow unchanged Given the user is on the Headless Buy playground (internal build) When the user taps Start headless buy and then Cancel headless session Then the session lifecycle + event log behaves exactly as on Phase 3 (BuildQuote opens, cancel fires onClose consumer_cancelled) ``` ## **Screenshots/Recordings** ### **Before** N/A ### **After** N/A — Phase 4 is a pure refactor. No UI changes. https://github.com/user-attachments/assets/22fcea1f-2b8b-4536-a6ec-0b0ff2aa569f https://github.com/user-attachments/assets/ba4f1b6d-edf4-43c5-9ab2-84128e21ba3d ## **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. <!-- Generated with the help of the pr-description AI skill --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Refactors core buy-flow continuation/navigation (native Transak + widget/external-browser paths) into a shared hook; behavior should be unchanged but small mismatches could break checkout routing or error surfacing. > > **Overview** > Extracts the post-quote “Continue” logic from `BuildQuote` into a new reusable `useContinueWithQuote` hook that handles both **native (Transak)** and **widget/aggregator** flows, including external-browser/InAppBrowser routing and navigation resets. > > `BuildQuote` is simplified to fire analytics, toggle loading, call `continueWithQuote(selectedQuote, { amount, assetId })`, and display the thrown user-facing error message. Tests are reorganized accordingly: detailed continuation behavior moves to `useContinueWithQuote.test.ts`, while `BuildQuote.test.tsx` now focuses on wiring/ordering/error surfacing. `PLAN.md` marks Phase 4 complete. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit d3aa850. 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: Pedro Pablo Aste Kompen <wachunei@gmail.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: wachunei <1024246+wachunei@users.noreply.github.com>
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** <!-- 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? --> Fixes the perps modify bottom sheet dismissal when tapping on the overlay ## **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: https://consensys.slack.com/archives/C08U6DYNJ1G/p1776265582646229 ## **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] --> https://consensys.slack.com/archives/C08U6DYNJ1G/p1776265582646229 ### **After** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/9d970cba-af60-4cc7-bd07-c5d683376257 ## **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.
<!-- 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** Fixes invalid deeplink navigation for Money Hub feature. <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: fixes invalid deeplink navigation for Money Hub feature. ## **Related issues** Fixes: - [MUSD-696: Fix Money Hub Deeplink navigation](https://consensyssoftware.atlassian.net/browse/MUSD-696) ## **Manual testing steps** ```gherkin Feature: Money Hub deeplink navigation Scenario: user opens earn-musd deeplink after seeing the education screen Given user has previously seen the mUSD conversion education screen And user is geo-eligible for mUSD conversion And the Money Hub feature flag is enabled When user opens the earn-musd deeplink Then user is navigated to the Money Hub Scenario: user opens earn-musd deeplink when Money Hub is disabled Given user has previously seen the mUSD conversion education screen And user is geo-eligible for mUSD conversion And the Money Hub feature flag is disabled When user opens the earn-musd deeplink Then user is navigated to the Wallet home screen Scenario: user opens earn-musd deeplink when geo-ineligible Given user has previously seen the mUSD conversion education screen And user is geo-ineligible for mUSD conversion When user opens the earn-musd deeplink Then user is navigated to the Wallet home screen Scenario: user opens earn-musd deeplink before seeing the education screen Given user has not seen the mUSD conversion education screen When user opens the earn-musd deeplink Then user is navigated to the mUSD conversion education screen with the deeplink flag set Scenario: user dismisses the education screen via deeplink with Money Hub enabled Given user arrived at the mUSD conversion education screen via deeplink And user is geo-eligible for mUSD conversion And the Money Hub feature flag is enabled When user taps "Not Now" Then the education screen is popped from the navigation stack And user is navigated to the Money Hub Scenario: user dismisses the education screen in normal (non-deeplink) flow Given user arrived at the mUSD conversion education screen via normal navigation When user taps "Not Now" Then user is navigated back to the previous 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** https://github.com/user-attachments/assets/54c734bf-0a95-4313-8a72-76d941afdd21 <!-- 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] > **Medium Risk** > Changes deeplink and education-screen navigation decisions for mUSD, including geo-eligibility gating and a new Money Hub redirect path; incorrect conditions could send users to the wrong screen or bypass intended compliance blocking. > > **Overview** > Fixes `earn-musd` deeplink behavior by routing users who have already seen the mUSD education screen **directly to Money Hub** (`Routes.WALLET.CASH_TOKENS_FULL_VIEW`) when the Money Hub flag is enabled and the user is geo-eligible; otherwise it falls back to `Routes.WALLET.HOME`. > > Updates the mUSD conversion education screen to support a new deeplink action `navigate_money_hub` (including analytics `redirects_to`), and changes the secondary "Not now" behavior to pop the screen and redirect to Money Hub only for deeplink + geo-eligible + flag-enabled cases. > > Refactors geo-eligibility computation into a new memoized selector `selectIsMusdConversionGeoEligible` (with tests) and wires `useMusdConversionEligibility` to use it; several unrelated tests were updated to mock `getDetectedGeolocation`/`selectMusdConversionBlockedCountries`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 78d390a. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description**
PR to use DS icons instead of custom SVG icons for chart.
## **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] -->
https://github.com/user-attachments/assets/184afbb6-2462-4140-a793-a112cf0e03fe
### **After**
<!-- [screenshots/recordings] -->
https://github.com/user-attachments/assets/d8f65547-b6b3-4883-926f-18598d2751ef
## **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-only change that swaps the chart type toggle’s custom SVG
icons for design-system `Icon` components; behavior and data flow are
unchanged.
>
> **Overview**
> Updates the token details chart `TimeRangeSelector` to **remove custom
`react-native-svg` candlestick/line icons** and instead render the
design-system `Icon` (`IconName.TrendUp` / `IconName.Candlestick`) for
the chart type toggle.
>
> This simplifies icon rendering by relying on DS-provided sizing/color
tokens (`IconSize`, `IconColor`) rather than inline SVG paths.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
a710363. 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? --> It was discovered that we're still using UAT signing configuration for main-dev builds, which is incorrect. It should be using a development profile. Since we have not yet set up a development profile in AWS, this PR temporarily routes main-dev to use github environments instead. ## **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: https://consensys.slack.com/archives/C02U025CVU4/p1776699450350369 ## **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** > Moderate risk because it changes CI code-signing behavior and secret sources for `main-dev` iOS builds, which can break build/release outputs if misconfigured. Scope is limited to the `main-dev` workflow path and does not affect prod/rc signing via AWS. > > **Overview** > Updates `main-dev` to stop using UAT AWS signing config and instead **temporarily sign iOS builds using GitHub Environment secrets** until dev signing is migrated to AWS. > > Adds a `build.yml` step that, for `ios` + `main-dev` only, decodes a base64 `.p12` and provisioning profile from secrets, creates/imports them into a temporary keychain, and installs the provisioning profile. `builds.yml` is adjusted to omit the `main-dev` AWS `signing` block and to include the new iOS signing secret mappings. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 083bee9. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…28701) <!-- 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 consolidates the account selector on the full-page experience and removes the feature flag that toggled it. The add-wallet / add-account flow no longer uses bottom sheet components; it opens in a standard `Modal` with the same headers and actions as before. `PickerBase` gains an optional `showDropdownIcon` prop (default `true`). `PickerAccount` always passes `false` so the wallet account picker no longer shows a trailing dropdown arrow, while other pickers keep the previous behavior. ## **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 the account selector to use the full-page list for all users and removed the dropdown arrow from the wallet account picker. ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MUL-1695 ## **Manual testing steps** ```gherkin Feature: Account selector and account picker Scenario: Open account list from wallet Given the user is on the wallet home screen When the user opens the account selector Then the full-page account list is shown and the user can switch accounts or open add wallet Scenario: Account picker on wallet header Given the user is on the wallet home screen When the user views the account name control Then no dropdown arrow is shown next to the account name ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** N/A ### **After** https://github.com/user-attachments/assets/e69513cb-f338-496a-be75-144fe58b5411 ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Moderate UI/navigation refactor in the account selector flow, replacing bottom-sheet behavior with animated full-page + nested modal, which could affect dismissal/navigation and related tests across platforms. > > **Overview** > Unifies `AccountSelector` onto the animated full-page presentation for all users by removing the full-page feature-flag path and the bottom-sheet implementation. > > The add-account/add-wallet actions now open via a standard `Modal` with its own header/back handling, and the footer action buttons are rendered directly (new footer styles) instead of using `BottomSheetFooter`. Tests and E2E page objects were updated accordingly (including snapshot updates and using a header back button to dismiss stacked modals). > > Separately, the wallet `PickerAccount` no longer applies dropdown-arrow sizing/styling (removing the trailing dropdown affordance). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 34f2a20. 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 the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** Add shared utility that runs hardware wallet operations behind the standard readiness + awaiting-confirmation flow. Includes foundation helpers (getDeviceIdForAddress, normalizeReplacementGasFeeParams) as prerequisites. <!-- 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** Related to: https://consensyssoftware.atlassian.net/browse/MUL-1741 ## **Manual testing steps** This can only be tested via #29087 ## **Screenshots/Recordings** Not applicable ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches the hardware wallet provider’s wallet-type resolution and introduces a new shared signing wrapper; mistakes could lead to incorrect adapter selection or confirmation/error UI behavior during signing. > > **Overview** > Adds a shared `executeHardwareWalletOperation` helper to standardize hardware-wallet operations: it resolves device id from address, gates on `ensureDeviceReady`, shows/hides the awaiting-confirmation UI, and centralizes rejection + error handling (including user-cancel suppression), with unit coverage. > > Updates `HardwareWalletProvider`/context to support a new `setPendingOperationAddress` hook and to *auto-derive* the effective wallet type from the in-flight operation address (via `getHardwareWalletTypeForAddress`) when no explicit `targetWalletType` is set. Also tightens the `setTargetWalletType` context type and updates affected tests/mocks. > > Separately introduces a `ReplacementGasFeeValues` type alias and reuses it in replacement gas normalization/repricing helpers (no functional behavior change). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 3db6970. 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 PR updates some strings in the Rewards tab. Some of these strings
were incorrect or didn't convey enough information. The legal disclaimer
was particularly off-base, as well as the campaign end strings.
## **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="1170" height="2532" alt="Simulator Screenshot - iPhone 16e -
2026-04-23 at 22 59 19"
src="https://github.com/user-attachments/assets/e925bcda-f99f-4a02-b457-ac63ef098c0a"
/>
## **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`.
-->
- [ ] 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**
> Low-code-risk (copy-only) change, but it updates user-facing
legal/disclosure language and campaign messaging, which may require
careful product/legal review for accuracy and compliance.
>
> **Overview**
> Updates Rewards English copy in `locales/languages/en.json`, including
a new onboarding description, a revised legal disclaimer ("Terms of Use"
+ clearer disclosure about opting in all device accounts and tracking
onchain activity), and clearer campaign-related messaging (load error
text and end/results banners switching from *contest* to *campaign*
wording).
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
092c410. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**
Adds the on-chain transaction layer for Money Account crypto deposits
and withdrawals (MUSD-593).
**What changed:**
- Added `buildMoneyAccountDepositBatch` and `buildMoneyAccountWithdraw`
utility functions (`moneyAccountTransactions.ts`) that encode the
approve + deposit / withdraw calldata against the Veda vault contracts
(Teller, Accountant, Lens).
- Added `useMoneyAccountDeposit` and `useMoneyAccountWithdrawal` hooks
(`useMoneyAccount.ts`) that read vault configuration from remote feature
flags, derive the provider from the active network client, and submit
the transactions via `addTransactionBatch` / `addTransaction`.
- Added `selectMoneyAccountVaultConfig` selector and the
`moneyAccountDepositConfig` remote feature flag registry entry, which
holds chain ID and contract addresses for the vault.
- Temporarily wired the "Add" button in `MoneyHomeView` to
`initiateDeposit` with a hardcoded amount as a dev integration test;
this will be replaced once the amount entry UI is built.
**Deposit flow:** `approve(boringVault, amount)` + `deposit(asset,
amount, minimumMint, 0x0)` submitted as an atomic batch. A 0.1% slippage
tolerance is applied to the `previewDeposit` quote.
**Withdrawal flow:** `getRate` → convert asset amount to vault shares →
`withdraw(asset, shares, minimumAssets, to)`.
## **Changelog**
CHANGELOG entry: null
## **TODO**
Note that the code has 2 todos that should be address seperatly:
- adding hook to get amount from MM pay
- updating addresses for mUSD and veda vault once we have a testing one
ready on monad
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Introduces new transaction-construction and submission code paths that
interact with wallet confirmations and remote-configured contract
addresses; mistakes could cause failed or incorrect on-chain calls. Risk
is reduced by added unit tests and feature-flag gating, but still
impacts critical transaction flow.
>
> **Overview**
> Adds the on-chain transaction building/submission layer for Money
Account deposits and withdrawals.
>
> Introduces `buildMoneyAccountDepositBatch` (approve + deposit batch
with preview+slippage) and `buildMoneyAccountWithdraw` (rate-based share
conversion + slippage) utilities, plus
`useMoneyAccountDeposit`/`useMoneyAccountWithdrawal` hooks that fetch
vault addresses from remote feature flags, resolve provider/network
client, navigate to confirmations, and submit via
`addTransactionBatch`/`addTransaction` with error logging.
>
> Adds a new `moneyAccountVaultConfig` remote flag (with a dev fallback
gated by `MM_MONEY_DEPOSIT_CONFIG_DEV_ENABLED`) and corresponding
selector/tests; updates test babel config to avoid inlining env vars for
those selector files. The Money home view only adds an import and TODO
scaffolding for wiring deposits later (no behavior change).
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
46369dc. 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: Shane T <muldots@gmail.com>
…ons tests (#29287) <!-- 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** > Refactors confirmations-related unit tests to stop using toMatchSnapshot and instead assert on specific UI elements via @testing-library/react-native (e.g., presence of buttons, text, and testIDs) across Tooltip, BottomModal, CopyButton, Network, BlockaidBanner, AddressElement/List, approval templates/results, and transaction header. > > Deletes the associated Jest snapshot files and adds a testID (blockaid-banner-loader) to the BlockaidBanner ActivityIndicator so the loader state can be asserted without snapshots. ## **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: changes are confined to test expectations and snapshot removals, with only a minor UI change adding a `testID` to the Blockaid loader for testability. > > **Overview** > Refactors confirmations-related unit tests to **stop using `toMatchSnapshot`** and instead assert on specific UI elements via `@testing-library/react-native` (e.g., presence of buttons, text, and testIDs) across Tooltip, BottomModal, CopyButton, Network, BlockaidBanner, AddressElement/List, approval templates/results, and transaction header. > > Deletes the associated Jest snapshot files and adds a `testID` (`blockaid-banner-loader`) to the BlockaidBanner `ActivityIndicator` so the loader state can be asserted without snapshots. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 0d0a988. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description**
This PR adds the missing-price warning flow for bridge quotes when price
data is unavailable. It shows an inline danger banner in the bridge
view, presents a confirmation modal before submission, and keeps the
warning order consistent so token warnings are handled before the
missing-price prompt. It also adds unit coverage for the new banner,
modal, and warning sequencing.
## **Changelog**
CHANGELOG entry: Added a warning flow in bridge quotes when token price
data is unavailable.
## **Related issues**
Fixes: SWAPS-4387
## **Manual testing steps**
```gherkin
Feature: bridge missing-price warning flow
Scenario: user sees a missing-price warning on the quote
Given a bridge quote is available without price data
When user reviews the bridge quote
Then the bridge view shows a danger warning about missing price information
Scenario: user confirms a bridge quote with missing price data
Given a bridge quote is available without price data
When user taps the button to continue with the bridge quote
Then a missing-price confirmation modal is shown before submission
Scenario: user sees token warning before missing-price confirmation
Given a bridge quote is available with a token warning and without price data
When user taps the button to continue with the bridge quote
Then the token warning modal is shown first
And continuing from the token warning opens the missing-price confirmation modal
```
## **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)
Not applicable for this warning-flow change.
- [ ] 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]
> **Medium Risk**
> Changes the bridge confirmation routing to block submission and
require an extra modal confirmation when quote price data/price impact
is missing, which could affect transaction flow if the detection logic
misfires. UI-only banner/text updates are low risk, but the new gating
impacts a core swap/bridge path.
>
> **Overview**
> Adds a **missing price data warning flow** for bridge quotes: when
`activeQuote.quote.priceData` or `priceImpact` is absent/empty, the
Bridge view now shows an inline *danger* `BannerAlert` and the confirm
action routes to a new `MissingPriceModal` instead of submitting.
>
> Introduces `hasMissingPriceData()` for shared detection, wires the new
modal into `Routes`/bridge modal stack, and ensures **warning
precedence**: token warning modal is shown first, and proceeding from
`TokenWarningModal` can redirect into the missing-price modal. Updates
the English copy for the missing-price title/body and adds unit tests
covering banner rendering and modal routing/ordering.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
1285121. 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** Refactor QuickBuy confirm button with blue color, animated spinner-to-checkmark transition, and haptic feedback. - Replace generic `Button` with custom `QuickBuyConfirmButton` component - Button is now blue (`colors.primary.default`) with 12px border radius, matching Figma design - On transaction submission, show white spinner; on success, transition to checkmark icon with scale animation - Add haptic feedback: `NotificationFeedbackType.Success` on tx success, `.Error` on failure (Perps pattern) - Auto-close sheet 800ms after success state appears - Update hook to track button state (`idle` | `loading` | `success`) instead of separate `isConfirmLoading` boolean https://github.com/user-attachments/assets/be4de517-f7ef-41e4-ae7e-1f683f971d55 <!-- 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: no-changelog ## **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 - [ ] 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: changes the QuickBuy transaction submission UX (new success phase, delayed close, and haptic feedback) and replaces the design-system `Button` with a custom component, which could affect interaction/disabled states during bridging. > > **Overview** > Updates the QuickBuy confirm flow to use a custom `QuickBuyConfirmButton` that supports an `idle`/`loading`/`success` state, showing a spinner during submission and an animated checkmark on success. > > Refactors `useQuickBuyBottomSheet` to expose `confirmButtonState` (replacing `isConfirmLoading`), trigger haptic feedback on success/error via `expo-haptics`, and delay sheet close by ~800ms after a successful submit before navigating to `Routes.TRANSACTIONS_VIEW`. Tests are updated to assert the new state model. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 74b79d0. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Don't show a date in the campaign card is the status is upcoming ## **Changelog** CHANGELOG entry: null <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk UI-only change that conditionally hides existing text; main risk is small visual regression if other statuses were expected to show the date separator/label. > > **Overview** > **Upcoming reward campaigns no longer show a date line in the campaign tile.** `CampaignTile` now conditionally renders the date separator and `dateLabel` only when `campaignStatus !== 'upcoming'`. > > Tests were updated to assert that the `campaign-tile-date-info` element is *not* rendered for upcoming campaigns (while still present for active/complete). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit c9a2d89. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…ble cp-7.74.0 (#29313) ## **Description** When no viable quote existed for a Perps withdraw (e.g. $0.1 → ETH on Ethereum), the confirmation still showed a big transaction fee and an enabled Withdraw button, letting the user submit into a failing transaction. `useNoPayTokenQuotesAlert`'s `isOptionalOnly` check was matching the post-quote `sourceAmount.targetTokenAddress` (the destination token, e.g. native ETH `0x0…0`) against a `skipIfBalance` required token on a different chain (Arbitrum native gas, also `0x0…0`). That false match suppressed the `NoPayTokenQuotes` alert. `isOptionalOnly` is only meaningful for non-post-quote flows, so this PR bypasses it for post-quote. The existing `CustomAmountInfo` logic then hides the fee rows and shows the disabled "No quotes" button as designed. ## **Changelog** CHANGELOG entry: Fixed Perps withdraw showing a transaction fee and enabled button when no route was available; the rows now hide and the button shows "No quotes". ## **Related issues** Fixes: [#29297](#29297) ## **Manual testing steps** ~~~gherkin Feature: Perps withdraw handles missing quotes Scenario: no viable quote for the amount Given user is on the Perps withdraw confirmation When user enters "0.1" and selects "ETH on Ethereum" And user presses Done Then "Transaction fee" and "You'll receive" rows are not shown And the primary button shows "No quotes" and is disabled Scenario: viable quote exists (regression) Given user is on the Perps withdraw confirmation When user enters a viable amount and selects any receive token And user presses Done Then "Transaction fee" and "You'll receive" rows are shown And the primary button shows "Withdraw" and is enabled ~~~ ## **Screenshots/Recordings** ### **Before** <img width="448" height="221" alt="image" src="https://github.com/user-attachments/assets/727d8f21-ce3a-41af-a90e-d30bcadc5c1b" /> ### **After** $0.1 <img width="460" height="220" alt="image" src="https://github.com/user-attachments/assets/05877a43-e94a-46ff-85d4-0ad7844fd622" /> $0.5 <img width="457" height="240" alt="image" src="https://github.com/user-attachments/assets/773271b5-a001-405b-b608-4c5fc6de9564" /> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes blocking alert logic in transaction confirmations for post-quote flows, which can affect whether users can proceed with withdrawals; risk is moderated by targeted condition and added tests. > > **Overview** > Fixes a false-negative in the `NoPayTokenQuotes` blocking alert for *post-quote* flows by bypassing the `isOptionalOnly` (skip-if-balance) suppression when `useTransactionPayIsPostQuote` is true, preventing cross-chain native-token address collisions (e.g., `0x0…0`) from hiding the no-quotes state. > > Adds/updates unit tests to cover the non-post-quote optional-token case and a regression scenario where a post-quote destination token address would previously suppress the alert. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f3b1072. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
## **Description** In the "trade with any token" flow, the custom confirm button performs its own validation but was not tracking when standardized blocking alerts (e.g. `useInsufficientPayTokenBalanceAlert`, `useNoPayTokenQuotesAlert`) fire. This meant validation errors like "insufficient funds" and "insufficient source token balance for relay deposit" — which account for the majority of deposit failures — were invisible in Mixpanel. This PR adds two `useEffect` hooks in `PerpsOrderViewContentBase` that fire `PERPS_ERROR` analytics events when: 1. **Blocking pay-token alerts** appear (e.g. insufficient balance for relay quote totals, no quotes available) — tracked as `error_type: 'validation'` with the alert's human-readable message. 2. **Insufficient pay-token balance warning** appears (custom margin-only check) — tracked as `error_type: 'warning'` with standardized `insufficient_balance` key. Both events include `error_type`, `error_message` / `warning_message`, `screen_name`, and `screen_type` properties, following the existing `PERPS_ERROR` schema. Note: the UI integration (button disabling + alert message rendering) was already in place. This PR adds only the missing analytics tracking and corresponding unit tests. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TAT-2720 ## **Manual testing steps** ```gherkin Feature: Pay-token validation error tracking in analytics Scenario: user sees blocking pay-token alert tracked in analytics Given the user is on the Perps order screen with "trade with any token" enabled And the user has selected a custom payment token (not Perps balance) When the relay quote returns an insufficient balance alert Then a PERPS_ERROR event fires with error_type "validation" and the alert message And the Place Order button is disabled Scenario: user sees no analytics event when using Perps balance Given the user is on the Perps order screen And the user is paying with their Perps balance (not a custom token) When blocking pay-token alerts would otherwise fire Then no PERPS_ERROR event is tracked (hasCustomTokenSelected is false) ``` ## **Screenshots/Recordings** N/A — no UI changes; analytics-only. ## **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: adds analytics-only `PERPS_ERROR` tracking in `PerpsOrderView` plus unit tests; behavior changes are limited to when events fire and could affect metrics volume if conditions are mis-triggered. > > **Overview** > Adds declarative `usePerpsEventTracking` instrumentation in `PerpsOrderView` to emit `MetaMetricsEvents.PERPS_ERROR` when **blocking pay-token alerts** appear (tracked as *validation* with a robust message/title/key fallback) and when the **insufficient pay-token balance** check is true (tracked as *warning* with the standardized `insufficient_balance` key). > > Extends `PerpsOrderView.test.tsx` with coverage ensuring events fire only for custom-token flows (not Perps balance), don’t fire when no blocking alerts exist, and validate the fallback message selection logic; introduces a mock for `useTransactionPayToken` to support the warning-path tests. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit b96cf19. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** This PR refactors and unifies security badge/icon display logic across the Token Details page, Trending tokens, and Security Trust screens to ensure consistent visual presentation and centralized configuration. https://www.figma.com/design/iqPZeL5rVg7tWGmacjIeyH/Token-details?node-id=6753-29048&p=f&m=dev ### Key Changes 1. **Unified Icon Configuration** - Merged `getSecurityBadgeConfig` into `getResultTypeConfig` with explicit badge configuration 2. **Consistent Icon Display** - All security icons now use the same source of truth across components 3. **Improved Security Warnings** - Enhanced malicious token warning UI in bottom sheet 4. **Fixed Icon Discrepancies** - Resolved inconsistencies between banners, badges, and feature tags ### 🎨 UI/UX Improvements **Security Badge Bottom Sheet** (`SecurityBadgeBottomSheet.tsx`): - ✅ Display max 5 feature IDs for risky/malicious tokens - ✅ Changed button layout from horizontal to vertical - ✅ Updated button text from "Proceed" to "Continue anyway" - ✅ Added red background with black text for "Continue anyway" on malicious tokens - ✅ Added malicious token banner in bottomSheet - ✅ Malicious banner text: "{Symbol} is flagged as malicious. It's likely to steal funds from anyone who interacts with it." **Token Details Page** (`AssetOverviewContent.tsx`): - ✅ Updated badge/banner display - now shows ONLY verified icon badge (not for warning/malicious) - ✅ Warning/Malicious tokens show banner only (no badge icon next to name) **Trending Tokens** (`TrendingTokenRowItem.tsx`): - ✅ Updated to use `IconAlert` component for consistent icon display - ✅ Inline badges now match icon style with banners and other security UIs ## **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: Implements new trust security token details design specs ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/jira/software/c/projects/ASSETS/boards/1567?assignee=61a5edc8b0b630006a140ec1&selectedIssue=ASSETS-3105 Fixes: https://consensyssoftware.atlassian.net/jira/software/c/projects/ASSETS/boards/1567?assignee=61a5edc8b0b630006a140ec1&selectedIssue=ASSETS-3105 ## **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** https://github.com/user-attachments/assets/6e92aeb5-230d-4ccb-84d2-a95156ed2a32 <!-- 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 security severity config and reworks token security warnings/bottom-sheet UI across multiple entry points, which could affect navigation params and what security indicators render for each result type. > > **Overview** > Centralizes security severity presentation by expanding `getResultTypeConfig` to include `IconAlert` severity, inline badge config, and bottom-sheet copy helpers, and removing the separate `getSecurityBadgeConfig` path. > > Updates token security UI to use the shared config everywhere: feature tags in `SecurityTrustScreen` and `SecurityTrustEntryCard` now render `IconAlert`, Trending token rows use the new badge config (with `IconAlert` when available), and Token Details switches from inline warning badges to a new `SecurityBanner` for Warning/Spam/Malicious (Verified remains an inline icon). > > Redesigns `SecurityBadgeBottomSheet`: supports passing `features`, shows up to 5 feature tags for Warning/Spam/Malicious, shows a malicious-specific banner/wording, and changes the primary action label to `Continue anyway` with malicious styling. Updates/enriches related tests and English strings accordingly. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 0661445. 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** Update @metamask/transaction-pay-controller, to add change to accountOverride property. ## **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** Ref: https://consensyssoftware.atlassian.net/browse/CONF-1187 ## **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** NA ## **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] > **Medium Risk** > Dependency bumps pull in newer `@metamask/*` controller and keyring packages, which can subtly change transaction/payment and bridge behavior at runtime. App code changes are minimal, but lockfile/resolution shifts increase integration/regression risk. > > **Overview** > Upgrades `@metamask/transaction-pay-controller` to `^19.3.0` and updates the lockfile/resolutions to align on newer `@metamask/*` packages (notably `@metamask/keyring-api` `23.0.1`, plus related bridge/assets/keyring client/internal deps). > > Updates `accountsControllerTestUtils.ts` to recognize Stellar (`XlmAccountType.Account` -> `XlmScope.Pubnet`) when generating mock account scopes. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit e677792. 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 the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: remove the nonce line from tx activity popin when nonce is missing. ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/NEB-966?atlOrigin=eyJpIjoiZTNjN2MyZGZiYmNhNDNjYTllNWUxNGFmNmE1YmMwYmMiLCJwIjoiaiJ9 ## **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] ``` 1. You can perform any tx from Mobile on Tempo (as long as you don't use a Hardware Wallet) to generate an activity in the Activity tab. 2. Click on the successful tx on Activity tab 3. Observe absence of any nonce line (vs. empty "nonce" field before). ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <img width="300" alt="image" src="https://github.com/user-attachments/assets/b8c61089-8844-415b-ba96-db7c65594024" /> <!-- [screenshots/recordings] --> ### **After** <img width="300" alt="image" src="https://github.com/user-attachments/assets/f34b9e8a-4f29-42d3-a7d0-e62d3d226563" /> <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### 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 UI-only conditional rendering change with a small accompanying test update; no changes to transaction processing or network logic. > > **Overview** > The transaction details modal now **omits the “Nonce” section** entirely when `txParams.nonce` is not provided, instead of rendering an empty row. > > Tests were updated to cover both cases (nonce present vs. missing) to ensure the UI consistently hides/shows the nonce row as expected. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit e4e8b70. 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.73.2. *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.73.2
## Version Bump After Release This PR bumps the main branch version from 7.75.0 to 7.76.0 after cutting the release branch. ### Why this is needed: - **Nightly builds**: Each nightly build needs to be one minor version ahead of the current release candidate - **Version conflicts**: Prevents conflicts between nightlies and release candidates - **Platform alignment**: Maintains version alignment between MetaMask mobile and extension - **Update systems**: Ensures nightlies are accepted by app stores and browser update systems ### What changed: - Version bumped from `7.75.0` to `7.76.0` - Platform: `mobile` - Files updated by `set-semvar-version.sh` script ### Next steps: This PR should be **manually reviewed and merged by the release manager** to maintain proper version flow. ### Related: - Release version: 7.75.0 - Release branch: release/7.75.0 - Platform: mobile - Test mode: false --- *This PR was automatically created by the `create-platform-release-pr.sh` script.* Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
…29316) <!-- 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** Token quantities in the Trader Profile position rows (216,649,924.26742363 ASTEROID) were rendered with full precision, making list rows noisy and hard to watch. Updated `formatTokenAmount` method to abbreviate values ≥ 1,000 using K/M/B/T suffixes (reusing the existing pattern in the app) and cap smaller values at 4 decimal places with a < 0.00001 floor, aligning with the market-data display convention already used in `AssetOverview`. <img height="850" alt="Simulator Screenshot - iPhone 17 Pro - 2026-04-24 at 11 55 22" src="https://github.com/user-attachments/assets/37f6c816-967d-4d84-b967-5e398963e6f8" /> ## **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 formatting change limited to how token quantities are displayed in social leaderboard position rows, with broad unit tests added to catch edge cases. > > **Overview** > Updates `formatTokenAmount` used by Social Leaderboard position rows to **abbreviate values >= 1,000** with `K/M/B/T` suffixes (via `localizeLargeNumber`), while **handling dust/precision** for smaller values via `formatAmountWithThreshold` and returning `0` for non-finite inputs. > > Adjusts the `PositionRow` test expectation for large balances and adds a dedicated `formatters.test.ts` suite covering USD, token amount, percent, and trade date formatting (including negative, null/undefined, dust threshold, and seconds-vs-ms timestamps). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 7ca4802. 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 the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** This PR is **split 4** of the QR hardware context merger with the hardware wallet context. It adds a `useQRSigningState` hook and `QRSigningContext` to manage pending scan requests from Redux, track request completion, and provide cancellation via the QR keyring scanner. The `useDeviceConnectionFlow` hook is extended to skip device discovery for QR wallets and resolve readiness directly so the caller can transition straight to awaiting-confirmation. Finally, `AwaitingConfirmationContent` is expanded to render wallet-type-specific content (Ledger vs QR), including QR scanning instructions, animated connection tips, and a reject button wired to the signing rejection callback. <!-- 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: Merges QR Signing Context with Hardware Wallet Context ## **Related issues** Related: https://consensyssoftware.atlassian.net/browse/MUL-1741?atlOrigin=eyJpIjoiMDdkOGRkYmYwMTdlNDRhMWEwMjNjMzM2ZGZmZDg5NDIiLCJwIjoiaiJ9 ## **Manual testing steps** ```gherkin Feature: QR hardware wallet context and Hardware wallet context merger. Scenario: User signs a transaction with a Ledger hardware wallet (regression) Given the user has a Ledger hardware wallet account imported And the user is on the transaction confirmation screen When the user initiates the transaction Then the awaiting-confirmation bottom sheet appears with Ledger-specific content And the existing Bluetooth connection and device discovery flow runs as before And the transaction is signed successfully Scenario: User signs a message with a Ledger hardware wallet (regression) Given the user has a Ledger hardware wallet account imported And a dApp requests a message signature When the user approves the signature request Then the awaiting-confirmation bottom sheet appears with Ledger-specific content And the message is signed successfully Scenario: User signs a transaction with a QR hardware wallet Given the user has a QR hardware wallet account imported And the user is on the transaction confirmation screen When the user initiates the transaction Then the device connection flow skips Bluetooth scanning and device discovery And the awaiting-confirmation bottom sheet appears with QR-specific instructions And QR connection tips are displayed (camera ready, align QR code, good lighting) And the user can scan the QR code to sign the transaction Scenario: User signs a message with a QR hardware wallet Given the user has a QR hardware wallet account imported And a dApp requests a message signature When the user approves the signature request Then the awaiting-confirmation bottom sheet appears with QR-specific instructions And the user can scan the QR code to sign the message Scenario: User rejects a QR signing request Given the user has a QR hardware wallet account imported And the awaiting-confirmation bottom sheet is showing for a signing request When the user taps the reject button Then the pending QR scan request is cancelled And the transaction or message is rejected Scenario: QR wallet connection flow resolves without intermediate connected modal Given the user has a QR hardware wallet account imported When the provider calls ensureDeviceReady for the QR wallet Then the flow does not show an intermediate connected/success modal And the readiness promise resolves directly And the UI transitions straight to awaiting-confirmation ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### 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] > **Medium Risk** > Touches core hardware-wallet connection/readiness flow and adds QR-specific signing UX, which could regress non-QR device connection states or error/retry behavior if edge cases are missed. > > **Overview** > Adds QR hardware-wallet signing support end-to-end by introducing `QRSigningContext`/`useQRSigningState` (Redux-backed) and wrapping `HardwareWalletProvider` children + bottom sheet with this context. > > Updates the connection flow to support QR wallets: derives an **effective** wallet type from a pending-operation address, prefers a `pendingOperationWalletTypeRef` before React renders catch up, skips device discovery when `requiresDeviceDiscovery` is false, and for `HardwareWalletType.Qr` resolves readiness directly (avoiding the intermediate "Ready/success" modal). > > Expands `AwaitingConfirmationContent` with a QR-specific UI (animated QR, scanner modal, cancel/reject wiring, mismatched-request-id handling with analytics) while keeping the existing Ledger/Lattice spinner view. Tests are significantly extended/updated to cover pending wallet-type derivation, QR scan success/error paths, and updated retry/close semantics after signing errors. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 9bf7d8c. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Shows a toast on the rewards home page or the campaign overview page if you're a potential winner with a verification code, or if you're a participant and we know that you're not a winner. ## **Changelog** CHANGELOG entry: null ## **Screenshots/Recordings** Showing toast for participant who didn't win once we know in the same tier for sure that there are 5 winners: <img width="326" height="123" alt="image" src="https://github.com/user-attachments/assets/e3de243f-a123-495c-aedd-4035b9a608fe" /> <img width="304" height="558" alt="image" src="https://github.com/user-attachments/assets/7925af0e-48b3-407c-a2a6-d0db12884952" /> Showing a toast for winners with verification code but still in pending state. <img width="304" height="558" alt="image" src="https://github.com/user-attachments/assets/97e5c31e-3fc5-471e-afc9-0f6cedc6ce55" /> <img width="304" height="558" alt="image" src="https://github.com/user-attachments/assets/e5b8cede-367e-4439-b350-8e57117a1657" /> - Dimissing the toast will cause it to not show up anymore in same session or cross session. - For non winners, it takes users to ondo details page; - For winners with verification code but pending, it takes them to winner sheet. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adds a new focus-driven toast + navigation side effect on key Rewards screens and persists new dismissal state in Redux, which could impact user-facing UX and state rehydration if mis-keyed or triggered unexpectedly. > > **Overview** > Adds `useOndoOutcomeToast`, which detects the most recently completed ONDO Holding campaign, derives an outcome variant from participant outcome data, and shows a persistent icon toast (with haptics) that deep-links to the winning or campaign details view. > > Introduces Redux support for remembering dismissed outcome toasts via `dismissedCampaignOutcomeToasts` (new selector + `dismissCampaignOutcomeToast` action) and persists/rehydrates this map. > > Wires the hook into `RewardsDashboard` and `CampaignsView`, updates fixtures/locales, and adds/extends unit tests covering toast behavior, dismissal, and integration. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 0aa3329. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…ons tests (#29329) <!-- 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 Jest snapshot coverage for several notification detail components and deletes the associated `.snap` files. > > Updates `NotificationBadge`, `NetworkFeeField`, and `Header` tests to assert specific rendered output instead of `toMatchSnapshot()` (e.g., presence of key `testID`s and title/description text, and explicitly expecting `null` renders where applicable). ## **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** > Test-only changes that remove snapshot reliance; low product risk but may reduce coverage of UI regressions previously caught by snapshots. > > **Overview** > Removes Jest snapshot files for several notification components and updates their tests to stop using `toMatchSnapshot()`. > > Tests now assert specific rendered output instead (e.g., presence of key `testID`s/text) and explicitly check `null` rendering for `NetworkFeeField` where applicable. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit dbddff4. 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** Fix broken Test Plan JSON link by uploading as GitHub Actions artifact instead of gh-pages (which is blocked by branch protection). Changes - Replace gh-pages upload with actions/upload-artifact@v4 (unzipped) - Update PR comment to link to build workflow for artifact access <!-- 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/MCRM-69 ## **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.
…ing to WHITELISTED_ACTIONS (#29264) <!-- 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? --> Adds six missing actions to `WHITELISTED_ACTIONS` in `handleUniversalLink.ts` so that deeplinks to these features bypass the interstitial modal, consistent with how similar actions (e.g. `PERPS`, `BUY`, `CARD_ONBOARDING`) are already handled. **Actions added (in `SUPPORTED_ACTIONS` order):** - `SWAP` — inserted after `DAPP`, before `WC` - `REWARDS` — inserted after `PERPS_ASSET`, before `BUY` - `PREDICT` — inserted after `REWARDS`, before `BUY` - `TRENDING` — inserted after `SELL_CRYPTO` - `SHIELD` — inserted after `TRENDING` - `EARN_MUSD` — inserted after `SHIELD` ## **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] > **Medium Risk** > Changes deep link safety/interstitial behavior by allowing additional actions (including `swap`) to bypass the “Proceed with caution” modal, which could affect user protection flows if mis-scoped. Logic is simple but touches a security-adjacent gate used for all universal links. > > **Overview** > Updates `handleUniversalLink` to expand `WHITELISTED_ACTIONS` so deeplinks for **Swap, Rewards, Predict, Trending, Shield, and Earn MUSD** skip the interstitial modal (while still tracking analytics as a non-interstitial flow). > > Adjusts tests accordingly: unit tests now use `send` as the representative non-whitelisted action for modal/signature scenarios, and the swap deeplink smoke test no longer expects/dismisses the “Proceed with caution” modal. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 8112ffc. 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: Baptiste Marchand <baptiste-marchand@users.noreply.github.com>
## **Description**
Implements the Money Account homepage "card linking" state — displayed
when a user has deposited funds and has an unlinked MetaMask Card. This
state encourages card linking with benefits messaging.
**Subtasks implemented:**
- **MUSD-610**: Updated the "Step 2 of 2" `MoneyOnboardingCard` with a
`variant` prop (`'get-card'` | `'link-card'`). The link-card variant
shows "Link your MetaMask Card" title, cashback description, benefits
bullets (checkmark icons with cashback and APY text), and a "Link card"
CTA button.
- **MUSD-611**: Added a `mode` prop (`'upsell'` | `'link'`) to
`MoneyMetaMaskCard`. Link mode replaces the virtual/metal card rows with
a card-linking layout: metal card thumbnail, benefits bullets, and a
full-width "Link card" button.
- **MUSD-612**: Wired the card-unlinked state in `MoneyHomeView` using
the `selectIsCardholder` Redux selector. When `isMilestone &&
isCardholder`, both `MoneyOnboardingCard` and `MoneyMetaMaskCard` switch
to their link-card variants. Verified all 6 reused sections (balance,
action pills, earnings, activity, condensed cards, potential earnings)
render correctly in the new state.
**Card linking CTA handlers** are currently stubbed with
`displayUnderConstructionAlert` — they will be wired to the card linking
flow when MUSD-489 lands.
## **Changelog**
CHANGELOG entry: null
## **Related issues**
Fixes: MUSD-602
## **Manual testing steps**
```gherkin
Feature: Money Account card linking homepage state
Scenario: user sees card linking prompt when they have an unlinked card
Given user has a Money Account with balance > $0.00
And user has ordered/received a MetaMask Card (isCardholder = true)
And card is NOT linked to Money Account
When user navigates to Money home screen
Then the "Step 2 of 2" card shows "Link your MetaMask Card" title
And benefits bullets show "Get 1-3% cashback" and "Earn 4% APY on your balance"
And CTA button reads "Link card"
And MetaMask Card section shows card linking layout instead of virtual/metal card rows
And all other sections (balance, earnings, activity, condensed cards) display correctly
Scenario: user without a card sees standard milestone state
Given user has a Money Account with balance > $0.00
And user does NOT have a MetaMask Card (isCardholder = false)
When user navigates to Money home screen
Then the "Step 2 of 2" card shows "Get your MetaMask Card" title
And MetaMask Card section shows virtual/metal card rows with "Get now" buttons
```
## **Screenshots/Recordings**
<img width="1206" height="2622" alt="image"
src="https://github.com/user-attachments/assets/66162bfd-36db-4c4a-b2c1-0bc12884ad4d"
/>
<img width="1206" height="2622" alt="image"
src="https://github.com/user-attachments/assets/79b1b757-571e-4ae6-bda7-b49243cae31e"
/>
## **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**
- [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/state changes: new rendering variants and CTA routing
based on `selectIsCardholder`, with handlers still stubbed to
under-construction alerts.
>
> **Overview**
> Adds a new **“card-unlinked”** homepage state on `MoneyHomeView` when
the user is in a milestone/filled state and `selectIsCardholder` is
true, switching the onboarding CTA to a **link-card** flow.
>
> Extends `MoneyOnboardingCard` with a `variant` to swap step-2 copy/CTA
for card linking, and extends `MoneyMetaMaskCard` with a `mode="link"`
layout (benefit bullets + “Link card” button, plus APY display) instead
of the virtual/metal upsell rows.
>
> Updates English i18n strings and expands unit tests to cover the new
variants/mode and CTA press behavior across
empty/milestone/card-unlinked states.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
0a8d8ea. 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** Combine the `preinstalled-snaps` and `external-snaps` build flags into one `snaps` flag. The separation was originally meant to exclude sensitive installation logic used for external Snaps. At this point, this logic is already used in production to support preinstalled Snaps and as such mostly unfinished components were currently excluded. These components won't be visible in production though. External Snaps are still unable to be installed unless the build is configured with build type Flask. ## **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** https://consensyssoftware.atlassian.net/browse/WPC-984 <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Medium risk because it changes build-time feature gating and navigation/engine wiring for Snaps, which could unintentionally include or exclude Snaps middleware and screens in certain build configurations. Runtime behavior is additionally gated by `CAN_INSTALL_THIRD_PARTY_SNAPS`, but misconfiguration could affect Snap approvals or settings availability. > > **Overview** > **Unifies Snaps feature gating** by replacing the separate `preinstalled-snaps`/`external-snaps` code fences with a single `snaps` flag across approvals, UI components, routes, engine wiring, and build tooling (`builds.yml`, `metro.transform.js`, `verify-build-config.js`). > > **Adds an explicit runtime gate for third‑party Snaps UI** via `CAN_INSTALL_THIRD_PARTY_SNAPS` (Flask-only), and uses it to conditionally register the Snaps settings stack and Settings entry, while aligning Snap controller initialization to use the same constant for `disableSnapInstallation`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit c1f921f. 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? --> Implements the updated Figma design for the Bridge/Swaps token warning modal, and consolidates the security UI logic into shared utilities. **What changed:** - **`TokenWarningModal` redesign** — The malicious state uses a stacked `Continue anyway` / `Cancel` button layout with `isDanger` styling. Content is wrapped in a `ScrollView` (from `react-native-gesture-handler`) to handle long feature lists on Android. - **Removed `selectDestTokenWarning` Redux selector** — all consumers (`BridgeView`, `SwapsConfirmButton`, `bridge` slice) now read `token.securityData` directly. Removes a deprecated selector. - **New `tokenSecurityUtils.ts`** — single source of truth for Bridge security UI configuration. `getBridgeTokenSecurityConfig(type)` returns the icon, icon color, severity, and label for each `SecurityDataType`. `getSecurityWarnings(token)` moved here from `tokenUtils.ts` for cohesion. - **`TokenSelectorItem` icon fix** — `getSecurityTag` now delegates to `getBridgeTokenSecurityConfig`, fixing a bug where the Warning and Malicious icons were swapped. - **Token warning banner in zero-state** — the banner in `BridgeView` now renders even before a quote is available, so users see the warning as soon as they select a flagged token. - **i18n for security feature labels** — 39 new keys added to `locales/languages/en.json` under `security_trust.features.positive.*` and `security_trust.features.negative.*`. `POSITIVE_FEATURE_LABELS` and `NEGATIVE_FEATURE_LABELS` in `securityUtils.ts` now call `strings()` instead of using hardcoded English. `NEGATIVE_FEATURE_LABELS` is exported so the modal can look up per-feature titles. ## **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 Bridge/Swaps token warning modal to match new design and fixed swapped warning/malicious icons in the token selector ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/SWAPS-4374 ## **Manual testing steps** ```gherkin Feature: Bridge/Swaps token warning modal Background: Given I am logged into MetaMask Mobile And I am on the Bridge/Swaps screen Scenario: suspicious token shows warning banner before quote Given I open the source token selector When I select a token flagged as "suspicious" Then a warning banner should appear on the Bridge screen And the banner should show the triangular Danger icon in yellow Scenario: suspicious token warning modal can be dismissed Given a suspicious token is selected and the warning banner is visible When I tap the warning banner Then the TokenWarningModal should open And I should see "Got it" When I tap "Got it" Then the modal should close and I remain on the Bridge screen Scenario: suspicious token warning modal shown after hitting Swap Given a suspicious token is selected and the warning banner is visible When I tap the Swap button Then the TokenWarningModal should open And I should see "Proceed" and "Cancel" When I tap "Proceed" Then the modal should close and my Swap should execute Scenario: malicious token shows danger-styled modal Given I open the source token selector When I select a token flagged as "malicious" And I tap the warning banner Then the TokenWarningModal should open in malicious mode And the "Got it" button should appear When I tap "Got it" Then the modal should close Scenario: malicious token shows danger-styled modal shows after hitting Swap Given I open the source token selector When I select a token flagged as "malicious" And I tap the Swap button Then the TokenWarningModal should open in malicious mode And the "Continue anyway" button should appear in red (danger styling) above a "Cancel" button When I tap "Continue anyway" Then the modal should close and my Swap should execute Scenario: long feature list is scrollable in the modal Given the TokenWarningModal is open for a token with many security features When I scroll down within the modal Then the feature list should scroll smoothly on both iOS and Android Scenario: token selector shows correct icon per severity Given I open the token selector When I see a token tagged as suspicious Then the tag should display the Danger icon in Warning (yellow) color When I see a token tagged as malicious Then the tag should display the Error icon in Error (red) color ``` ## **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/c2217d9f-7c83-4074-a137-7ef5dee1fed2 ## **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. <!-- Generated with the help of the pr-description AI skill --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes the Bridge/Swaps token-warning gating path (banner + confirm-button routing) to rely on `destToken.securityData` and new feature lists, which could affect when/why users are blocked or allowed to proceed. Mostly UI/UX and selector refactors, but touches pre-transaction warnings. > > **Overview** > Updates Bridge/Swaps token-warning handling to read `destToken.securityData` directly (removing `selectDestTokenWarning`) and to pass **feature lists** into `TokenWarningModal` instead of a single backend description. > > Redesigns `TokenWarningModal` to match new Figma (scrollable content, per-feature rows with localized labels, and a *danger-styled* malicious execution flow using stacked `Continue anyway`/`Cancel` buttons). The Bridge warning banner now renders whenever the destination token is flagged (including zero-state before quotes) and uses shared `getBridgeTokenSecurityConfig` for consistent icons/colors. > > Adds `tokenSecurityUtils` as the shared source of truth for Bridge security UI config (icons/severity/labels and warning extraction), fixes the token selector malicious icon, and expands i18n (`security_trust.features.*` plus new modal strings) while updating `securityUtils` to use translated labels. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 78020b2. 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>
Co-authored-by: Cursor <cursoragent@cursor.com>
Restore CI runs for pull requests whose base is `stable` (i.e. the release/X.Y.Z -> stable release PRs). PR #29305 added `branches-ignore: stable` under `pull_request:` here, which makes the `ci` workflow skip every release PR targeting `stable`. The classic branch protection on `stable` still requires the `Check all jobs pass` and `All jobs pass` status checks (both produced by this workflow), so those PRs end up `BLOCKED` in `mergeStateStatus` with no way for non-admin release managers to merge — they neither get the checks nor have bypass rights. Concretely this broke release/7.76.0 (PR #29584): no `ci` runs at all, and the merge button stays disabled. Older release PRs (29443, 29290, 29674, ...) had their release branches cut from `main` before #29305 landed, so they did not carry the `branches-ignore` line and CI ran normally. Removing only the `branches-ignore` block restores the previous trigger surface. Future release branches cut from `main` will inherit the fix; release/7.76.0 itself still needs the same removal applied directly to that branch to unblock the current merge. Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description** Re-enables the `ci` workflow on pull requests whose base is `stable` (the release `release/X.Y.Z -> stable` PRs). PR [MetaMask#29305](https://github.com/MetaMask/metamask-mobile/pull/29305/changes#diff-b803fcb7f17ed9235f1e5cb1fcd2f5d3b2838429d4368ae4c57ce4436577f03f) accidentally added `branches-ignore: stable` in `.github/workflows/ci.yml`, which makes the workflow refuse to run on any PR whose base branch is `stable`. We have branch protection on `stable`, which requires the `Check all jobs pass` and `All jobs pass` status checks. So `Check all jobs pass` / `All jobs pass` never appeared (no `ci` run) on the release PR : MetaMask#29584, so the release PR currently cannot be merged. ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: MetaMask#29584 (release/7.76.0 PR currently blocked by the missing CI checks) Refs: MetaMask#29305 (introduced the regression) ## **Manual testing steps** N/A ## **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. <!-- Generated with the help of the pr-description AI skill --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: only adjusts GitHub Actions trigger filters so CI runs on `stable`-based pull requests again, with no production code changes. > > **Overview** > Re-enables the `ci` GitHub Actions workflow for pull requests targeting `stable` by removing the `pull_request.branches-ignore: stable` filter, allowing required CI checks to run on release PRs again. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 6e0ed20. 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>
## **Description** Re-enables the `ci` workflow on pull requests whose base is `stable` (the release `release/X.Y.Z -> stable` PRs). PR [#29305](https://github.com/MetaMask/metamask-mobile/pull/29305/changes#diff-b803fcb7f17ed9235f1e5cb1fcd2f5d3b2838429d4368ae4c57ce4436577f03f) accidentally added `branches-ignore: stable` in `.github/workflows/ci.yml`, which makes the workflow refuse to run on any PR whose base branch is `stable`. We have branch protection on `stable`, which requires the `Check all jobs pass` and `All jobs pass` status checks. So `Check all jobs pass` / `All jobs pass` never appeared (no `ci` run) on the release PR : #29584, so the release PR currently cannot be merged. ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: #29584 (release/7.76.0 PR currently blocked by the missing CI checks) Refs: #29305 (introduced the regression) ## **Manual testing steps** N/A ## **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. <!-- Generated with the help of the pr-description AI skill --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: only adjusts GitHub Actions trigger filters so CI runs on `stable`-based pull requests again, with no production code changes. > > **Overview** > Re-enables the `ci` GitHub Actions workflow for pull requests targeting `stable` by removing the `pull_request.branches-ignore: stable` filter, allowing required CI checks to run on release PRs again. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 6e0ed20. 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>
## **Description** Re-enables the `ci` workflow on pull requests whose base is `stable` (the release `release/X.Y.Z -> stable` PRs). PR [#29305](https://github.com/MetaMask/metamask-mobile/pull/29305/changes#diff-b803fcb7f17ed9235f1e5cb1fcd2f5d3b2838429d4368ae4c57ce4436577f03f) accidentally added `branches-ignore: stable` in `.github/workflows/ci.yml`, which makes the workflow refuse to run on any PR whose base branch is `stable`. We have branch protection on `stable`, which requires the `Check all jobs pass` and `All jobs pass` status checks. So `Check all jobs pass` / `All jobs pass` never appeared (no `ci` run) on the release PR : #29584, so the release PR currently cannot be merged. ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: #29584 (release/7.76.0 PR currently blocked by the missing CI checks) Refs: #29305 (introduced the regression) ## **Manual testing steps** N/A ## **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. <!-- Generated with the help of the pr-description AI skill --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: only adjusts GitHub Actions trigger filters so CI runs on `stable`-based pull requests again, with no production code changes. > > **Overview** > Re-enables the `ci` GitHub Actions workflow for pull requests targeting `stable` by removing the `pull_request.branches-ignore: stable` filter, allowing required CI checks to run on release PRs again. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 6e0ed20. 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>
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection:
The combination of CI infrastructure changes (which need validation that the pipeline works) and core shared UI component changes (TabBar, BottomSheetFooter, MainActionButton) that are used across virtually all test flows justifies running the full test suite. The TabBar change alone is sufficient reason to run all tags since it's the primary navigation mechanism for every E2E test. Performance Test Selection: |
|
policy-bot: approve |
## **Description** Re-enables the `ci` workflow on pull requests whose base is `stable` (the release `release/X.Y.Z -> stable` PRs). PR [#29305](https://github.com/MetaMask/metamask-mobile/pull/29305/changes#diff-b803fcb7f17ed9235f1e5cb1fcd2f5d3b2838429d4368ae4c57ce4436577f03f) accidentally added `branches-ignore: stable` in `.github/workflows/ci.yml`, which makes the workflow refuse to run on any PR whose base branch is `stable`. We have branch protection on `stable`, which requires the `Check all jobs pass` and `All jobs pass` status checks. So `Check all jobs pass` / `All jobs pass` never appeared (no `ci` run) on the release PR : #29584, so the release PR currently cannot be merged. ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: #29584 (release/7.76.0 PR currently blocked by the missing CI checks) Refs: #29305 (introduced the regression) ## **Manual testing steps** N/A ## **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. <!-- Generated with the help of the pr-description AI skill --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: only adjusts GitHub Actions trigger filters so CI runs on `stable`-based pull requests again, with no production code changes. > > **Overview** > Re-enables the `ci` GitHub Actions workflow for pull requests targeting `stable` by removing the `pull_request.branches-ignore: stable` filter, allowing required CI checks to run on release PRs again. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 6e0ed20. 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>
## **Description** Re-enables the `ci` workflow on pull requests whose base is `stable` (the release `release/X.Y.Z -> stable` PRs). PR [#29305](https://github.com/MetaMask/metamask-mobile/pull/29305/changes#diff-b803fcb7f17ed9235f1e5cb1fcd2f5d3b2838429d4368ae4c57ce4436577f03f) accidentally added `branches-ignore: stable` in `.github/workflows/ci.yml`, which makes the workflow refuse to run on any PR whose base branch is `stable`. We have branch protection on `stable`, which requires the `Check all jobs pass` and `All jobs pass` status checks. So `Check all jobs pass` / `All jobs pass` never appeared (no `ci` run) on the release PR : #29584, so the release PR currently cannot be merged. ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: #29584 (release/7.76.0 PR currently blocked by the missing CI checks) Refs: #29305 (introduced the regression) ## **Manual testing steps** N/A ## **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. <!-- Generated with the help of the pr-description AI skill --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: only adjusts GitHub Actions trigger filters so CI runs on `stable`-based pull requests again, with no production code changes. > > **Overview** > Re-enables the `ci` GitHub Actions workflow for pull requests targeting `stable` by removing the `pull_request.branches-ignore: stable` filter, allowing required CI checks to run on release PRs again. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 6e0ed20. 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>
…p-7.76.0 (#29986) ## **Description** Re-enables the `ci` workflow on pull requests whose base is `stable` (the release `release/X.Y.Z -> stable` PRs). PR [#29305](https://github.com/MetaMask/metamask-mobile/pull/29305/changes#diff-b803fcb7f17ed9235f1e5cb1fcd2f5d3b2838429d4368ae4c57ce4436577f03f) accidentally added `branches-ignore: stable` in `.github/workflows/ci.yml`, which makes the workflow refuse to run on any PR whose base branch is `stable`. We have branch protection on `stable`, which requires the `Check all jobs pass` and `All jobs pass` status checks. So `Check all jobs pass` / `All jobs pass` never appeared (no `ci` run) on the release PR : #29584, so the release PR currently cannot be merged. ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: #29584 (release/7.76.0 PR currently blocked by the missing CI checks) Refs: #29305 (introduced the regression) ## **Manual testing steps** N/A ## **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. <!-- Generated with the help of the pr-description AI skill --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: only adjusts GitHub Actions trigger filters so CI runs on `stable`-based pull requests again, with no production code changes. > > **Overview** > Re-enables the `ci` GitHub Actions workflow for pull requests targeting `stable` by removing the `pull_request.branches-ignore: stable` filter, allowing required CI checks to run on release PRs again. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 6e0ed20. 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>
|
## **Description** Re-enables the `ci` workflow on pull requests whose base is `stable` (the release `release/X.Y.Z -> stable` PRs). PR [#29305](https://github.com/MetaMask/metamask-mobile/pull/29305/changes#diff-b803fcb7f17ed9235f1e5cb1fcd2f5d3b2838429d4368ae4c57ce4436577f03f) accidentally added `branches-ignore: stable` in `.github/workflows/ci.yml`, which makes the workflow refuse to run on any PR whose base branch is `stable`. We have branch protection on `stable`, which requires the `Check all jobs pass` and `All jobs pass` status checks. So `Check all jobs pass` / `All jobs pass` never appeared (no `ci` run) on the release PR : #29584, so the release PR currently cannot be merged. ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: #29584 (release/7.76.0 PR currently blocked by the missing CI checks) Refs: #29305 (introduced the regression) ## **Manual testing steps** N/A ## **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. <!-- Generated with the help of the pr-description AI skill --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: only adjusts GitHub Actions trigger filters so CI runs on `stable`-based pull requests again, with no production code changes. > > **Overview** > Re-enables the `ci` GitHub Actions workflow for pull requests targeting `stable` by removing the `pull_request.branches-ignore: stable` filter, allowing required CI checks to run on release PRs again. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 6e0ed20. 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>
…p-7.76.0 (#30082) - ci: re-enable CI on PRs targeting stable cp-7.76.0 (#29986) ## **Description** Re-enables the `ci` workflow on pull requests whose base is `stable` (the release `release/X.Y.Z -> stable` PRs). PR [#29305](https://github.com/MetaMask/metamask-mobile/pull/29305/changes#diff-b803fcb7f17ed9235f1e5cb1fcd2f5d3b2838429d4368ae4c57ce4436577f03f) accidentally added `branches-ignore: stable` in `.github/workflows/ci.yml`, which makes the workflow refuse to run on any PR whose base branch is `stable`. We have branch protection on `stable`, which requires the `Check all jobs pass` and `All jobs pass` status checks. So `Check all jobs pass` / `All jobs pass` never appeared (no `ci` run) on the release PR : #29584, so the release PR currently cannot be merged. ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: #29584 (release/7.76.0 PR currently blocked by the missing CI checks) Refs: #29305 (introduced the regression) ## **Manual testing steps** N/A ## **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. <!-- Generated with the help of the pr-description AI skill --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: only adjusts GitHub Actions trigger filters so CI runs on `stable`-based pull requests again, with no production code changes. > > **Overview** > Re-enables the `ci` GitHub Actions workflow for pull requests targeting `stable` by removing the `pull_request.branches-ignore: stable` filter, allowing required CI checks to run on release PRs again. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 6e0ed20. 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> [b9f3ee5](b9f3ee5) Co-authored-by: chloeYue <105063779+chloeYue@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com>



🚀 v7.76.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