[pull] main from MetaMask:main#579
Merged
Merged
Conversation
…26994) <!-- 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? --> Delete the `EvmAccountSelectorList` and `EvmAccountSelectorList` components. ## **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/MUL-1484 ## **Manual testing steps** Not applicable ## **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. ## **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** > Mostly deletes unused/deprecated UI components and their tests, with minimal functional change. Main risk is an overlooked navigation or import reference to the removed screens/components causing runtime or test failures. > > **Overview** > **Removes deprecated UI surfaces.** Deletes `EvmAccountSelectorList` (and associated styles, types, tests, and snapshots) and removes its CODEOWNERS entry. > > **Cleans up navigation and tests.** Drops the `TurnOnBackupAndSync` screen from `MainNavigator` and deletes its implementation/tests/snapshots, updating `MainNavigator` snapshots and simplifying `MultichainAccountConnect` test mocks accordingly. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 3d793d9. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description**
Migrates the BuildQuote screen header from the centralized
`Navbar/index.js` factory pattern (`getRampsBuildQuoteNavbarOptions` +
`navigation.setOptions()`) to an inline `<HeaderCompactStandard>`
rendered directly in the component.
**Why**: The codebase has established a clear pattern (40+ screens
including Ramp Settings, Rewards, Perps, Predict, and all Settings
screens) where `HeaderCompactStandard` is rendered inline in the
component with `headerShown: false` in the navigator. The BuildQuote
screen was one of the last Ramps screens still using the old centralized
factory approach. This change aligns it with the modern pattern as part
of TRAM-3321.
**What changed**:
- Added `headerShown: false` for BuildQuote in `routes.tsx`
- Replaced `useEffect` /
`navigation.setOptions(getRampsBuildQuoteNavbarOptions(...))` with
inline `<HeaderCompactStandard>` in `BuildQuote.tsx`
- Extracted `handleSettingsPress` and `handleBackPress` into
`useCallback` hooks
- Deleted `getRampsBuildQuoteNavbarOptions` from `Navbar/index.js` (no
other consumers)
- Updated tests to assert on rendered header content instead of mock
function calls
- Updated snapshots (header now in component tree)
**Net effect**: −41 lines across 6 files. The header renders a title
("Buy {ticker}"), subtitle ("on {networkName}"), back arrow, and
settings gear — matching the Figma design for TRAM-3321.
## **Changelog**
CHANGELOG entry: null
## **Related issues**
Refs:
[TRAM-3321](https://consensyssoftware.atlassian.net/browse/TRAM-3321)
## **Manual testing steps**
```gherkin
Feature: BuildQuote header displays correctly with inline HeaderCompactStandard
Scenario: user navigates to Buy crypto flow
Given user is on the wallet home screen
When user taps "Buy" and reaches the BuildQuote screen
Then the header displays "Buy ETH" as title
And the header displays "on Ethereum Mainnet" as subtitle
And a back arrow button is visible on the left
And a settings gear button is visible on the right
Scenario: user taps back button on BuildQuote
Given user is on the BuildQuote screen
When user taps the back arrow button
Then user is navigated back to the previous screen
Scenario: user taps settings button on BuildQuote
Given user is on the BuildQuote screen
When user taps the settings gear button
Then the Ramps settings sheet opens
Scenario: header shows loading state when token not yet resolved
Given user navigates to BuildQuote before token data loads
When the screen renders
Then the header does not display a title or subtitle
And back and settings buttons are still functional
```
## **Screenshots/Recordings**
### **Before**
<img width="400" height="1000" alt="image"
src="https://github.com/user-attachments/assets/9267fd5a-a54f-42b2-9257-27f6cef8b11b"
/>
### **After**
<img width="400" height="1000" alt="image"
src="https://github.com/user-attachments/assets/076f0ae0-8359-4f23-bd77-993fae94efdb"
/>
## **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]
> **Low Risk**
> Low risk refactor limited to BuildQuote header rendering and
navigation configuration; main risk is UI/regression in back/settings
interactions due to moving logic out of `navigation.setOptions`.
>
> **Overview**
> BuildQuote’s header is migrated from the centralized
`getRampsBuildQuoteNavbarOptions` + `navigation.setOptions()` approach
to an inline `HeaderCompactStandard` rendered directly in
`BuildQuote.tsx`, with back/settings handlers extracted into
`useCallback` and title/subtitle gated on token/network availability.
>
> The Ramp navigator now sets `options={{ headerShown: false }}` for the
BuildQuote route, the unused `getRampsBuildQuoteNavbarOptions` is
removed from `Navbar/index.js`, and BuildQuote tests/snapshots are
updated to assert rendered header elements (including
`build-quote-back-button` / `build-quote-settings-button`) rather than
mocked navbar option calls.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
dd51d28. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description** Adds the "refundTo" param for postQuote transactions, so refunds from Relay will be refunded back to Predict balance. Updates the transaction-pay-controller version, which supports this param. ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: Adds the "refundTo" param for postQuote transactions, so refunds from Relay will be refunded back to Predict balance. ## **Related issues** Fixes: #26990 ## **Manual testing steps** ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adds a new `refundTo` address into post-quote transaction config and bumps `@metamask/transaction-pay-controller`, which can affect where bridge/relay refunds are sent. Scope is small and covered by unit tests, but it touches payment/bridging transaction configuration. > > **Overview** > **Post-quote pay transactions now include a refund destination.** `useTransactionPayPostQuote` computes a Predict proxy address from `txParams.from` and sets `config.refundTo` alongside `config.isPostQuote=true` when initializing the transaction. > > Unit tests were expanded to mock `computeProxyAddress` and assert `refundTo` behavior (including the missing-`from` case). Dependencies were updated by bumping `@metamask/transaction-pay-controller` to `16.3.0` (with corresponding lockfile changes). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 8bab985. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** <!-- 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: add network logo for Tempo mainnet ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/NEB-143?atlOrigin=eyJpIjoiZWU5NTZkOTkxNmZmNDg5YTgzNWVjZDVmYzkyMTNjNmUiLCJwIjoiaiJ9 ## **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] ``` - Add Tempo network manually with: Name: `Tempo` RPC: `https://tempo-mainnet.drpc.org` Currency: `USD` ChainId: `4217` - Observe network logo is displayed correctly. - Tempo has no native token, which the plan is to hide it in an upcoming support. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <img width="200" alt="image" src="https://github.com/user-attachments/assets/2d76413c-ce68-4488-8997-1e3783c3bbd1" /> <img width="200" alt="image" src="https://github.com/user-attachments/assets/b694212e-4d7f-41f7-ba42-0666a674af37" /> (worth noting that the native token will disappear as part as upcoming Tempo support) ## **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] > **Low Risk** > Low risk: adds a new constant and image mapping entry for Tempo Mainnet without changing any network logic or existing mappings. > > **Overview** > Adds support for displaying a logo for **Tempo Mainnet** by introducing a new `NETWORK_CHAIN_ID.TEMPO_MAINNET` (`0x1079`) and wiring it into `CustomNetworkImgMapping` to use the existing `tempo.png` asset. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 674e343. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…#26453) <!-- 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 updates copy for the mUSD conversion flow. All occurrences of `"boost"` have been replaced with `"bonus"`. <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: updated mUSD conversion flow copy to replace boost with bonus ## **Related issues** Fixes: [MUSD-352: Replace "Boost" with "Bonus" Globally](https://consensyssoftware.atlassian.net/browse/MUSD-352) ## **Manual testing steps** ```gherkin Feature: mUSD conversion bonus terminology Scenario: user sees mUSD conversion incentive wording Given user is viewing mUSD conversion entry points in the Earn flow When user views the conversion CTA and quick convert balance card Then the incentive is labeled as a "bonus" (not "boost") ``` ## **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. ## **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 copy-only change, but it renames i18n keys; any missed references would surface as missing localized strings at runtime. > > **Overview** > Replaces **“boost”** wording with **“bonus”** across the mUSD conversion entry points (asset overview CTA and quick convert balance card), including MetaMetrics `cta_text` generation. > > Renames the associated localization keys (e.g., `boost_title/description`, `percentage_boost` → `bonus_title/description`, `percentage_bonus`) across supported languages and updates affected unit/view tests accordingly. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit ff9faa7. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…a feature flag (#27028) ## **Description** When the Permit2 feature flag is enabled, the provider now: 1. **Always uses Permit2 fee authorization** — removes the on-chain allowance readiness gate that previously caused a fallback to Safe fee authorization when the Permit2 allowance wasn't set on-chain yet. 2. **Attaches `allowancesTx`** to the relay order when the proxy wallet lacks the required Permit2 allowances, so the relay can submit the allowance transaction on-chain before processing the order. 3. **Simplifies `previewOrder` FAK logic** — FAK order type is now determined purely from feature flags and Permit2 config, since `placeOrder` guarantees allowances are available. 4. **Gates FAK on actual allowance readiness** — for fee-bearing Buy orders, FAK requires both Permit2 fee auth AND confirmed allowance availability (on-chain or via `allowancesTx`). 5. **Replaces on-chain Permit2 nonce bitmap** with random nonce generation to avoid collisions on back-to-back orders and eliminate an RPC round-trip. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/PRED-720 ## **Manual testing steps** ```gherkin Feature: Permit2 fee authorization and allowancesTx relay Scenario: user places a BUY order with Permit2 enabled and proxy wallet lacking allowances Given Permit2 feature flag is enabled And the proxy wallet does not have Permit2 allowances set on-chain When user places a BUY order with fees Then the order uses Permit2 fee authorization (not Safe fallback) And an allowancesTx is attached to the relay request And the order type is FAK (if fakOrdersEnabled) Scenario: user places a BUY order with Permit2 enabled and proxy wallet already has allowances Given Permit2 feature flag is enabled And the proxy wallet already has Permit2 allowances on-chain When user places a BUY order with fees Then the order uses Permit2 fee authorization And no allowancesTx is attached And the order type is FAK (if fakOrdersEnabled) Scenario: user places a SELL order with Permit2 enabled Given Permit2 feature flag is enabled When user places a SELL order (no fees) Then no fee authorization is generated And an allowancesTx is attached if proxy wallet lacks allowances And the order type is FAK (if fakOrdersEnabled) Scenario: allowancesTx generation fails gracefully Given Permit2 feature flag is enabled And getProxyWalletAllowancesTransaction throws an error When user places a BUY order with fees Then the order still submits (without allowancesTx) And the order type falls back to FOK (not FAK) And the error is logged but does not block order placement ``` ## **Screenshots/Recordings** ### Before https://www.loom.com/share/5bd9ee06414042e7a4ba944c666b1b9a ### After FOK + Permit2: https://www.loom.com/share/1241e70594684c43bf86880ad29b9fdf FAK + Permit2: https://www.loom.com/share/94c01e493c6149ef806f09b32afe5430 ## **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** > Touches order submission/fee-collection logic and relayer request payloads; incorrect gating or allowance handling could cause orders to fail or use the wrong order type (FAK vs FOK). Changes are localized but impact a critical trading path. > > **Overview** > **Permit2 fee collection is now treated as always-available when enabled.** `placeOrder` no longer falls back to Safe fee authorization based on an on-chain Permit2 allowance check, and `previewOrder` now selects `FAK` purely from feature flags/config. > > **Order submission can now include a prerequisite allowances transaction.** When the Permit2 feature flag is on and the proxy wallet lacks allowances, `placeOrder` generates and sends an `allowancesTx` to the relayer (and logs/continues if generation fails); `submitClobOrder` includes this optional field in the request body. Permit2 nonce generation was also switched from on-chain bitmap reads to a random nonce to avoid extra RPC calls/collisions, with tests updated accordingly. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 373d73b. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** This PR is the Predict-only split of the `color-no-hex` batch work, extracted from the original umbrella PR #26651 and the previously combined batch branch. Scope: - Predict files only (`app/components/UI/Predict/**`) - temporary eslint rollout override for `app/components/UI/Predict/**/*.{js,jsx,ts,tsx}` Reference PR: #26651 ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: color-no-hex predict batch Scenario: validate predict lint and tests Given this branch is checked out When running eslint for Predict scope Then there are no lint errors When running jest for Predict scope with snapshot updates Then tests pass ``` ## **Screenshots/Recordings** ### **Before** N/A (test/lint/config updates only) ### **After** N/A (test/lint/config updates 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 - [ ] 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] > **Low Risk** > Primarily test-only refactors plus an ESLint override for `app/components/UI/Predict`; low runtime risk, but it may surface new lint failures if any remaining hex colors exist in that folder. > > **Overview** > Enables `@metamask/design-tokens/color-no-hex` enforcement for `app/components/UI/Predict/**/*` via an ESLint override. > > Refactors Predict unit tests to comply by replacing inline hex strings with a new shared `TEST_HEX_COLORS` fixture and by standardizing theme mocks to reuse `mockTheme` from `app/util/theme` (including updating a few toast/theme color mocks). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 99e9156. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…inea DAI and USDT (#27022) <!-- 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** ### Fix missing block explorer link for mUSD conversions on aggregator routes #### Problem The "Receive mUSD" row in transaction details was missing the block explorer link for Linea USDT and DAI conversions. These tokens use Relay's aggregator routes (approve + deposit batch) instead of optimized single-deposit routes. For same-chain multi-step routes, the Relay strategy skips status polling and sets the musdConversion transaction hash to `'0x0'`, which the UI treated as "no hash available." ### Fix When the musdConversion hash is `'0x0'`, fall back to the relay deposit transaction's on-chain hash (already available in `relatedTransactions`). This is semantically correct since the relay deposit IS the on-chain transaction where mUSD was received for aggregator routes. <!-- 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: fixed missing block explorer link on "Receive mUSD" row for Linea USDT and DAI conversions using aggregator routes. ## **Related issues** Fixes: [MUSD-404: Missing "Received mUSD" link in transaction details for Linea DAI and USDT](https://consensyssoftware.atlassian.net/browse/MUSD-404) ## **Manual testing steps** ```gherkin Feature: mUSD conversion transaction details block explorer link Scenario: user views block explorer link for optimized route mUSD conversion (fixed-spread) Given user completed an mUSD conversion via an optimized relay route (e.g. Mainnet USDC) When user opens the transaction details Then the "Receive mUSD" row displays a block explorer link Scenario: user views block explorer link for aggregator route mUSD conversion Given user completed an mUSD conversion via an aggregator relay route (e.g. Linea DAI) When user opens the transaction details Then the "Receive mUSD" row displays a block explorer link using the relay deposit hash Scenario: user views mUSD conversion with no available hash Given user completed an mUSD conversion where no relay deposit hash is available When user opens the transaction details Then the "Receive mUSD" row renders without a block explorer link ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> <img width="420" height="922" alt="image" src="https://github.com/user-attachments/assets/78f33013-984f-46ef-b648-45287c06adb8" /> ### **After** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/7eaf139a-8207-4c0a-83a8-fec8ba24690c ## **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] > **Low Risk** > Low risk UI-only change that only affects which transaction hash is used to build a block-explorer URL for `musdConversion` summaries. Main risk is choosing an incorrect fallback hash if related transactions are unexpected. > > **Overview** > Fixes the `musdConversion` receive summary line to **use the `relayDeposit` tx hash** when the conversion tx hash is `0x0`, restoring the block-explorer link for same-chain/aggregator routes. > > Updates `TransactionDetailsSummary` to pass `relatedTransactions` into `useBridgeReceiveData`, and extends unit tests to cover the new fallback behavior and the no-relay-deposit case. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 0c4493d. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…tions (#27091) <!-- 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** Replace the mUSD-specific `NetworkFeeRow` with the generic `TransactionFeeRow` on conversion confirmations, and update the transaction fee tooltip copy to clarify that no MetaMask fee applies. <!-- 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: replaced mUSD conversion-specific network fee row with the generic transaction fee row and updated fee tooltip copy ## **Related issues** Fixes: [MUSD-394: Add generic "Transaction Fee" row to conversion confirmations](https://consensyssoftware.atlassian.net/browse/MUSD-394) ## **Manual testing steps** ```gherkin Feature: Generic transaction fee row for mUSD conversions Scenario: user views fee breakdown on mUSD conversion confirmation Given user is on the mUSD conversion confirmation screen When user views the fee details Then the generic transaction fee row is displayed instead of a network-fee-only row ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** mUSD conversions only displayed the "Network Fee" <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ### Custom conversion input <img width="493" height="1014" alt="image" src="https://github.com/user-attachments/assets/10ab06f2-ff3c-4039-85c9-da636fef70fc" /> <img width="493" height="1014" alt="image" src="https://github.com/user-attachments/assets/015e4775-64e6-42c7-b303-4142d12a7132" /> ### "Max" convert bottom sheet <img width="493" height="1014" alt="image" src="https://github.com/user-attachments/assets/e60de70d-94ec-4da8-9cf1-070e18b05f26" /> ## **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] > **Low Risk** > UI-only confirmation changes to fee row rendering and tooltip copy; main risk is mismatched testIDs or fee display expectations in mUSD conversion flows. > > **Overview** > **mUSD conversion confirmations now use the generic `TransactionFeeRow`** instead of the mUSD-specific `NetworkFeeRow`, so conversions show the same combined transaction fee total (network + provider + MetaMask) and tooltip breakdown as other pay flows. > > Removes the `ConfirmationRowComponentIDs.NETWORK_FEE` selector and deletes the associated `musdConversion` network-fee row/skeleton tests; updates English tooltip copy to clarify *no MetaMask fee applies* for mUSD conversions (and fixes `mUSD` casing in the predict-withdraw tooltip). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit dd076d6. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** - Add global mUSD foreground cleanup to reject stale pending conversion approvals when the app resumes. - Wire cleanup into EarnTransactionMonitor so it covers all mUSD entry points (Quick Convert + CTAs). - Removed Quick Convert list loading spinner when transaction is pending approval <!-- 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: hardened mUSD conversion quick convert status tracking. Auto reject pending mUSD approvals when app is foregrounded. ## **Related issues** Fixes: - [MUSD-359: Loading circle going from MM Pay -> Convert page](https://consensyssoftware.atlassian.net/browse/MUSD-359) - [MUSD-345: Improve loading states](https://consensyssoftware.atlassian.net/browse/MUSD-345) - [MUSD-316: Screen stuck because of navigation](https://consensyssoftware.atlassian.net/browse/MUSD-316) - [MUSD-366: Disable Conversion CTAs when there's an in-flight conversion.](https://consensyssoftware.atlassian.net/browse/MUSD-366) ## **Manual testing steps** ```gherkin Feature: mUSD pending approval recovery on app resume Scenario: user resumes app after leaving mUSD conversion pending Given user started an mUSD conversion and left it in pending approval state When user backgrounds the app and returns via deeplink/notification Then stale pending mUSD approvals are automatically rejected And Quick Convert actions (Max/Edit) are not stuck disabled Scenario: user has no stale pending mUSD approval Given user has no pending unapproved mUSD approval When user returns the app to foreground Then no approval is rejected and normal behavior continues ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### Stale pending approvals are cleared when app is brought back to foreground https://github.com/user-attachments/assets/6b1eeb0f-040d-4d94-b62a-8104fe060b60 ### **After** <!-- [screenshots/recordings] --> ### Block user from entering mUSD conversion flow while existing conversion is in flight https://github.com/user-attachments/assets/d81a65d6-7e90-41cf-bc77-40991cc0f89b ## **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** > Touches confirmation navigation and auto-rejects pending approvals on app foreground, which can affect transaction flows if the selectors or app-state transitions behave unexpectedly. Scope is localized to mUSD conversion/Earn paths with good test coverage, so risk is moderate. > > **Overview** > Hardens mUSD conversion flows by separating **unapproved** vs **in-flight** conversion tracking and using that to gate Quick Convert actions without treating unapproved approvals as “pending” conversions. > > Adds `useMusdConversionStaleApprovalCleanup` (mounted via `EarnTransactionMonitor`) to auto-reject stale unapproved mUSD conversion approvals when the app returns from background, and to pop an orphaned confirmations screen if it’s still focused. > > Updates confirmation behavior for `TransactionType.musdConversion` to use a new `useMusdConfirmNavigation` helper (go back when possible under Quick Convert, otherwise navigate to `Routes.WALLET_VIEW`). Also includes a small Earn toast icon size tweak. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 7b091f0. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…ts vertically when text overflow is detected (#27010) <!-- 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** Refactored token-conversion-asset-header to stack assets vertically when text overflow is detected <!-- 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: refactored token-conversion-asset-header to stack assets vertically when text overflow is detected ## **Related issues** Fixes: [MUSD-363: Quick convert bottom sheet asset header should only stack when text overflows](https://consensyssoftware.atlassian.net/browse/MUSD-363) ## **Manual testing steps** ```gherkin Feature: Adaptive token conversion asset header layout Scenario: user views conversion with short fiat amounts Given user sees the Max mUSD conversion bottom sheet confirmation When the input and output fiat amounts fit on one line Then the assets are displayed side-by-side horizontally Scenario: user views conversion with long fiat amounts Given user sees the Max mUSD conversion bottom sheet confirmation When either fiat amount overflows to a second line Then the assets stack vertically with a downward arrow ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** Asset header always had vertical layout <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ### Horizontal layout when text doesn't overflow (default behaviour) https://github.com/user-attachments/assets/bd5f9771-ab83-4509-b61f-afbae8c8a612 ### Vertical layout when text overflows (edge case) https://github.com/user-attachments/assets/93810add-e4f7-4fea-ac46-ed990a89cecc ## **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** > UI layout now depends on runtime text measurement and a new hidden-render measurement pass, which could cause edge-case rendering or skeleton timing regressions on different devices/font scales. > > **Overview** > Updates `TokenConversionAssetHeader` to **default to a horizontal, side-by-side layout** and switch to a **stacked vertical layout** when either fiat amount wraps to multiple lines (detected via `onTextLayout`). > > Introduces a measurement phase that **renders the real content hidden under the skeleton** until both amounts are measured, updates the skeleton to match the resolved layout (including arrow direction), and expands styles/tests to cover horizontal vs stacked behavior and the new `CONTENT_CONTAINER`/measurement flow. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 45ec77d. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
#26674) Banner showing up in settings page if we detect enrolled accounts that aren't on device: <img width="989" height="359" alt="image" src="https://github.com/user-attachments/assets/2f8c6fdf-05fd-48a3-bb6a-1a232e8d9617" /> Sheet when users click on cta: (scrollable list of addresses, sorted on address value) <img width="1414" height="1170" alt="image" src="https://github.com/user-attachments/assets/332f5dc5-61c3-4dc8-9250-6260442a3afc" /> 'Let us know' opens up external browser to `https://support.metamask.io` (contact support) <img width="817" height="1885" alt="image" src="https://github.com/user-attachments/assets/36a968a0-1b21-4bbc-a887-530f66406544" /> The banner on settings page is behind a feature flag with key `rewards-missing-enrolled-accounts`. ## Summary - Adds `GET /subscriptions/accounts` to the rewards data service (new backend endpoint from [va-mmcx-rewards PR #464](consensys-vertical-apps/va-mmcx-rewards#464)) - `RewardsController:getOffDeviceSubscriptionAccounts` computes and caches (5 min) the delta between backend CAIP-10 accounts and device `InternalAccounts`; uses namespace-aware address matching (`eip155` case-insensitive, all other namespaces such as `solana` and `bip122` case-sensitive); cache is invalidated on `accountLinked` - `useLinkedOffDeviceAccounts` hook calls the controller directly with local state; re-fetches on screen focus and on `accountLinked` events - `LinkedOffDeviceAccountsSheet` bottom sheet lists off-device accounts (network icon, shortened address, copy CTA) - Info banner shown at the top of `RewardsSettingsView` when off-device accounts exist, with a CTA that opens the sheet ## Changelog - **Added**: `RewardsController:getOffDeviceSubscriptionAccounts` action — fetches accounts linked to the rewards subscription that are not present on the current device, with a 5-minute cache - **Added**: `useLinkedOffDeviceAccounts` hook — returns off-device accounts, re-fetches on focus and account link events - **Added**: `LinkedOffDeviceAccountsSheet` bottom sheet — FlatList of off-device accounts with network icon, shortened address, and copy CTA - **Added**: Info banner on `RewardsSettingsView` surfacing off-device accounts with a CTA to open the detail sheet <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adds a new rewards API call and cached controller state to compute off-device subscription accounts, which could affect rewards data fetching and persistence if the new endpoint or filtering logic misbehaves (though gated by a feature flag). UI changes are contained to the rewards settings screen and a new bottom sheet. > > **Overview** > **Adds “Missing Enrolled Accounts” surfacing in Rewards Settings.** `RewardsSettingsView` now conditionally shows a banner (when off-device accounts exist) that opens a new `LinkedOffDeviceAccountsSheet` listing those accounts with network/short address display, copy-to-clipboard, and a support link. > > **Introduces the data pipeline to detect off-device accounts.** Adds `useLinkedOffDeviceAccounts` (gated by the new `rewards-missing-enrolled-accounts` feature flag) which fetches via `RewardsController:getOffDeviceSubscriptionAccounts`; the controller adds a persisted 5‑minute cache, filters backend CAIP-10 subscription accounts against on-device multichain accounts (EVM case-insensitive, non-EVM case-sensitive), and invalidates this cache on subscription cache invalidation. > > **Backend integration + flags/tests.** Adds `RewardsDataService:getSubscriptionAccounts` (`GET /subscriptions/accounts` with 401→`AuthorizationFailedError`), wires messenger/types/state snapshots, adds new i18n strings, and adds/updates unit tests covering UI, hook behavior, controller caching/filtering, and the new API method. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 0243306. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> CHANGELOG entry: Added off-device linked accounts detection, caching, and display in Rewards Settings --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…MarketDetails cp-7.69.0 (#27090) ## **Description** The fee exemption logic in `PredictMarketDetails` was hardcoded to check for a `'Middle East'` tag label, while `PredictController` and `PolymarketProvider` already used a feature-flag-driven approach via `feeCollection.waiveList`. This PR aligns the UI layer with the existing pattern: - **`parsePolymarketEvents`**: Switch tag mapping from `t.label` to `t.slug` so parsed market tags match the slug-based `waiveList` entries used by `waiveFees()` - **`selectPredictFeeCollectionFlag`**: New selector that reads the `predictFeeCollection` remote feature flag, falling back to `DEFAULT_FEE_COLLECTION_FLAG` - **`PredictMarketDetails`**: Replace hardcoded `tags?.includes('Middle East')` with `tags?.some(slug => waiveList.includes(slug))` driven by the selector - Added defensive optional chaining on `tags` access for safety ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: [PRED-736](https://consensyssoftware.atlassian.net/browse/PRED-736) ## **Manual testing steps** ```gherkin Feature: Fee exemption display on market details Scenario: user views a market with a tag in the waiveList Given the remote feature flag predictFeeCollection has waiveList containing 'middle-east' And a market has the tag slug 'middle-east' When user navigates to the market details screen Then the fee exemption message is displayed Scenario: user views a market without waived tags Given the remote feature flag predictFeeCollection has waiveList containing 'middle-east' And a market only has tag slugs 'sports' and 'politics' When user navigates to the market details screen Then the fee exemption message is not displayed Scenario: user views a market when waiveList is empty Given the remote feature flag predictFeeCollection has an empty waiveList And a market has any tags When user navigates to the market details screen Then the fee exemption message is not displayed ``` ## **Screenshots/Recordings** ### **Before** N/A — logic change only, no visual diff ### **After** N/A — logic change only, no visual diff ## **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** > Changes Predict market `tags` from human-readable labels to slugs and uses remote `predictFeeCollection.waiveList` to control fee-exemption UI, which could affect any UI/analytics expecting label-form tags. Logic is straightforward and covered by updated/additional selector and view tests. > > **Overview** > Aligns fee-exemption behavior in `PredictMarketDetails` with the fee-collection feature flag by replacing the hardcoded `'Middle East'` tag check with a `waiveList` (slug) match from the new `selectPredictFeeCollectionFlag` selector (defaulting to `DEFAULT_FEE_COLLECTION_FLAG`). > > Updates Polymarket parsing to store market `tags` as tag **slugs** (`t.slug`) instead of labels, and adjusts tests to validate the new slug-based exemption behavior plus selector fallbacks when the remote flag is missing/null/undefined. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit daf0e58. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…erage (#27093) ## **Description** Evaluates the behaviors tested in `offramp.failing.ts` e2e test and confirms they are already covered by existing component tests. Fills two minor coverage gaps with new unit tests, then deletes the e2e test. ### Coverage Analysis | E2E Behavior | Existing Coverage | |---|---| | Navigate to sell flow | N/A (navigation-level) | | SellGetStartedView "Get Started" | Dead event — `OFFRAMP_GET_STARTED_CLICKED` has zero call sites in source | | BuildQuote: Amount to sell, Get Quotes | `BuildQuote.test.tsx` — "Amount to sell input" section | | BuildQuote: Cancel + analytics | `BuildQuote.test.tsx` — verifies `OFFRAMP_CANCELED` | | BuildQuote: Enter amount → Get Quotes | `BuildQuote.test.tsx` — verifies navigation + `OFFRAMP_QUOTES_REQUESTED` | | QuotesView: Quotes visible | `Quotes.test.tsx` — multiple render tests | | QuotesView: Expand quotes | **Gap filled** — added `OFFRAMP_QUOTES_EXPANDED` sell-mode test | | QuotesView: Continue with provider | `Quotes.test.tsx` — `OFFRAMP_PROVIDER_SELECTED` (both browser types) | | QuotesView: Quote errors | **Gap filled** — added `OFFRAMP_QUOTE_ERROR` sell-mode test | ### New Tests Added - `tracks OFFRAMP_QUOTES_EXPANDED when expanding quotes in sell mode` — verifies the sell-mode variant of the quotes expand analytics event - `tracks OFFRAMP_QUOTE_ERROR for sell quotes with errors` — verifies the sell-mode quote error analytics event fires with correct properties A separate component-view test is not needed because the existing `Quotes.test.tsx` already uses `renderScreen()`, which renders the full component within the navigation stack with Redux state — making it functionally equivalent to a component-view test. Similarly, `BuildQuote.test.tsx` uses the same `renderScreen()` pattern. Since both test files already operate at the component-view level, adding a new component-view test would duplicate existing coverage. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MMQA-1521 ## **Manual testing steps** ```gherkin Feature: Offramp sell-mode unit test coverage Scenario: Existing component tests cover offramp e2e behaviors Given the offramp.failing.ts e2e test validates sell flow UI and analytics When existing component tests in Quotes.test.tsx and BuildQuote.test.tsx are reviewed Then all key behaviors are already covered by component-level tests Scenario: OFFRAMP_QUOTES_EXPANDED fires in sell mode Given the user is on the Quotes screen in sell mode When the user taps "Explore more options" Then the OFFRAMP_QUOTES_EXPANDED analytics event fires with correct sell-mode properties Scenario: OFFRAMP_QUOTE_ERROR fires for sell quote errors Given the user is on the Quotes screen in sell mode with errored quotes When quotes are received with errors Then the OFFRAMP_QUOTE_ERROR analytics event fires with correct sell-mode properties ``` ## **Screenshots/Recordings** ### **Before** - `offramp.failing.ts` e2e test existed but was not running (marked as failing) - `OFFRAMP_QUOTES_EXPANDED` only tested in buy mode - `OFFRAMP_QUOTE_ERROR` test existed but mock data had empty errors array, so sell error path was never exercised ### **After** - `offramp.failing.ts` e2e test deleted — all behaviors confirmed covered by component tests - New unit test verifies `OFFRAMP_QUOTES_EXPANDED` fires with correct properties in sell mode - New unit test verifies `OFFRAMP_QUOTE_ERROR` fires with correct properties for sell quote errors ## **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] > **Low Risk** > Low risk because changes are test-only (adds unit assertions for off-ramp analytics and removes an unstable smoke E2E), with no production logic modifications. > > **Overview** > Adds sell-mode unit test coverage in `Quotes.test.tsx` to assert `OFFRAMP_QUOTES_EXPANDED` is emitted when expanding quotes and `OFFRAMP_QUOTE_ERROR` is emitted when sell quotes include provider errors. > > Removes the flaky `tests/smoke/ramps/offramp.failing.ts` E2E test and updates the `Quotes` snapshot output accordingly (gesture handler tag changes). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit eb7d1c0. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…acy components (#27083) ## **Description** Upgraded the MetaMask design system React Native package to the latest compatible release and marked legacy components as deprecated. https://github.com/MetaMask/metamask-design-system/releases Changes in this PR: - Upgraded `@metamask/design-system-react-native` from `^0.8.0` to `^0.10.0` - Updated lockfile resolution to `@metamask/design-system-react-native@0.10.0` and `@metamask/design-system-shared@0.3.0` - Added missing `@deprecated` JSDoc tags to local overlapping wrappers: - `BottomSheetHeader` - `ButtonBase` - `ActionListItem` - `ButtonHero` - `ButtonSemantic` ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: Design system dependency upgrade Scenario: install and lint after upgrade Given the branch with dependency and JSDoc updates is checked out When running yarn install Then dependencies resolve successfully with the updated lockfile When running eslint on modified component files Then lint passes with no errors ``` ## **Screenshots/Recordings** ### **Before** N/A (dependency and JSDoc changes only) ### **After** N/A (dependency and JSDoc changes only) General smoke test to ensure mobile still runs as expected https://github.com/user-attachments/assets/b23b3c36-772c-4da5-8f72-a961271b1d7a ## **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** > Moderate risk due to the design-system dependency bump (and `design-system-shared` transitive update) potentially changing UI behavior or typings at build/runtime. The code changes themselves are limited to JSDoc deprecation annotations. > > **Overview** > **Upgrades the MetaMask React Native design system dependency** by bumping `@metamask/design-system-react-native` from `^0.8.0` to `^0.10.0` (with corresponding `yarn.lock` updates, including `@metamask/design-system-shared` to `^0.3.0`). > > **Deprecates local legacy/overlapping components** by adding `@deprecated` JSDoc guidance (and upstream README links) to `ActionListItem`, `ButtonHero`, `ButtonSemantic`, `BottomSheetHeader`, and `ButtonBase`; `TextField`’s deprecation docs are also updated with a `@since` tag. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit ff051dd. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description**
Fixes the Checkout WebView header so the provider title/name (for
example, `Moonpay (Staging)`) no longer renders on top of the WebView
content.
Per the design, the Checkout screen should only show the close (`X`)
button in the shared header. This change removes the rendered title from
the `BottomSheetHeader` used in
`app/components/UI/Ramp/Views/Checkout/Checkout.tsx`.
## **Changelog**
CHANGELOG entry: Fixed a bug where the Ramp checkout provider title
appeared above the WebView content.
## **Related issues**
## **Manual testing steps**
```gherkin
Feature: Ramp checkout header title removal
Scenario: checkout webview does not show provider title
Given the user starts the Buy flow and reaches the provider Checkout WebView screen
When the Checkout screen is displayed
Then the provider name/title is not shown above the WebView content
And the close button is still visible in the header
And the close button still works correctly
```
## **Screenshots/Recordings**
### **Before**
<img width="388" height="296" alt="Screenshot 2026-03-05 080429"
src="https://github.com/user-attachments/assets/ab97f344-0fcd-4445-9893-070629a5c7a4"
/>
### **After**
<img width="380" height="316" alt="Screenshot 2026-03-04 152121"
src="https://github.com/user-attachments/assets/b0f201f1-d075-451f-b189-2425791962b4"
/>
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] 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]
> **Low Risk**
> UI-only change that removes a duplicated header title; low risk aside
from potential minor navigation header title regressions.
>
> **Overview**
> Removes the rendered provider title from the `Checkout` screen’s
`BottomSheetHeader`, leaving only the close (`X`) button so the WebView
content isn’t obscured.
>
> Simplifies header option setup by dropping the cached `headerTitle`
fallback and updates the Jest snapshots to reflect the title-less shared
header.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
75e00bf. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## Version Bump After Release This PR bumps the main branch version from 7.69.0 to 7.70.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.69.0` to `7.70.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.69.0 - Release branch: release/7.69.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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )