Skip to content

chore: Stable sync release 7.70.0#27468

Merged
chloeYue merged 74 commits intorelease/7.70.0from
stable-sync-release-7.70.0
Mar 14, 2026
Merged

chore: Stable sync release 7.70.0#27468
chloeYue merged 74 commits intorelease/7.70.0from
stable-sync-release-7.70.0

Conversation

@chloeYue
Copy link
Contributor

@chloeYue chloeYue commented Mar 13, 2026

Description

Sync stable branch into release/7.70.0 to include hotfix releases (7.68.1, 7.68.2) that were merged to stable.

Changelog

CHANGELOG entry: null

Related issues

Fixes:

Manual testing steps

Feature: Stable sync

  Scenario: release branch includes latest stable changes
    Given the release/7.70.0 branch exists

    When stable is synced into release/7.70.0
    Then the release branch includes all hotfix changes from stable

Pre-merge author checklist

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Made with Cursor


Note

Low Risk
Documentation-only change updating CHANGELOG.md; no runtime code paths are affected.

Overview
Updates release documentation by adding a new 7.69.0 section to CHANGELOG.md with consolidated Added/Changed/Fixed entries.

Also adds 7.68.1 and 7.68.2 sections and updates the bottom compare links so [Unreleased] now compares from v7.69.0 and includes new version link references.

Written by Cursor Bugbot for commit a0eca7f. This will update automatically on new commits. Configure here.

