Skip to content

[pull] main from MetaMask:main#406

Merged
pull[bot] merged 14 commits into
Reality2byte:mainfrom
MetaMask:main
Dec 12, 2025
Merged

[pull] main from MetaMask:main#406
pull[bot] merged 14 commits into
Reality2byte:mainfrom
MetaMask:main

Conversation

@pull

@pull pull Bot commented Dec 12, 2025

Copy link
Copy Markdown

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 : )

cmd-ob and others added 14 commits December 12, 2025 11:43
…I response configuration to be more deterministic (#23965)

<!--
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 rule to ignore e2e changes not related to Detox when recommending
tags
* Use `temparature` to make reasoning more deterministic when the same
input is used. i.e So we don't get different outputs for the same inputs
* Remove extended thinking as it cannot be used with `0` temparature. 
* This is fine since we are using the Opus model 

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

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

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

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

CHANGELOG entry:

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Include `appwright/` in code search and switch Claude to temperature=0
with no extended thinking; update prompts/guidance accordingly.
> 
> - **AI Analysis & Config**
> - Set `CLAUDE_CONFIG.temperature` to `0` and pass `temperature` to
`anthropic.messages.create`.
> - Remove extended thinking config and logging (`thinking`,
`thinkingBudgetTokens`) and related prompt references.
>   - Keep `maxTokens` usage unchanged.
> - **Prompt Updates**
> - Add guidance: changes in `wdio/` or `appwright/` don't require Detox
tags unless app code also changed.
>   - Remove mention of extended thinking from shared reasoning text.
> - **Tooling**
> - Update `grep-codebase` to search `appwright/` directory in addition
to existing paths.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d19c38b. 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**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

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

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

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

CHANGELOG entry:

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

- [ ] 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]
> Enhances tapAtIndex with optional delay and shorter inner timeout,
adds an ellipsis-button accessor, and updates the multi-SRP test to wait
for/tap the ellipsis by index before renaming.
> 
> - **E2E Framework (`e2e/framework/Gestures.ts`)**:
>   - Improves `tapAtIndex`:
>     - Adds `delay` option and pre-tap wait.
> - Uses shorter inner visibility timeout (`min(3000, timeout/3)`) for
retries.
>     - Passes `elemDescription` to retry metadata.
> - **Wallet Page Object
(`e2e/pages/wallet/AccountListBottomSheet.ts`)**:
> - Adds `getEllipsisMenuButtonAtIndex(accountIndex)` to fetch
`AccountCellIds.MENU` at a given index.
> - **Tests (`e2e/specs/identity/account-syncing/multi-srp.spec.ts`)**:
> - Updates flow to wait for the 4th account’s ellipsis button via
`getEllipsisMenuButtonAtIndex(3)` before tapping and renaming.
>   - Clarifies descriptions/comments around visibility waits.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
113a90a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…on device. (#23520)

<!--
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: google login fallback in android if no google account available
on device.
* Jira: https://consensyssoftware.atlassian.net/browse/SL-351
* Github Issue: #22766
<!--
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: google login fallback in android if no google
account available on device.

## **Related issues**

Fixes: #22766

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


https://github.com/user-attachments/assets/c3d4f0fb-187d-4daf-839a-6dd80e539fe9


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

### **After**


https://github.com/user-attachments/assets/9b7bb0bf-8251-4808-8e02-c56ec191a518


<!-- [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]
> Adds a browser-based Google login fallback on Android when ACM has no
credentials, refactors Google handlers with a shared base, and updates
onboarding to use the fallback path.
> 
> - **OAuth Handlers**:
> - **Android Google Fallback**: Introduces
`AndroidGoogleFallbackLoginHandler` (browser/PKCE flow) and
`AndroidGoogleRedirectUri` (universal link) in `constants`.
> - **Shared Google Logic**: Adds `BaseGoogleLoginHandler` used by
`IosGoogleLoginHandler` and Android fallback; updates error messages and
token request shaping.
> - **Factory**: `createLoginHandler(os, provider, fallback?)` supports
Android Google fallback; uses universal redirect for fallback.
> - **Types**: `OAuthService.handleSeedlessAuthenticate` now uses
`SeedlessAuthConnection`.
> - **Onboarding Flow**:
> - On Android Google errors
`GoogleLoginNoCredential`/`GoogleLoginNoMatchingCredential`, attempts
browser fallback instead of showing error sheet; maintains loading state
and success navigation (e.g., `ChoosePassword`).
> - **Tests**:
> - Adds unit tests for Android Google fallback handler and factory
fallback behavior.
> - Updates onboarding tests to verify fallback attempts, silent
handling on failure, and success navigation.
> - Minor test message tweaks and selector test type import adjustments.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
a463787. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: ieow <4881057+ieow@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**

Refactor block explorer URL generation in AssetOptions to correctly link
to token pages for all assets, including Solana tokens.

The previous implementation for "View on Block Explorer" in
`AssetOptions` had fragmented logic, especially for non-EVM chains like
Solana, leading to incorrect links (e.g., linking to the base explorer
URL instead of the token's page). This PR centralizes the block explorer
URL logic into the `useBlockExplorer` hook, introducing dedicated
methods for fetching base and token-specific URLs, ensuring accurate
navigation for both EVM and non-EVM assets. This resolves
#22321 and
[ASSETS-1968](https://consensyssoftware.atlassian.net/browse/ASSETS-1968).

<!--
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: token details block explorer correct urls

## **Related issues**

Fixes: #22321 and
[ASSETS-1968](https://consensyssoftware.atlassian.net/browse/ASSETS-1968).

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

https://www.loom.com/share/5504ab1a9bc249419419ea06b7dbce6d

https://www.loom.com/share/31c7823f68244e0bb28b47e0572cb630

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

---
<a
href="https://cursor.com/background-agent?bcId=bc-b572264e-4b72-4b23-a44c-c47758f3e277"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-cursor-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-cursor-light.svg"><img alt="Open in
Cursor"
src="https://cursor.com/open-in-cursor.svg"></picture></a>&nbsp;<a
href="https://cursor.com/agents?id=bc-b572264e-4b72-4b23-a44c-c47758f3e277"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-web-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-web-light.svg"><img alt="Open in Web"
src="https://cursor.com/open-in-web.svg"></picture></a>



[ASSETS-1968]:
https://consensyssoftware.atlassian.net/browse/ASSETS-1968?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Centralizes block explorer URL generation in useBlockExplorer (incl.
base URL), updates AssetOptions to correctly handle EVM/non‑EVM tokens,
and refreshes tests and notification icons to the new design system.
> 
> - **Hooks**:
> - `useBlockExplorer`: adds `getBlockExplorerBaseUrl`, expands
EVM/non‑EVM support, cleans CAIP handling, and consolidates explorer
name/URL logic.
> - `useMultichainBlockExplorerTxUrl` tests: mock
`getBlockExplorerBaseUrl` and validate EVM/non‑EVM explorer name/URL
resolution.
> - **Asset Options**:
> - Replace legacy explorer logic with `useBlockExplorer`; correct "View
on block explorer" for native vs token addresses (incl. Solana CAIP
extraction and wrapped SOL handling).
> - Preserve portfolio/token details/remove flows; add conditional
rendering based on native/non‑EVM state.
> - Tests: update expectations to address URLs, add parametrized cases
for EVM and non‑EVM, and InAppBrowser navigation.
> - **Notifications UI**:
> - Migrate to `@metamask/design-system-react-native` icons (`IconName`,
`BadgeIcon`), adjust unread dot positioning.
> - Update `getNotificationBadge` return type and `NotificationMenuItem`
icon types.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
4244c71013db46a5e0acf02e7477bc84079692b3. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
…23975)

## **Description**
We no longer need to track if a confirmations is redesign so we can
delete this code. Similar thing was done in the extension:
MetaMask/metamask-extension#38706

## **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: MetaMask/MetaMask-planning#6075

## **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]
> Removes 'redesigned_confirmation' from metrics and conditionally
includes only Blockaid-provided `ui_customizations`; updates related
tests and ERC20 tracking event.
> 
> - **Metrics (signatures)**
> - `useSignatureMetrics`: stop appending `redesigned_confirmation`;
only set `ui_customizations` when non-empty and pass through Blockaid
values unchanged.
>   - Refactors analytics params construction accordingly.
> - **Tests**
> - Update `useSignatureMetrics.test.ts` expectations to remove
`redesigned_confirmation` and reflect conditional `ui_customizations`.
> - **ERC20 Tracking**
> - `useTrackERC20WithoutDecimalInformation`: remove `ui_customizations`
from `INCOMPLETE_ASSET_DISPLAYED` event properties.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
93c9ece. 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**

Remove the sparkle icon from the product announcements setting.

<!--
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: style: remove announcement settings sparkle icon

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MDP-372,
https://consensyssoftware.atlassian.net/browse/ASSETS-2121

## **Manual testing steps**

1. View Notifications Settings
2. Inspect Feature Announcement Label

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

<img width="420" height="880" alt="Screenshot 2025-12-12 at 09 35 06"
src="https://github.com/user-attachments/assets/e759bb67-b9ec-438b-aa22-bbf7f4ddcc54"
/>

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

---
<a
href="https://cursor.com/background-agent?bcId=bc-fe4cd523-44cf-4b37-ad51-47ed238dd763"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-cursor-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-cursor-light.svg"><img alt="Open in
Cursor"
src="https://cursor.com/open-in-cursor.svg"></picture></a>&nbsp;<a
href="https://cursor.com/agents?id=bc-fe4cd523-44cf-4b37-ad51-47ed238dd763"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-web-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-web-light.svg"><img alt="Open in Web"
src="https://cursor.com/open-in-web.svg"></picture></a>


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Removes the icon from the Feature Announcement toggle and makes
`CustomNotificationsRow` simpler by making `icon` optional and removing
`description`, with styles/tests updated.
> 
> - **Settings/Notifications**
> - **FeatureAnnouncementToggle**: Stop passing `icon` prop to
`CustomNotificationsRow`.
>   - **CustomNotificationsRow**:
>     - Make `icon` optional and render it conditionally.
>     - Remove `description` prop and its rendering.
>     - Simplify title text usage and remove extra title style.
> - **Styles**: Remove unused `title` style in
`NotificationOptionToggle/styles.ts`.
> - **Tests**: Update test and snapshot to reflect removed `description`
and optional `icon`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f4c65f2. 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**

Update NotificationSettings container padding and line margin to align
with app spacing consistency.

<!--
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: style: update notification setting container padding

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MDP-373
https://consensyssoftware.atlassian.net/browse/ASSETS-2120

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

<img width="483" height="971" alt="Screenshot 2025-12-12 at 11 44 47"
src="https://github.com/user-attachments/assets/0fa26104-b2b7-4bed-8840-14115d926e07"
/>


### **After**

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

<img width="488" height="971" alt="Screenshot 2025-12-12 at 11 44 09"
src="https://github.com/user-attachments/assets/b8fdaf1b-c656-4a57-aad8-55dae65427c8"
/>


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

---
<a
href="https://cursor.com/background-agent?bcId=bc-a4ccb57f-a60a-4c7f-9b23-0691e150611b"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-cursor-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-cursor-light.svg"><img alt="Open in
Cursor"
src="https://cursor.com/open-in-cursor.svg"></picture></a>&nbsp;<a
href="https://cursor.com/agents?id=bc-a4ccb57f-a60a-4c7f-9b23-0691e150611b"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-web-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-web-light.svg"><img alt="Open in Web"
src="https://cursor.com/open-in-web.svg"></picture></a>


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Tightens NotificationsSettings horizontal padding to 16 and updates
divider margin; refreshes snapshot accordingly.
> 
> - **Styles (NotificationsSettings)**:
> - Change `container` from `padding: 24` to `paddingLeft/Right: 16` and
keep `paddingBottom: 48`.
>   - Update `line` `marginHorizontal` from `-24` to `-16`.
> - **Tests**:
>   - Update snapshot to reflect new horizontal padding values.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
6460ac1. 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**

Update notification badges to use `BadgeIcon` from the design system to
improve visibility of icons.

The previous `Badge` component with `BadgeVariant.NotificationsKinds`
rendered icons at `IconSize.Xss`, making them difficult to see.
Switching to `BadgeIcon` with `IconSize.Lg` addresses this by providing
a larger, more readable icon.

## **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: style: update notification item badge style

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MDP-371
https://consensyssoftware.atlassian.net/browse/ASSETS-2122

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

<img width="436" height="893" alt="Screenshot 2025-12-12 at 14 03 20"
src="https://github.com/user-attachments/assets/613350a6-0f86-488f-bdd6-d0381c1824b0"
/>


### **After**

<img width="437" height="906" alt="Screenshot 2025-12-12 at 11 35 52"
src="https://github.com/user-attachments/assets/d813daa9-b1bb-41f5-9641-ebabc3a4cbe9"
/>


<!-- [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.

---
<a
href="https://cursor.com/background-agent?bcId=bc-1e901d8a-a6db-48c0-9c90-3a80aa114e18"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-cursor-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-cursor-light.svg"><img alt="Open in
Cursor"
src="https://cursor.com/open-in-cursor.svg"></picture></a>&nbsp;<a
href="https://cursor.com/agents?id=bc-1e901d8a-a6db-48c0-9c90-3a80aa114e18"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-web-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-web-light.svg"><img alt="Open in Web"
src="https://cursor.com/open-in-web.svg"></picture></a>


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Replaces notification item badge with design-system BadgeIcon (larger
size) and adds a design-system unread status indicator, updating related
imports/types and removing an unused style.
> 
> - **UI**:
> - `NotificationMenuItem/Icon.tsx`: Replace `Badge` with `BadgeIcon`
(`IconSize.Lg`); add `BadgeStatus` ("New") shown when unread; tweak
layout (`flex-row gap-1`) and remove reliance on `styles.badgeWrapper`.
>   - `Notification/List/styles.ts`: Remove unused `badgeWrapper` style.
> - **Types/Utils**:
> - Use `IconName` from `@metamask/design-system-react-native` across
files; annotate `getNotificationBadge` to return `IconName`.
> - **Tests**:
>   - Update `Icon.test.tsx` to import `IconName` from design system.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
681890e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

This PR introduces a service to manage the horizontal orientation of the
mobile application programatically instead of being global.

## **Changelog**

CHANGELOG entry: horizontal orientation service

## **Related issues**

Fixes: #23903

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

Uploading Screen Recording 2025-12-11 at 2.46.30 PM.mov…

## **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]
> Centralizes orientation control, locking app to portrait and enabling
landscape solely for the perps fullscreen chart, with updated modal
logic and tests.
> 
> - **Core**:
> - **ScreenOrientation**: Add `ScreenOrientationService`
(`lockToPortrait`, `allowLandscape`, `isLockedToPortrait`) with exports
and constants; introduce `useScreenOrientation` hook.
> - **App Init**: Lock orientation to portrait on startup in
`components/Views/Root/index.tsx`.
> - **Perps**:
> - **Fullscreen Modal**: Refactor `PerpsChartFullscreenModal` to use
`useScreenOrientation({ allowLandscape: isVisible })`; simplify
close/error handlers (orientation handled by hook).
> - **Tests**:
> - Add unit tests for `ScreenOrientationService` and
`useScreenOrientation`.
> - Update modal tests to reflect hook-managed orientation and ensure
`onClose` behavior; mock `Logger`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
5b75bee. 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**

Improves Toast component styling and positioning:

1. **Vertical centering:** Added alignItems: 'center' to the toast base
styles to vertically center the icon/avatar with the text content
2. **Elevated position:** Increased bottomPadding from 16px to 36px to
raise the toast higher above the tab bar for better visibility

## **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`
3. 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: Improved Toast component visual alignment and
positioning

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MDP-261
https://consensyssoftware.atlassian.net/browse/MDP-387

## **Manual testing steps**

```gherkin
Feature: Toast component styling improvements

  Scenario: Toast appears at elevated position
    Given the app is running
    When any toast notification is triggered
    Then the toast renders 20px higher than before (36px padding vs 16px) with the icon vertically centered with the text
```

## **Screenshots/Recordings**

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

### **Before**
<img width="406" height="463" alt="Screenshot 2025-12-11 at 16 16 26"
src="https://github.com/user-attachments/assets/a73efca1-2a0e-4471-befa-01d624aae2df"
/>

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

### **After**
<img width="391" height="453" alt="Screenshot 2025-12-11 at 16 08 08"
src="https://github.com/user-attachments/assets/a126742c-0c31-429d-b2cf-467da0526a07"
/>

<!-- [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]
> Vertically centers Toast content and raises its position by increasing
bottom padding to 36.
> 
> - **Toast**:
> - **Styles**: Add `alignItems: 'center'` to `Toast.styles.ts` base
container for vertical alignment of avatar/icon with text.
> - **Layout**: Increase `bottomPadding` from `16` to `36` in
`Toast.tsx` to position the toast higher above the tab bar.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
eea5f97. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…it (#23968)

## **Description**

Controllers can modify state during `Engine.init()` (e.g.,
`SnapController` granting permissions to `PermissionController` when
handling preinstalled snaps). These state changes were not being
persisted because persistence subscriptions are set up **after**
controller construction completes, missing any events emitted during
initialization.

CHANGELOG entry: null

### The Problem

1. `EngineService.start()` calls `Engine.init()`
2. During `Engine.init()`, controllers are constructed via
`initModularizedControllers()`
3. `SnapController` constructor calls `#handlePreinstalledSnaps()` →
`#updatePermissions()` → `PermissionController:grantPermissions`
4. `PermissionController` updates its state (e.g., adds snap
permissions)
5. `PermissionController` emits `stateChange` event, but no
subscriptions exist yet
6. After `Engine.init()` returns, persistence subscriptions are set up -
**too late to capture the changes**

### The Solution

This fix passes the initial state (loaded from persistence before init)
to `setupEnginePersistence()` and compares controller state after init
using **1-level deep referential equality**.

Controllers preserve referential equality for unchanged properties (via
Immer). If a property reference at the first level differs from the
initial state, the state changed during init and needs to be persisted.

### Key Changes

- Add `initialState` parameter to `initializeControllers()` and
`setupEnginePersistence()`
- Compare `filteredState` properties against `initialState` at 1-level
deep
- Handle new installs/controllers where `initialState` is undefined
- Only persist if there's actual state to save (non-empty
`filteredState`)
- Reuse the same debounced `persistController` function for consistency

## **Changelog**

CHANGELOG entry: Fixed an issue where controller state changes during
engine initialization were not being persisted

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: Persist controller state changes during Engine.init()

  Scenario: Preinstalled snap permissions are persisted on fresh install
    Given the app is freshly installed with no persisted state
    
    When the app starts and Engine.init() completes
    Then PermissionController state should contain preinstalled snap permissions
    And the PermissionController state should be persisted to storage
    
    When the app is killed and restarted
    Then the preinstalled snap permissions should still be present

  Scenario: Controller state changes during init are detected and persisted
    Given the app has persisted state from a previous session
    
    When the app starts and a controller's state changes during Engine.init()
    Then the changed controller state should be persisted
    And a log message should indicate the controller state was queued for persist
```

## **Screenshots/Recordings**

### **Before**

N/A - This is a persistence/data fix, not a UI change.

### **After**

N/A - This is a persistence/data fix, not a UI change.

## **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
- [ ] 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).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Detects and persists controller state changes occurring during
Engine.init by comparing post-init filtered state to initial state, and
adds comprehensive tests.
> 
> - **EngineService**
> - Pass `initialState` into `initializeControllers` and
`setupEnginePersistence` to detect changes made during `Engine.init()`.
> - In `setupEnginePersistence`, compute filtered state via
`getPersistentState` and compare 1-level deep against `initialState`; if
changed and non-empty, persist immediately using debounced
`persistController` and log.
> - Maintain subscriptions for future state changes; add error
handling/logging and skip controllers without persistent state.
> - Update `start()` and `initializeVaultFromBackup()` to pass loaded
state when initializing controllers.
> - **Tests**
> - Add/expand tests covering: init-time persistence detection,
unchanged state, new installs, property removals, empty filtered state,
missing `controllerMessenger`, and graceful error handling.
> - Ensure cleanup/restoration of mocked properties and avoid unhandled
rejections in persistence tests.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b0cf0da. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

update asset details transition to left to right
## **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/MDP-231

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

`~`

### **Before**


https://github.com/user-attachments/assets/f6af6291-fd0b-4279-a283-c8b18d69df3d

### **After**


https://github.com/user-attachments/assets/55fe6812-a515-4fe1-9159-9feb8c6f53aa

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

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Updates the Asset route to slide in left-to-right and replaces the
modal-based Asset flow with a standard navigator.
> 
> - **Navigation**:
> - **Asset flow**: Replace `AssetModalFlow` with `AssetNavigator`
(non-modal) and add left-to-right transition via
`options.animationEnabled` and `cardStyleInterpolator` on `Stack.Screen`
`"Asset"` in `app/components/Nav/Main/MainNavigator.js`.
> - **Tests**:
>   - Update snapshot to reflect new `options` on the `"Asset"` screen.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b70d239. 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**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

This PR bumps `@metamask/bridge-controller` to v64.1 and
`@metamask/bridge-status-controller` to v64.0.1

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


<img width="1520" height="919" alt="Screenshot 2025-12-10 at 5 11 46 PM"
src="https://github.com/user-attachments/assets/7b086e9d-fb48-4d83-8319-b482090931e4"
/>

## **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]
> Upgrades bridge controllers and refactors bridge hooks/utils to use
new quote properties and fiat calculations, adds `usd_amount_source`,
updates tests, and removes an obsolete messenger action.
> 
> - **Dependencies**
> - Upgrade `@metamask/bridge-controller` to `^64.1.0` and
`@metamask/bridge-status-controller` to `^64.0.1`; remove patch; update
`yarn.lock`.
> - **Bridge Quote Events**
> - Replace manual event props with `getQuotesReceivedProperties` and
adopt `QuoteWarning` typings; change warning key to `price_impact`.
> - **Unified Swap/Bridge Context**
> - Add USD source amount via new exchange-rate utilities: compute
`usd_amount_source` from `calcTokenFiatValue` and currency rates.
> - **Exchange Rates Utils**
> - Extract `calcTokenFiatValue` (numeric) and rework
`getDisplayCurrencyValue` to use it.
> - Add `fetchTokenExchangeRates` for EVM (Codefi) and non-EVM (Price
API) paths.
> - **Messaging**
> - Remove delegated action `BridgeController:getBridgeERC20Allowance`
from Bridge Status messenger.
> - **Tests**
> - Update/expand tests for new warnings, event props, fiat
calculations, fetching paths, and Solana handling.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
392679d. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
#23742)

## **Description**

This PR performs a significant cleanup and simplification of the
`DeeplinkManager` subsystem by removing unused code from an incomplete
v2 routing system migration and consolidating the codebase architecture.

### What changed and why

**1. Removed unused v2 deeplink routing system (~1,500 lines)**
The codebase contained a partially-built "v2" deeplink routing system
that was never activated (gated behind an unused `MM_UNIVERSAL_ROUTER`
feature flag). This included:
- `/handlers/v2/` directory (BaseHandler, SwapHandler, SendHandler,
NavigationHandler)
- UniversalRouter and registry patterns that weren't connected to
production code
- Type definitions that only served the v2 system

**2. Consolidated `SharedDeeplinkManager` into `DeeplinkManager`**
Previously, `SharedDeeplinkManager` was a separate file that was
essentially a singleton wrapper around `DeeplinkManager`. This added
unnecessary indirection. Now:
- `SharedDeeplinkManager` is exported directly from `DeeplinkManager.ts`
- The singleton pattern is built into the `DeeplinkManager` class itself
- Removed `dispatch` and `navigation` instance properties in favor of
using services directly where needed

**3. Reorganized file structure**
- Moved `parseDeeplink.ts` to `/utils/` (it's a utility, not a handler)
- Moved `handleDeeplink.ts` to `/handlers/legacy/` (entry point handler)
- Consolidated tests alongside their implementations

**4. Refactored `handleUniversalLink.ts`**
- Changed 15+ `if/else if` chains to cleaner `switch` statements for
action handling
- Improved readability without changing behavior

### Trade-offs
- This is a large diff due to deleted files (~1,134 lines removed, ~456
added)
- The v2 system removal is irreversible, but the system was never used
in production

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Refs: Internal deeplink cleanup initiative (no tracking issue)

## **Manual testing steps**

```gherkin
Feature: Deeplink handling

  Scenario: User opens a universal link from external source
    Given the app is installed and user is logged in
    When user taps a metamask.io deeplink (e.g. https://link.metamask.io/swap)
    Then the app should open and navigate to the appropriate screen

  Scenario: User opens app via branch.io link
    Given the app is installed but not running
    When user taps a branch.io deeplink
    Then the app should cold start and process the deeplink correctly

  Scenario: User receives push notification with deeplink
    Given the app is suspended/closed
    When user taps a push notification containing a deeplink
    Then the app should handle the deeplink after launch
```

## **Screenshots/Recordings**

### **Before**

N/A - No UI changes

### **After**

N/A - No UI changes

## **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]
> Consolidates DeeplinkManager (inlining SharedDeeplinkManager), removes
the unused v2 routing system, refactors legacy handlers/navigation
usage, and updates call sites and tests.
> 
> - **Core Deeplink Architecture**
> - Merge `SharedDeeplinkManager` into `DeeplinkManager` (singleton API:
`init/start/getInstance/parse/...`).
>   - Add Branch + FCM push processing in `DeeplinkManager.start`.
> - Move `parseDeeplink` to `utils`; re-export entry points from
`core/DeeplinkManager/index.ts`.
> - Remove v2 router system (handlers, registry, normalizer, types, and
related tests).
> - **Legacy Handlers Refactor**
> - Convert many handlers to use `NavigationService` directly and
simplify signatures (drop explicit navigation arg).
> - `handleUniversalLink`: switch-based action routing, interstitial
logic kept, streamlined
ramp/deposit/send/dapp/create-account/perps/rewards/predict flows.
> - Extract `handleApproveUrl`; `handleEthereumUrl` now uses it and
`switchNetwork` utility.
> - Add new handlers: perps/rewards/create-account/enable-card-button
with Redux/Navigation integration.
> - **App Integration Updates**
> - Replace imports of `SharedDeeplinkManager` with
`core/DeeplinkManager/DeeplinkManager` across BrowserTab, Carousel,
Notifications, QRScanner, Navbar, sagas.
> - Update calls to `SharedDeeplinkManager.parse` or
`getInstance().parse` accordingly.
> - Ramp/Deposit deeplink modules now navigate via `NavigationService`.
> - **Utilities/Network**
> - `switchNetwork` refactored to use global `store.dispatch` and
`handleNetworkSwitch` helper; adds alerting and active-chain guard.
> - **Tests**
> - Adjust unit tests to new APIs and mocks; add coverage for
`DeeplinkManager.start` (Branch/FCM), universal link routing,
perps/rewards flows, and network switching.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3c926c1. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@pull pull Bot locked and limited conversation to collaborators Dec 12, 2025
@pull pull Bot added the ⤵️ pull label Dec 12, 2025
@pull pull Bot merged commit 627263e into Reality2byte:main Dec 12, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.