Skip to content

[pull] main from MetaMask:main#447

Merged
pull[bot] merged 8 commits into
Reality2byte:mainfrom
MetaMask:main
Jan 13, 2026
Merged

[pull] main from MetaMask:main#447
pull[bot] merged 8 commits into
Reality2byte:mainfrom
MetaMask:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Jan 13, 2026

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

smilingkylan and others added 8 commits January 12, 2026 23:31
## **Description**

This PR adds a new deeplink handler for the `download-extension` action,
enabling deep linking to the extension download flow with support for
optional query parameters.

**Reason for change:**
- Enables external services and marketing campaigns to deep link users
directly to the extension download flow
- Provides a standardized way to pass download context (type, timestamp)
via URL parameters
- Follows the established deeplink handler pattern used throughout the
app

**Improvement/Solution:**
- Created `handleDownloadExtensionUrl.ts` handler following the legacy
handler pattern
- Added comprehensive unit tests covering all parameter combinations and
error scenarios
- Integrated the handler into the deeplink routing system with proper
enum registration and switch case handling
- Supports optional `type` and `timestamp` query parameters for tracking
and analytics

**Technical details:**
- Handler parses URL parameters using URLSearchParams pattern
- Navigates to `Routes.DOWNLOAD.START` with parsed parameters
- Includes proper error handling with fallback to `Routes.WALLET.HOME`
- Uses DevLogger for debugging (not console.log)
- Fully documented with TSDoc including all supported URL formats

## **Changelog**

CHANGELOG entry: Added support for `download-extension` deeplink action
to enable direct navigation to extension download flow

## **Related issues**

Fixes:

## **Manual testing steps**

1. Type `/create-deeplink-handler` in Cursor or Claude Code and follow
the prompts. If you answer "full" to the last question it will generate
your handler code for you.

**Additional testing commands:**

**iOS Simulator:**
```bash
xcrun simctl openurl booted "https://link-test.metamask.io/my-path?type=chrome&timestamp=1234567890"
```

**Android Emulator:**
```bash
adb shell am start -W -a android.intent.action.VIEW \
  -d "https://link-test.metamask.io/my-path?type=chrome&timestamp=1234567890" \
  io.metamask.debug
```

## **Screenshots/Recordings**

### **Before**

N/A - This is a new feature (no existing behavior to show)

### **After**



https://github.com/user-attachments/assets/118e7d97-f890-4f5a-b1ad-91bddd434e1f



## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Updates the deeplink handler generation command to a comprehensive,
step-by-step guide and adds a mirrored version for Cursor.
> 
> - **Overhauled `.claude/commands/create-deeplink-handler.md`** with
interactive info gathering, `snippets` vs `full` integration modes,
detailed handler/test patterns, integration steps (A–F with critical
switch case), test commands, documentation reminders, pitfalls, and a
completion checklist
> - **Added `.cursor/commands/create-deeplink-handler.md`** containing
the same expanded guidance to keep Cursor in sync
> - **Includes references** to related rules and example handler files
to standardize implementation
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b2273eb. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

### Problem
Search token input box is too large

### Solution
Removed padding and added fixed height

## **Changelog**

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

### Android
| before | after |
| -------- | ------- |
|
![before](https://github.com/user-attachments/assets/620e55c1-f0d6-4b8e-a6d8-1a9d6ac7bf3c)
|
![after](https://github.com/user-attachments/assets/d5c8ca38-095d-4383-bf4a-dcaa5a8b8465)
|


### iOS (no change)
| before | after |
| -------- | ------- |
|
![before](https://github.com/user-attachments/assets/b71b5413-c441-481b-9d80-5a6fd87ce29b)
|
![after](https://github.com/user-attachments/assets/2caa0835-2338-4b83-9231-18a26f563d0e)
|

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

- [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]
> Adjusts the token search input sizing for consistency and reduced
height.
> 
> - In `AssetSearch`, remove `paddingVertical` from `styles.input` and
add fixed `height: 42` to `styles.textInput`
> - Update snapshots in `AssetSearch` and `SearchTokenAutocomplete` to
reflect the new input dimensions
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
501cede. 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**
bump assets controllers to v95.1.0

<!--
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: bump assets controllers to v95.1.0

## **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]
> Updates controller stack and aligns messengers with new APIs.
> 
> - Bumps `@metamask/assets-controllers` to `^95.1.0` plus related deps
(`controller-utils` `^11.18.0`, `core-backend` `^5.0.0`,
`multichain-account-service` `^5.0.0`, `network-controller` `^27.2.0`,
`permission-controller` `^12.2.0`, txn controller in lockfile, etc.);
updates `yarn.lock`
> - `AccountTrackerController` messenger: adds
`KeyringController:getState` action and `KeyringController:lock` event
> - `MultichainAccountService` messenger: adds `SnapController:getState`
action and `SnapController:stateChange` event; removes reliance on error
reporting action
> - `NetworkController` messenger: removes delegated
`ErrorReportingService:captureException` action (now none)
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
bcae286. 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 introduces a consolidated `unlockWallet` method in the
`Authentication` service. In follow up PRs, we will be replacing both
`userEntryAuth` and `appTriggeredAuth` invocations with this new method.
Under the hood, `unlockWallet` handles both manual and biometric
password login as well as seedless onboarding checks. Unit tests has
been provided to validate functionality.

## **Changelog**

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

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

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

CHANGELOG entry:

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-238

## **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
- [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]
> Adds a unified wallet unlock path and supporting utilities to
streamline login flows and error handling.
> 
> - Introduces `Authentication.unlockWallet` to handle manual/biometric
login, seedless rehydration/password sync checks, post-login ops, and
navigation to `onboarding` or `home`
> - Adds `utils` (`handlePasswordSubmissionError`,
`checkPasswordRequirement`), `constants` (error strings,
`MIN_PASSWORD_LENGTH`), and `types` (`UnlockWalletErrorType`) for
granular error handling
> - Exposes `unlockWallet` via `useAuthentication` hook
> - Resets biometrics after password change and tidies `lockApp`
(explicit keyring lock, state reset, navigation)
> - Extensive unit tests for `unlockWallet` and new utils; adjusts
existing tests (e.g., vault recreation failure expectations)
> - Adds placeholder `store/sagas/authentication.ts` for future state
machine integration
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
c65e0e2. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
… showActionLabels (#24433)

<!--
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 selecting a network through dapp connection, the network list
showed "Add" text for adding popular networks, while the token filter
network list showed a "+" icon. This inconsistency was addressed by
aligning both to use the "+" icon.

The compactMode prop was refactored to showActionLabels with inverted
logic - the "+" icon is now the default behavior, and showActionLabels
is used to opt-in for "Add"/"Switch" text labels (only needed in the
full NetworkSettings screen).

## **Changelog**

CHANGELOG entry: Changed "Add" text to "+" icon for adding popular
networks in dapp connection flow for UI consistency

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TMCU-321

## **Manual testing steps**

```gherkin
Feature: Add popular networks icon consistency

  Scenario: user views popular networks in dapp connection flow
    Given user has a dapp requesting network connection
    And user opens the network selector

    When user scrolls to the "Additional Networks" section
    Then user sees popular networks with a "+" icon on the right side
    And user does NOT see "Add" text
```

## **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/2ced488f-32a3-4b57-9798-7003ad55d4c3


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

### **After**


https://github.com/user-attachments/assets/defa82ba-7d69-4c94-9565-432ee6d1bbc4


<!-- [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]
> Aligns popular network actions to use a "+" icon by default and
introduces `showActionLabels` to opt-in to "Add"/"Switch" labels where
needed.
> 
> - Replaces `compactMode` with `showActionLabels` in `CustomNetwork`
props and implementation; inverted logic so icon is default
> - Updates `NetworkMultiSelector` to drop `compactMode` from
`CUSTOM_NETWORK_PROPS` and forward new props
> - Passes `showActionLabels` from `NetworkSettings` where text labels
are required
> - Refreshes tests and `NetworkSelector` snapshots to reflect the icon
(`Svg Add`) instead of "Add" text
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f8cc15c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…24454)

## **Description**

Adds the foundational feature flag and TypeScript types for the Predict
Live NFL feature. This is Task 00 from the Live NFL implementation plan
and unblocks all subsequent development work.

**Reason for change:**
The Live NFL feature requires new data structures to represent game
state (teams, scores, periods, game status) and a feature flag to gate
the rollout.

**Solution:**
- Added `selectPredictLiveNflEnabled` feature flag selector with remote
config and local env fallback (`MM_PREDICT_LIVE_NFL_ENABLED`)
- Added game-related TypeScript types: `PredictSportsLeague`,
`PredictGameStatus`, `PredictSportTeam`, `PredictMarketGame`,
`GameUpdate`, `PriceUpdate`
- Extended `PredictMarket` type with optional `game` property
- Updated navigation params with `isGame` flag
- Added Polymarket API types for team and game event data

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: N/A (internal infrastructure task)

## **Manual testing steps**

```gherkin
Feature: Live NFL Feature Flag and Types

  Scenario: Feature flag returns true when remote flag is enabled
    Given the remote feature flag predictLiveNflEnabled is set to enabled with valid version
    
    When selectPredictLiveNflEnabled selector is called
    Then it returns true

  Scenario: Feature flag falls back to local env var
    Given the remote feature flag is not configured
    And MM_PREDICT_LIVE_NFL_ENABLED environment variable is set to "true"
    
    When selectPredictLiveNflEnabled selector is called
    Then it returns true

  Scenario: Types compile without errors
    Given the new types are added to the codebase
    
    When TypeScript compilation runs
    Then no type errors are reported
```

## **Screenshots/Recordings**

### **Before**

N/A - Infrastructure task (no UI changes)

### **After**

N/A - Infrastructure task (no UI changes)

**Test Results:**
```
PASS app/components/UI/Predict/selectors/featureFlags/index.test.ts
  Predict Feature Flag Selectors
    selectPredictLiveNflEnabled
      ✓ returns true for enabled version-gated flag with valid version
      remote flag precedence
        ✓ returns true when remote flag enabled overrides local flag false
        ✓ returns false when remote flag disabled overrides local flag true
        ✓ returns false when app version below minimum required version
      local flag fallback
        ✓ falls back to local flag when remote flag is invalid
        ✓ returns false from local flag when remote flag is null
        ✓ falls back to local flag when remote feature flags are empty
        ✓ returns false from local flag when controller is undefined

Test Suites: 1 passed, 1 total
Tests:       27 passed, 27 total
```

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Establishes the foundation for Live NFL in Predict with a
version-gated feature flag and new game data structures.
> 
> - Adds `selectPredictLiveNflEnabled` selector (remote
`predictLiveNflEnabled` with env fallback `MM_PREDICT_LIVE_NFL_ENABLED`)
and comprehensive tests
> - Extends Predict types: `PredictSportsLeague`, `PredictGameStatus`,
`PredictSportTeam`, `PredictMarketGame`, `GameUpdate`, `PriceUpdate`;
adds optional `game` to `PredictMarket`
> - Updates navigation params: `PredictMarketDetails` now supports
`isGame`
> - Expands Polymarket API types with `PolymarketApiTeam` and
`PolymarketApiGameEvent`
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
1592a1c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

This PR implements a graceful degradation pattern for Perps asset icons,
allowing the app to first attempt loading icons from MetaMask's
contract-metadata repository and automatically fall back to
HyperLiquid's CDN if the primary source fails.

We want to host curated Perps icons in our own contract-metadata repo
for quality control. However, not all icons may be uploaded yet, and we
need a reliable fallback. This approach allows gradual migration while
maintaining full icon coverage

Solution:
1. Re-added `METAMASK_PERPS_ICONS_BASE_URL` constant pointing to
contract-metadata repo
2. Created `getAssetIconUrls()` function that returns both primary and
fallback URLs
3. Updated PerpsTokenLogo component to try primary URL first, then
fallback on error
4. HIP-3 assets use the hip3:dex_SYMBOL.svg format for MetaMask URLs

In cases where both primary and fallback urls fail, we fallback to the
default two letter icon.

## **Changelog**

CHANGELOG entry: Perps icon fallback url mechanism

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TAT-2329

## **Manual testing steps**

```gherkin
Feature: Perps Token Icon Fallback

  Scenario: User views Perps market list with icons from MetaMask repo
    Given the user has opened the Perps tab
    When the market list loads
    Then icons load from MetaMask contract-metadata URL first
    And if MetaMask URL fails, icons fall back to HyperLiquid URL
    And if both URLs fail, a 2-letter text fallback is displayed

  Scenario: User views HIP-3 asset icons
    Given the user has opened a HIP-3 market (e.g., xyz:AAPL)
    When the icon loads
    Then the primary URL uses format hip3:xyz_AAPL.svg
    And the fallback URL uses format xyz:AAPL.svg
```

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Implements a two-source icon strategy for Perps, prioritizing
MetaMask’s `contract-metadata` with automatic fallback to HyperLiquid,
plus comprehensive tests.
> 
> - Adds `METAMASK_PERPS_ICONS_BASE_URL` and new `getAssetIconUrls()` in
`marketUtils` to return `{ primary, fallback }` URLs (supports HIP-3
`hip3:dex_SYMBOL.svg` and `k`-prefix handling)
> - Updates `PerpsTokenLogo` to try `primary` first, switch to
`fallback` on `onError`, reset to primary on symbol change, and show
2-letter text fallback if both fail; adjusts `key/recyclingKey` to
reflect URL state
> - Extends tests in `PerpsTokenLogo.test.tsx` and `marketUtils.test.ts`
to cover URL selection, fallback flow, HIP-3 formatting, and casing
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
03ee9c9. 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**

fix 7702 transactions related e2e on mobile

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

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**
NA

## **Pre-merge author checklist**

- [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]
> Updates E2E to stabilize and enable smart account flows for 7702
transactions.
> 
> - Adds testIDs to `SmartAccount` link and modal back button; imports
`SwitchAccountModalSelectorIDs`
> - Updates selectors (`SMART_ACCOUNT_BUTTON_LOCALHOST` →
`switch_account_button-Local RPC`) and adds
`SMART_ACCOUNT_BACK_BUTTON`/`SMART_ACCOUNT_LINK`
> - Extends `SwitchAccountModal` page object with smart account
link/back actions
> - Introduces new spec
`e2e/specs/confirmations-redesigned/transactions/7702/batch-transaction.spec.ts`
with Local RPC fixture; removes old failing quarantine spec
> - Adjusts test flow for network switching and Dapp navigation; some
steps commented/skipped pending toggle click fix
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
aa26f47. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Charly Chevalier <charlyy.chevalier@gmail.com>
@pull pull Bot locked and limited conversation to collaborators Jan 13, 2026
@pull pull Bot added the ⤵️ pull label Jan 13, 2026
@pull pull Bot merged commit 75f64d7 into Reality2byte:main Jan 13, 2026
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.

8 participants