metamaskbot and others added 30 commits March 5, 2026 22:16
…Market Insights (#27205)

- chore: reposition perps components around Market Insights cp-7.69.0
(#27193)

<!--
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**

Reorders the perps and Market Insights sections on the token details
screen so the layout is stable regardless of position state.
1. When a user has an open perps position, the position card now appears
directly below the balance (above Market Insights), giving active trades
priority.
2. When there is no position, the discovery/promotional banner renders
below Market Insights instead. This means

Market Insights always stays in the same place, meaning no layout shifts
as perps state changes. The discovery banner is demoted to a secondary
position so it never pushes informational content down.

<img height="800" alt="Simulator Screenshot - iPhone 16e - 2026-03-09 at
11 37 57"

src="https://github.com/user-attachments/assets/5cb5a681-8b24-4635-ac03-27b966ccc1d8"
/>
<img height="800" alt="Simulator Screenshot - iPhone 16e - 2026-03-09 at
11 38 26"

src="https://github.com/user-attachments/assets/6536ee13-2beb-4c6e-a8f4-da5e386b76cb"
/>


## **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**

- [ ] 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 UI/layout-only change that reorders Perps components and
adjusts spacing; main risk is visual regression on the token details
screen when Perps position/loading states change.
> 
> **Overview**
> **Token details layout is reordered to be stable regardless of Perps
position state.** When a Perps position exists, the `PerpsPositionCard`
now renders above the Market Insights entry card; when no position
exists, the `PerpsDiscoveryBanner` renders below Market Insights.
> 
> This introduces a shared `showPerpsSection` guard to centralize Perps
render conditions and updates unit tests to mock
`usePerpsPositionForAsset` and assert the new ordering/visibility
behavior. Separately, the Market Insights entry card adds bottom spacing
(`mb-4`) for improved visual separation.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
08cf77e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
[66a77d8](66a77d8)

Co-authored-by: António Regadas <antonio.regadas@consensys.net>
…69.0 (#27191)

- fix: mixpanel event missing property cp-7.69.0 (#27187)

<!--
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**

**Bug fix**

Fixed market_insights_displayed always reporting false in the
`TOKEN_DETAILS_OPENED` event by initializing `isLoading` to true in
`useMarketInsights` when a fetch will occur, preventing a race condition
where the tracking callback fired before loading started and
deduplication blocked the correct value

## **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/TSA-243

## **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**

- [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**

- [x] 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 state-initialization change in a React hook; main risk is a
minor behavior shift where `isLoading` may start `true` when enabled and
an asset id is present.
> 
> **Overview**
> Fixes a race where market insights tracking could run before loading
begins by initializing `useMarketInsights`’s `isLoading` state to `true`
whenever the hook is enabled and a `caip19Id` is provided, ensuring
first-render consumers don’t see a transient “not loading” state before
the initial fetch.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
2033d2c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
[fd5adac](fd5adac)

Co-authored-by: João Santos <joaosantos15@users.noreply.github.com>
…/allowance refresh workaround cp-7.69.0 (#27166)

- revert(predict): remove Polymarket balance/allowance refresh
workaround cp-7.69.0 (#27162)

## **Description**

Reverts #26954.

Polymarket has resolved the underlying CLOB infrastructure issue that
was causing intermittent `not enough balance / allowance` 400 errors
during order placement. The temporary `refreshBalanceAllowance()`
workaround (calling `GET /balance-allowance/update` before each order)
is no longer needed and is removed here.

### Changes:
- **`utils.ts`**: Remove `refreshBalanceAllowance()` utility and related
HMAC auth logic
- **`PolymarketProvider.ts`**: Remove the preflight refresh call from
`placeOrder()`
- **`utils.test.ts`**: Remove associated unit tests
- **`PolymarketProvider.test.ts`**: Remove associated integration tests

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: Polymarket order placement without refresh workaround

  Scenario: user places a BUY order on a prediction market
    Given the user has USDC deposited in their Polymarket proxy wallet

    When user places a BUY order on any market
    Then the order completes successfully without a preflight refresh call

  Scenario: user places a SELL order on a prediction market
    Given the user holds outcome tokens for a market

    When user places a SELL order
    Then the order completes successfully without a preflight refresh call
```

## **Screenshots/Recordings**

N/A — no UI changes

### **Before**

<!-- N/A -->

### **After**

<!-- N/A -->

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes Polymarket order submission behavior by removing a preflight
balance/allowance refresh; if the upstream CLOB issue is not fully
resolved, this could reintroduce intermittent order failures under load.
> 
> **Overview**
> Removes the temporary Polymarket CLOB *balance/allowance refresh*
workaround by deleting `refreshBalanceAllowance` from `utils.ts` and
dropping the pre-submit call in `PolymarketProvider.placeOrder()`.
> 
> Cleans up the associated unit/integration coverage by removing mocks
and test cases that asserted the refresh call ordering and failure
handling.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
db50f7d. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
[8099e72](8099e72)

Co-authored-by: Luis Taniça <matallui@gmail.com>
…licked event cp-7.69.0 (#27125)

- feat: fix button label for action button clicked event cp-7.69.0
(#27117)

## **Description**

The sticky Buy and Sell buttons on the token details page were both
firing ACTION_BUTTON_CLICKED with button_label: "Swap", making it
impossible to distinguish between the two actions in Mixpanel.
Changes:
* Added an optional buttonLabel param to goToSwaps / goToNativeBridge in
useSwapBridgeNavigation, falls back to "Swap" so all existing callers
are unaffected
* `handleBuyPress` now passes `button_label: "Buy"` and
`handleSellPress` passes `button_label: "Sell"`

## **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 event property for ACTION_BUTTON_CLICKED

## **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]
> **Low Risk**
> Low risk: changes only analytics event properties by threading an
optional `buttonLabel` through navigation helpers; swap/bridge
navigation behavior is unchanged due to a default fallback.
> 
> **Overview**
> Fixes token details *Buy*/*Sell* sticky buttons reporting
`ACTION_BUTTON_CLICKED` with `button_label: "Swap"`.
> 
> `useSwapBridgeNavigation` now accepts an optional `buttonLabel` in
`goToNativeBridge`/`goToSwaps` and uses it for `trackActionButtonClick`
(defaulting to the existing Swap label), and `useTokenActions` passes
the correct localized Buy/Sell labels; tests were updated to assert the
new arguments.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
8c1b45d. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
[0e76ada](0e76ada)

Co-authored-by: sahar-fehri <sahar.fehri@consensys.net>
…ss cp-7.69.0 (#27119)

- fix: account for POL non-zero native address cp-7.69.0 (#27052)

## **Description**

Fixes a bug in the bridge token selector where Polygon's native token
(POL) appeared twice in the list — once with balance at the top and once
without balance at the bottom. Selecting the balance entry as a
destination token caused the quote to show 0 and the rate to display
"--".

**Root cause**: Polygon's native token uses address
`0x0000000000000000000000000000000000001010` in wallet state (from
`getNativeTokenAddress`), but the bridge API expects `AddressZero`
(`0x0000...0000`) for all native assets. The bridge-controller's
`isNativeAddress()` does not recognize `0x...1010` as native, so:
1. `tokenToIncludeAsset` sent the wrong asset ID (`erc20:0x...1010`
instead of `slip44:966`) to the API, which couldn't deduplicate it with
its own native POL entry.
2. When the user selected POL with `0x...1010`, quote matching in
`useBridgeQuoteData` failed because the returned quote used
`AddressZero` for `destAsset.address`.

**Fix**: Extracted the existing normalization logic from
`useTokenAddress` into a reusable pure function `normalizeTokenAddress`,
and applied it in `useTokensWithBalance` when building `BridgeToken`
objects from wallet state. This ensures POL enters the bridge flow with
`AddressZero` from the start, fixing both the duplicate listing and the
quote/rate mismatch.

## **Changelog**

CHANGELOG entry: Fixed a bug where Polygon's native token (POL) appeared
twice in the bridge token selector and selecting it showed incorrect
quote data.

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: Bridge token selector - Polygon native token

  Scenario: user selects POL as destination token on Polygon
    Given user has a POL balance on Polygon
    And user opens the bridge token selector for destination

    When user filters by Polygon network
    Then POL appears only once in the token list with balance displayed

  Scenario: user gets a valid quote after selecting POL destination
    Given user has a source token with balance
    And user has selected POL on Polygon as the destination token

    When the quote loads
    Then the destination input shows a non-zero amount
    And the rate displays a valid exchange rate (not "--")
```

## **Screenshots/Recordings**

### **Before**


### **After**


## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **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**
> Medium risk because it changes how token addresses are represented in
the bridge token list and downstream API/quote matching, which could
affect token identification on Polygon. Scope is small and isolated to
bridge token normalization.
> 
> **Overview**
> Fixes Polygon native token (POL) handling in the bridge UI by
normalizing Polygon’s non-zero native token address to the zero address
the bridge API expects.
> 
> Extracts the Polygon-specific normalization from `useTokenAddress`
into a reusable `normalizeTokenAddress` utility and applies it when
constructing tokens in `useTokensWithBalance`, preventing duplicate POL
entries and quote mismatches caused by inconsistent native-address
representations.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b0deef0. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
[ec4fbf2](ec4fbf2)

Co-authored-by: Bryan Fullam <bryan.fullam@consensys.net>
…lect annualized bonus and claim timeline (#27210)

- feat: Updating mUSD conversion copy to reflect annualized bonus and
claim timeline (#27097)

<!--
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 mUSD conversion copy to reflect annualized bonus and
claim timeline.
<!--
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 copy to reflect annualized
bonus and claim timeline

## **Related issues**

Fixes:
- [MUSD-392: Annual bonus
copy](https://consensyssoftware.atlassian.net/browse/MUSD-392)
- [MUSD-393: Communicate the timeframe of the
bonus](https://consensyssoftware.atlassian.net/browse/MUSD-393)

## **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] -->
### Education screen
<img width="489" height="1022" alt="image"

src="https://github.com/user-attachments/assets/e4435213-193b-4fc8-9212-4c797a5a3fc1"
/>

### Custom convert navbar tooltip
<img width="489" height="1022" alt="image"

src="https://github.com/user-attachments/assets/b26a4251-4c2e-4aa0-b044-279894e609ce"
/>

### Claimable bonus tooltip

Custom convert
<img width="489" height="1022" alt="image"

src="https://github.com/user-attachments/assets/8e706082-165b-455e-835b-f17c555fd313"
/>

Quick conver
<img width="489" height="1022" alt="image"

src="https://github.com/user-attachments/assets/842dfe5f-fb8c-40dd-ba71-6609b2fbfb2f"
/>

### Asset details CTA
<img width="489" height="1022" alt="image"

src="https://github.com/user-attachments/assets/10d66946-64e2-4bb4-8d9a-915f64cef29a"
/>

## **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: primarily copy/translation key updates plus minor UI
tooltip/toast rendering changes (adds a terms link and an extra
success-toast description) with no changes to conversion logic or data
handling.
> 
> **Overview**
> Updates mUSD conversion user-facing messaging to consistently describe
the incentive as an *annualized bonus* and to communicate that the bonus
becomes claimable within about a day.
> 
> This refreshes strings across the education screen, quick convert
header, asset overview CTA, claimable bonus tooltip, and conversion
success toast (now includes a secondary description line), and adjusts
the confirmation `PercentageRow` tooltip to include a tappable “Terms
apply” link to the bonus terms URL. Tests are updated to match the new
copy and label formatting.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
388fcc0. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
[f9325e3](f9325e3)

Co-authored-by: Matthew Grainger <46547583+Matt561@users.noreply.github.com>
…ture-flag-driven in PredictMarketDetails cp-7.69.0 (#27100)

- fix(predict): make fee exemption logic feature-flag-driven in
PredictMarketDetails 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 -->
[098426e](098426e)

Co-authored-by: Luis Taniça <matallui@gmail.com>
Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
…e token regardless of selected network in deeplink flow (#27216)

- fix: cp-7.69.0 default to first convertible token regardless of
selected network in deeplink flow (#27202)

<!--
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**

When a user opens the mUSD conversion education screen via deeplink, the
component calls getPaymentTokenForSelectedNetwork() to determine which
token to convert. If the user hasn't selected a specific network (e.g.,
using the "Popular networks" filter), this function can return null —
causing the flow to skip conversion entirely and fall through to the buy
or navigate-home paths, even though the user has convertible tokens.

This fix adds a fallback: when getPaymentTokenForSelectedNetwork()
returns null but conversionTokens is non-empty (guarded by the
hasConvertibleTokens check), the component defaults to the first
available conversion token. This ensures deeplink users are always
routed to the conversion flow when they have eligible tokens.

<!--
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: n/a

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MUSD-496

## **Manual testing steps**

```gherkin
Feature: mUSD Deeplink Conversion Fallback

  Background:
    Given the user has convertible stablecoin tokens in their wallet
    And the user goes through deeplink flow  `xcrun simctl openurl booted "metamask://earn-musd"`

  Scenario: Deeplink converts using first available token when no network-specific token exists
    Given the user has not selected a specific network filter
    And getPaymentTokenForSelectedNetwork returns null
    When the user opens the mUSD conversion deeplink
    And the education screen is displayed
    And the user presses the primary "Get Started" button
    Then the conversion flow initiates with the first convertible token
    And the education screen is marked as seen

  Scenario: Deeplink converts using network-specific token when available
    Given the user has selected a specific network
    And getPaymentTokenForSelectedNetwork returns a valid token
    When the user opens the mUSD conversion deeplink
    And the education screen is displayed
    And the user presses the primary "Get Started" button
    Then the conversion flow initiates with the network-specific token
    And the education screen is marked as seen
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**



https://consensys.slack.com/files/U06EZC2Q81X/F0AKSVBC51P/screenrecording_03-09-2026_10-22-25_1.mp4

<!-- [screenshots/recordings] -->

### **After**



https://github.com/user-attachments/assets/4adb4590-20e1-4555-b652-201edff1d8c1

<!-- [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]
> **Medium Risk**
> Changes deeplink routing to auto-select a fallback conversion token
and alters conversion-token ordering, which can affect which asset is
preselected/converted for users in edge cases. Scope is limited to mUSD
conversion entry flow and covered by added tests, but impacts
user-facing navigation/selection logic.
> 
> **Overview**
> **mUSD deeplink conversion now falls back to a wallet token instead of
skipping conversion.** When `getPaymentTokenForSelectedNetwork()`
returns `null`, the education deeplink flow uses the first
`conversionTokens` entry (validated/normalized via
`safeFormatChainIdToHex` + `toChecksumAddress`) to proceed with
`convert` rather than falling through to *buy* or *home*.
> 
> **Conversion token ordering is updated.** `useMusdConversionTokens`
now sorts eligible conversion tokens by descending fiat balance so the
fallback token is deterministically the highest-value option.
> 
> **Tests updated/added** to cover the fallback conversion behavior and
the buy/home fall-through when the fallback token is invalid (e.g.,
missing `chainId`), plus token sorting by fiat balance.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
5a5c5da. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
[da3d5ff](da3d5ff)

Co-authored-by: Nicholas Smith <nick.smith@consensys.net>
… row to conversion confirmations (#27225)

- feat: MUSD-394 add generic transaction fee row to conversion
confirmations (#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 -->
[903489d](903489d)

Co-authored-by: Matthew Grainger <46547583+Matt561@users.noreply.github.com>
…in price details breakdown cp-7.69.0 (#27229)

- feat(predict): show FAK partial fill note in price details breakdown
cp-7.69.0 (#27218)

## **Description**

When FAK (Fill-And-Kill) orders are enabled, the
PredictFeeBreakdownSheet now displays a footnote below the Total row
explaining that prices assume a fully filled order and actual amounts
may vary if the order is only partially filled.

Additionally, the component was refactored to use
`@metamask/design-system-react-native` primitives (`Text`, `TextColor`,
`TextVariant`, `FontWeight`) instead of the local `component-library`
Text, aligning with the project's UI development guidelines.

**Changes:**
- Created `selectPredictFakOrdersEnabledFlag` Redux selector for the
`predictFakOrders` version-gated remote feature flag
- Added `fakOrdersEnabled` prop to `PredictFeeBreakdownSheet` —
conditionally renders a partial fill note
- Wired `PredictBuyPreview` to read the selector and pass it to the
sheet
- Migrated `Text`, `TextColor`, `TextVariant` imports from
`component-library` to `@metamask/design-system-react-native`
- Replaced `TextVariant.BodyMDBold` with `TextVariant.BodyMd` +
`fontWeight={FontWeight.Bold}`

## **Changelog**

CHANGELOG entry: Added a note in prediction price details explaining
that prices assume a fully filled order when FAK orders are enabled

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/PRED-722

## **Manual testing steps**

```gherkin
Feature: FAK partial fill note in price details

  Scenario: user sees partial fill note when FAK orders flag is enabled
    Given the predictFakOrders remote feature flag is enabled
    And the user is on the buy prediction preview screen

    When user taps on the price details row to open the fee breakdown sheet
    Then a note is displayed below the Total row reading "Prices shown assume your order is fully filled. Actual amounts may vary if the order is only partially filled."

  Scenario: user does not see partial fill note when FAK flag is disabled
    Given the predictFakOrders remote feature flag is disabled
    And the user is on the buy prediction preview screen

    When user taps on the price details row to open the fee breakdown sheet
    Then no partial fill note is displayed below the Total row
```

## **Screenshots/Recordings**

### **Before**

<!-- Price details sheet shows Total as the last row -->

<img width="420" height="865" alt="Screenshot 2026-03-09 at 1 19 11 PM"

src="https://github.com/user-attachments/assets/a0c1110c-1840-401f-8807-bebe018253cd"
/>

### **After**

<!-- Price details sheet shows a footnote below Total when FAK is
enabled -->
<img width="421" height="854" alt="Screenshot 2026-03-09 at 1 20 36 PM"

src="https://github.com/user-attachments/assets/056237e0-37ea-4b8e-8501-5b82befafd27"
/>



## **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/feature-flag change that adds conditional copy and a new
selector; main risk is incorrect flag evaluation or unintended note
display.
> 
> **Overview**
> **Predict price details now conditionally shows a FAK partial-fill
disclaimer** when the remote `predictFakOrders` version-gated flag is
enabled.
> 
> This introduces `selectPredictFakOrdersEnabledFlag`, wires it into
`PredictBuyPreview` to pass `fakOrdersEnabled` to
`PredictFeeBreakdownSheet`, and updates the sheet to render the new
footnote (plus a small refactor to
`@metamask/design-system-react-native` `Text` primitives via a reusable
`FeeRow`). Tests and `en.json` strings are updated accordingly.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
9bf73d0. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
[7e988fc](7e988fc)

Co-authored-by: Luis Taniça <matallui@gmail.com>
…p-7.69.0 (#27234)

- fix(predict): fix fee amount calculation cp-7.69.0 (#27232)

## **Description**

Fix the Predict fee calculation to match the backend order relay
calculation. Previously, individual fee components (`metamaskFee`,
`providerFee`) were rounded to 3 decimal places before summing, and
`previewOrder` was passing `size` instead of `makerAmount` as the fee
basis. This caused rounding discrepancies that led to order failures on
certain amounts (e.g., $6.12 yielding a $0.244 fee instead of $0.2448).

**Changes:**
- Remove per-component rounding of `metamaskFee` and `providerFee` —
keep full precision
- Round only `totalFee` to 6 decimal places (matching backend precision)
- Use `makerAmount` instead of `size` as the `userBetAmount` in
`previewOrder`, aligning with the backend order relay

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/PRED-740

## **Manual testing steps**

```gherkin
Feature: Predict fee calculation accuracy

  Scenario: user places a bet with an amount that previously caused rounding errors
    Given the user is on the Predict market detail screen

    When user enters a bet amount of $6.12
    Then the displayed fee should be $0.2448 (not $0.244)
    And the order should succeed without a fee mismatch error
```

## **Screenshots/Recordings**

<!-- Not applicable — logic-only change with no UI modifications -->

### **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
- [ ] 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**
> Updates fee math used for order previews/relaying; incorrect rounding
or amount basis could still cause fee mismatches and failed orders, but
the change is localized to fee computation.
> 
> **Overview**
> Adjusts Predict’s Polymarket fee calculation to **stop rounding
`metamaskFee`/`providerFee` individually** and instead **round only
`totalFee` to 6 decimals**, matching backend precision.
> 
> Updates `previewOrder` (BUY) to compute fees from the rounded
`makerAmount` rather than the raw input `size`, reducing client/backend
fee discrepancies that can cause order submission failures.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
06004e3. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
[dbf2c8f](dbf2c8f)

Co-authored-by: Luis Taniça <matallui@gmail.com>
…ed confirmations with perps header (#27231)

- fix(perps): route deposit flow to redesigned confirmations with perps
header cp-7.69.0 (#27106)

## **Description**

The perps deposit flow was using `navigateToConfirmation({ stack:
Routes.PERPS.ROOT })`, which did not correctly route users to the
redesigned confirmations screen after initiating a deposit. Users could
end up on the wrong confirmation stack or without the perps-specific
header.

This change updates the flow so that when the user taps the Perps
balance token to deposit:
1. The current approval/confirmation is dismissed via `handleReject()`
from `useApprovalRequest`.
2. `depositWithConfirmation()` runs to start the deposit flow.
3. On success, navigation goes to `REDESIGNED_CONFIRMATIONS` with
`showPerpsHeader: true` instead of the previous PERPS.ROOT stack.

Dependencies on `useConfirmNavigation` are removed in favor of
`useNavigation` and `useApprovalRequest` so the deposit action and
post-deposit navigation are explicit and aligned with the redesigned
confirmations screen.

## **Changelog**

CHANGELOG entry: Fixed perps deposit flow so it routes to the redesigned
confirmations screen with the perps header after a successful deposit.

## **Related issues**

Fixes:
https://consensys.slack.com/archives/C092T3GPHQD/p1772719051867319

## **Manual testing steps**

```gherkin
Feature: Perps deposit from pay-with / token list

  Scenario: user initiates perps deposit from token selector
    Given user is on a confirmation screen with "Perps balance" in the token list (e.g. perps deposit and order)
    When user taps "Perps balance" to deposit
    Then the current confirmation is dismissed, deposit flow runs, and on success the user is taken to the redesigned confirmations screen with the perps header visible
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**
<img width="1206" height="2622"
alt="simulator_screenshot_1025DB15-7197-4622-964F-F1F05143DFC8"

src="https://github.com/user-attachments/assets/5e3dde3e-e91b-4966-945e-8a1b910933e0"
/>


<!-- [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]
> **Medium Risk**
> Changes the perps deposit tap-handler to dismiss the current approval
and navigate to a different confirmation route, so regressions could
strand users on the wrong screen or break the deposit flow sequencing.
> 
> **Overview**
> Fixes the **Perps “Add funds”** action from the synthetic “Perps
balance” token so it no longer uses
`useConfirmNavigation`/`Routes.PERPS.ROOT`.
> 
> The handler now calls `useApprovalRequest().onReject()` to dismiss the
current approval, runs `depositWithConfirmation()`, and then navigates
via React Navigation to
`Routes.FULL_SCREEN_CONFIRMATIONS.REDESIGNED_CONFIRMATIONS` with
`showPerpsHeader: true`. Tests were updated to mock the new hooks
(`useNavigation`, `useApprovalRequest`) and assert the new call
order/route using `waitFor`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
48571b0. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
[9975c8c](9975c8c)

---------

Co-authored-by: Michal Szorad <michal.szorad@consensys.net>
Co-authored-by: chloeYue <105063779+chloeYue@users.noreply.github.com>
…on android cp-7.69.0 (#27302)

- fix: swaps network selector not scrolling on android cp-7.69.0
(#27295)

## **Description**

The "Select Network" bottom sheet in the Bridge token selector was not
scrollable on Android.

Tested on both iOS and Android.

## **Changelog**

CHANGELOG entry: Fixed the Bridge "Select Network" bottom sheet not
being scrollable when many networks are available on Android.

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/SWAPS-4252
Fixes: #27290

## **Manual testing steps**

```
Feature: Bridge token selector network filter

  Scenario: user scrolls the network list in the Select Network bottom sheet
    Given the user is on the Bridge screen
    And many networks are available

    When user taps the network filter pill above the token list
    Then the Select Network bottom sheet opens

    When user attempts to scroll the network list
    Then the list scrolls smoothly without dismissing the sheet

    When user taps a network
    Then the sheet closes and the token list is filtered to that network
```

## **Screenshots/Recordings**

### **Before**

<!-- List clipped, vertical pan dismissed the sheet instead of scrolling
-->

### **After**





https://github.com/user-attachments/assets/006154c0-b0a3-482d-8c23-be4cfbb37085





<!-- Full network list scrollable -->

## **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**
> Small UI gesture-handling change limited to the Bridge network
selector; no auth, security, or data-flow logic is modified.
> 
> **Overview**
> Fixes the Bridge token selector "Select Network" bottom sheet not
scrolling on Android by switching the network list container to
`ScrollView` from `react-native-gesture-handler`, which correctly
handles scroll gestures inside the bottom sheet.
> 
> Removes the unused `BridgeNetworkSelectorBase` component that
previously wrapped children in a bottom sheet + `react-native`
`ScrollView`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d3b24db. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
[c22e473](c22e473)

Co-authored-by: infiniteflower <139582705+infiniteflower@users.noreply.github.com>
…139] cp-7.69.0 (#27309)

- fix: try fixing X deeplinks by adding [GE-139] cp-7.69.0 (#27139)

<!--
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?
-->
Fix branch deeplinks not working with the X (Twitter) app by adding a
`$deeplink_path` param in branch.io and consuming it in MetaMask Mobile.

### Context

- Platform: happens only on iOS. Android behaves differently (no
Deepview in our flow).
- User taps a t.co link in X (Twitter) → redirects to
https://metamask.app.link/1WkF6GmE40b (which is a link generated by
X/Branch.io on Tweet posting) → Branch Deepview is shown → user taps
“Get the app” → opens MetaMask via Universal Link:

https://metamask-alternate.app.link/1WkF6GmE40b?__branch_flow_type=viewapp&__branch_flow_id=...&__branch_mobile_deepview_type=1.
- Issue: The app opens correctly, but in-app we show a “page not found”
(404). So the OS and Branch open the app, but we don’t know which in-app
route corresponds to link ID 1WkF6GmE40b.

### What we found

1. No resolved URI from the SDK
- The Branch iOS SDK (and react-native-branch) give us:
- The raw URL that opened the app (e.g.
https://metamask-alternate.app.link/1WkF6GmE40b?...), and
- The params from the session (e.g. from getLatestReferringParams() /
subscribe callback).
- The SDK does not build a custom deeplink URI (e.g. metamask://swap)
from link data; it only returns the params. So we have to do routing
ourselves.

2. Implemented fix:
- Added a $deeplink_path in Branch deeplinks (this must be added to
every existing and future deeplinks that we want to post on X)
- Read it from the params and build our deeplink ourselves (e.g.
metamask://${params.$deeplink_path}) and then route inside the app.

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: Fixed a bug that was causing deeplinks opened from X
app to fail

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/GE-139
Fixes: #27140

## **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**
> Touches deeplink routing/host allowlists and Branch handling on app
start, which can affect navigation from external links, but the change
is narrowly scoped and covered by new unit tests.
> 
> **Overview**
> Fixes Branch short-link universal links (notably from X on iOS) by
introducing `rewriteBranchUri`, which converts
`metamask-alternate.app.link/<id>` URLs into
`https://link.metamask.io/<$deeplink_path>` while preserving query
params.
> 
> `DeeplinkManager.start()` now applies this rewrite for both cold-start
Branch params (`~referring_link`) and `branch.subscribe` events,
replacing the prior `getLatestReferringParams` fallback logic.
> 
> Adds `MM_UNIVERSAL_LINK_HOST_ALTERNATE`
(`metamask-alternate.app.link`) and includes it in universal-link host
validation (`handleUniversalLink`) and MetaMask-host detection
(`util/deeplinks`), with new tests covering rewrite and routing
behavior.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
de4e3dc. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
[0696104](0696104)

Co-authored-by: Baptiste Marchand <75846779+baptiste-marchand@users.noreply.github.com>
…7332)

- fix: update token selector font sizing cp-7.69.0 (#27327)

<!--
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 fixes the font sizing that was broken due to a design team
update.

<!--
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: Fix bug where token selector fonts were too big

## **Related issues**

Fixes: #27328

## **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]
> **Low Risk**
> Low risk visual-only changes to
`BridgeTokenSelector`/`TokenSelectorItem` typography and icon sizing
with no logic, data, or flow changes.
> 
> **Overview**
> Updates the Bridge token selector UI to align with new sizing
guidelines by reducing the info `ButtonIcon` from `Md` to `Sm` and
dialing down token list text variants (e.g., balances and names from
`BodyMD` to `BodySM`, and symbol/balance weights from `BodyMDMedium` to
`BodyMD`).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
684ccd6. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
[6f10e3c](6f10e3c)

Co-authored-by: Bryan Fullam <bryan.fullam@consensys.net>
Resolved conflicts between stable (7.68.0) and release/7.69.0:

Build/version: take release/7.69.0 versions (7.69.0)
- android/app/build.gradle, ios project, bitrise.yml

Dependencies: take release/7.69.0 versions
- package.json: transaction-pay-controller v16.3.0, tron-wallet-snap 1.22.1
- yarn.lock: take release/7.69.0

Source code: take release/7.69.0 (newer cherry-picked fixes)
- Perps: usePerpsBalanceTokenFilter deposit flow fix (cherry-pick #27231)
- Perps: PerpsConnectionManager + HyperLiquidProvider updates
- Card: ViewPin, CardHome, CardSDK, useCardPinToken updates
- Predict: useUnrealizedPnL updates
- Ramp: index.tsx updates
- Tokens: TokenListItemV2 updates
- TransactionDetails test updates
- Trending API mock updates

Locales: take release/7.69.0 (14 language files with newer translations)
Made-with: Cursor
The Veriff SDK was reverted in 7.68.0 (commit fb9776a) but the
yarn.lock entry remained from the release/7.69.0 side of the merge,
causing yarn install to fail in CI.

Made-with: Cursor
@github-actions
Copy link
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added the INVALID-PR-TEMPLATE PR's body doesn't match template label Mar 13, 2026
@chloeYue chloeYue added team-mobile-delivery and removed INVALID-PR-TEMPLATE PR's body doesn't match template labels Mar 13, 2026
@metamaskbot metamaskbot added the INVALID-PR-TEMPLATE PR's body doesn't match template label Mar 13, 2026
@chloeYue chloeYue force-pushed the stable-sync-release-7.70.0 branch from f148b91 to e7ebdc1 Compare March 13, 2026 20:26
@github-actions github-actions bot added size-XL and removed size-M labels Mar 13, 2026
@chloeYue chloeYue force-pushed the stable-sync-release-7.70.0 branch from 8bb5e7d to 2225f98 Compare March 13, 2026 20:35
@github-actions github-actions bot added size-M and removed size-XL labels Mar 13, 2026
Resolved conflicts between stable (7.69.0) and release/7.70.0:

Build/version: take release/7.70.0 versions (7.70.0, build 4020)
- android/app/build.gradle, ios project, bitrise.yml

Dependencies: take release/7.70.0 versions
- package.json, yarn.lock

Source code: take release/7.70.0 (newer features and fixes)
- Bridge, Perps, Predict, TokenList, confirmations, HyperLiquidProvider
- All locale files (de, el, es, fr, hi, id, ja, ko, pt, ru, tl, tr, vi, zh)

Merge with "Create a merge commit" — do NOT squash.

Made-with: Cursor
@chloeYue chloeYue force-pushed the stable-sync-release-7.70.0 branch from 2225f98 to bb9ccfa Compare March 13, 2026 20:40
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

@github-actions
Copy link
Contributor

E2E Fixture Validation — Schema is up to date
16 value mismatches detected (expected — fixture represents an existing user).
View details

@chloeYue chloeYue added the skip-sonar-cloud Only used for bypassing sonar cloud when failures are not relevant to the changes. label Mar 13, 2026
The provider code comes from stable (7.69.0) but the test was taken
from release/7.70.0 during conflict resolution, causing mock mismatches.
Take stable's test to match the provider.

Made-with: Cursor
@github-actions github-actions bot added size-L and removed size-M labels Mar 13, 2026
The test must match release/7.70.0's provider, not stable's.
Reverting to release/7.70.0's test so merging this PR doesn't
break the release branch.

Made-with: Cursor
@github-actions
Copy link
Contributor

🔍 Smart E2E Test Selection

⏭️ Smart E2E selection skipped - base branch is not main (base: release/7.70.0)

All E2E tests pre-selected.

View GitHub Actions results

@github-actions github-actions bot added size-S and removed size-L labels Mar 13, 2026
@sonarqubecloud
Copy link

@chloeYue chloeYue merged commit a5fc9d3 into release/7.70.0 Mar 14, 2026
52 of 54 checks passed
@chloeYue chloeYue deleted the stable-sync-release-7.70.0 branch March 14, 2026 10:25
@github-actions github-actions bot locked and limited conversation to collaborators Mar 14, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

INVALID-PR-TEMPLATE PR's body doesn't match template size-S skip-sonar-cloud Only used for bypassing sonar cloud when failures are not relevant to the changes. team-mobile-delivery

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants