Skip to content

release: 13.42.0#44797

Draft
metamaskbot wants to merge 248 commits into
stablefrom
release/13.42.0
Draft

release: 13.42.0#44797
metamaskbot wants to merge 248 commits into
stablefrom
release/13.42.0

Conversation

@metamaskbot

@metamaskbot metamaskbot commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

🚀 v13.42.0 Testing & Release Quality Process

Hi Team,
As part of our new MetaMask Release Quality Process, here’s a quick overview of the key processes, testing strategies, and milestones to ensure a smooth and high-quality deployment.


📋 Key Processes

Testing Strategy

  • Developer Teams:
    Conduct regression and exploratory testing for your functional areas, including automated and manual tests for critical workflows.
  • QA Team:
    Focus on exploratory testing across the wallet, prioritize high-impact areas, and triage any Sentry errors found during testing.
  • Customer Success Team:
    Validate new functionalities and provide feedback to support release monitoring.

GitHub Signoff

  • Each team must sign off on the Release Candidate (RC) via GitHub by the end of the validation timeline (Tuesday EOD PT).
  • Ensure all tests outlined in the Testing Plan are executed, and any identified issues are addressed.

Issue Resolution

  • Resolve all Release Blockers (Sev0 and Sev1) by Tuesday EOD PT.
  • For unresolved blockers, PRs may be reverted, or feature flags disabled to maintain release quality and timelines.

Cherry-Picking Criteria

  • Only critical fixes meeting outlined criteria will be cherry-picked.
  • Developers must ensure these fixes are thoroughly reviewed, tested, and merged by Tuesday EOD PT.

🗓️ Timeline and Milestones

  1. Today (Friday): Begin Release Candidate validation.
  2. Tuesday EOD PT: Finalize RC with all fixes and cherry-picks.
  3. Wednesday: Buffer day for final checks.
  4. Thursday: Submit release to app stores and begin rollout to 1% of users.
  5. Monday: Scale deployment to 10%.
  6. Tuesday: Full rollout to 100%.

✅ Signoff Checklist

Each team is responsible for signing off via GitHub. Use the checkbox below to track signoff completion:

Team sign-off checklist

  • Accounts
  • Assets
  • Bots Team
  • Core Extension UX
  • Core Platform
  • Delegation
  • Design System
  • Extension Platform
  • MetaMask Delivery
  • Money Movement
  • Networks
  • Onboarding
  • Perps
  • Product Safety
  • Social & AI
  • Swaps and Bridge

This process is a major step forward in ensuring release stability and quality. Let’s stay aligned and make this release a success! 🚀

Feel free to reach out if you have questions or need clarification.

Many thanks in advance

Reference

Copilot AI and others added 30 commits July 11, 2026 06:43
…44294)

Fixes: https://github.com/MetaMask/MetaMask-planning/issues/7466
CHANGELOG entry: null

Derived values from multiple `useSelector` calls in the home balance hot
path were recomputed on every render, even when their dependencies
hadn't changed.

### Changes

- **`aggregated-balance.tsx`** — memoize `showNativeTokenAsMain`,
`isNonEvmRatesAvailable`, `formattedFiatDisplay`,
`formattedTokenDisplay`

- **`coin-overview.tsx` (`LegacyAggregatedBalance`)** — memoize
`showNativeTokenAsMain`, `isNotAggregatedFiatBalance`,
`balanceToDisplay`; convert `getCurrencyDisplayType()` inline function
to `useMemo`

- **`coin-overview.tsx` (`CoinOverview`)** — memoize
`isMetaMetricsEnabled`, `shouldShowBalanceEmptyState`; wrap
`handleSensitiveToggle` in `useCallback`

- **`aggregated-percentage-overview.tsx`** — consolidate all derived
display values (`amountChange`, `percentageChange`, formatted strings,
`color`) into a single `useMemo` in both `AggregatedPercentageOverview`
and `AggregatedMultichainPercentageOverview`

- **`aggregated-percentage-overview-cross-chains.tsx`** — wrap
`getPerChainTotalFiat1dAgo` (closes over `crossChainMarketData`) in
`useCallback`; consolidate derived cross-chain display values into a
single `useMemo`

- **`account-group-balance.tsx`** — memoize `caipChainId`, `isEvm`,
`isTestnetSelected`, `showNativeTokenAsMain`

### Example

```tsx
// Before: recomputed on every render
const showNativeTokenAsMain =
  showNativeTokenAsMainBalance && Object.keys(enabledNetworks).length === 1;

// After: only recomputed when deps change
const showNativeTokenAsMain = useMemo(
  () => showNativeTokenAsMainBalance && Object.keys(enabledNetworks).length === 1,
  [showNativeTokenAsMainBalance, enabledNetworks],
);
```

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> <sup>[Cursor Bugbot](https://cursor.com/bugbot) is generating a
summary for commit c8ad878. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: dddddanica <zhaodanica@gmail.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**

This PR completes the **"Sync with mobile"** flow in MetaMask Extension.
After pairing with MetaMask Mobile via QR code, the extension sends the
user's selected wallets and accounts to mobile in a secure, structured
format.

The extension is the **sender**; mobile is the **receiver**.

### What changed

- Built the full **wallet export payload** sent when sync is ready
(`sync-ready` message).
- Users pick which wallets to sync (SRP wallets and imported private-key
accounts only — hardware and Snap wallets are excluded).
- Account names, primary wallet flag, and hidden/pinned states are
included so mobile can restore the same setup.
- Added `QrSyncDataService` to build the export payload from the user's
account selection.
- Wired the Settings UI through to the controller end-to-end.

### Flow by phase

Each step shows what the **user sees (UI)**, what the **extension does
behind the scenes (Controller)**, and what **MetaMask Mobile** does.
They communicate through a secure relay (MWP).

---

#### Phase 1: `idle` → `displaying-qr` — Start pairing

```
User opens "Sync with mobile"
         │
         ▼
┌─────────────┐    create session     ┌──────────────┐
│     UI      │ ───────────────────►  │  Controller  │
│  (QR code)  │ ◄───────────────────  │              │
└─────────────┘    show QR code      └──────┬───────┘
                                              │
                                              │ init-sync-session
                                              ▼
                                       ┌──────────────┐
                                       │    Mobile    │
                                       │  (scans QR)  │
                                       └──────────────┘
```

**What happens:** User opens Settings → Sync with mobile. The extension
creates a session and shows a QR code. Mobile scans it to connect.

---

#### Phase 2: `awaiting-otp-input` — Enter verification code

```
Mobile shows a code          User types code
         │                          │
         ▼                          ▼
┌──────────────┐   submit OTP   ┌──────────────┐
│    Mobile    │ ◄───────────── │  Controller  │
│  (shows OTP) │                │              │
└──────────────┘                └──────┬───────┘
                                       │
                                       ▼
                                ┌─────────────┐
                                │     UI      │
                                │ (code entry)│
                                └─────────────┘
```

**What happens:** Mobile displays a one-time code. The user enters it in
the extension to confirm both devices are paired.

---

#### Phase 3: `awaiting-sync-offer` — Waiting for mobile

```
┌─────────────┐                  ┌──────────────┐
│     UI      │ ◄─────────────── │  Controller  │
│  (loading)  │   "validating…"  │  (validates  │
└─────────────┘                  │   OTP)       │
                                 └──────┬───────┘
                                        │
                          sync-offer    │
                                 ┌──────▼───────┐
                                 │    Mobile    │
                                 │ "ready sync" │
                                 └──────────────┘
```

**What happens:** The extension validates the code and shows a loading
screen. Mobile confirms it is ready to receive wallets.

---

#### Phase 4: `reviewing-sync-offer` — Choose wallets & enter password

```
┌─────────────┐  pick wallets +   ┌──────────────┐
│     UI      │  enter password   │  Controller  │
│ (wallet list│ ────────────────► │ (stores      │
│ + password) │                   │  selection)  │
└─────────────┘                   └──────────────┘
```

**What happens:** The user enters their MetaMask password and selects
which wallets to sync. Only syncable wallets are shown (SRP and imported
accounts). Hardware and Snap wallets are hidden.

---

#### Phase 5: `awaiting-sync-completion` — Sending wallets to mobile

```
┌─────────────┐                  ┌──────────────┐
│     UI      │ ◄─────────────── │  Controller  │
│  (loading)  │   "syncing…"     │  builds +    │
└─────────────┘                  │  encrypts    │
                                 │  wallet data │
                                 └──────┬───────┘
                                        │
                          sync-ready    │  (encrypted wallet data)
                                 ┌──────▼───────┐
                                 │    Mobile    │
                                 │  (imports)   │
                                 └──────────────┘
```

**What happens:** The extension packages the selected wallets
(encrypted), sends them to mobile, and shows a loading screen while
mobile imports.

---

#### Phase 6: `completed` — Done

```
                                 ┌──────────────┐
                                 │  Controller  │
                                 │  (marks done)│
                                 └──────┬───────┘
                          sync-completed│
                                 ┌──────▼───────┐
                                 │    Mobile    │
                                 │  (finished)  │
                                 └──────────────┘
                                        │
                                        ▼
                                 ┌─────────────┐
                                 │     UI      │
                                 │  (success)  │
                                 └─────────────┘
```

**What happens:** Mobile confirms import is complete. The extension
shows a success screen with how many wallets and accounts were synced.

---

#### Error / cancel paths: `failed` or `cancelled`

If something goes wrong (wrong code, timeout, user cancels, mobile
disconnects), the flow stops and the user is returned to the home
screen. No wallet data is sent unless sync reaches the `sync-ready` step
successfully.

---

### Updated `sync-ready` payload schema (`QrSyncReadyData`)

When the extension is ready to sync, it sends a `sync-ready` message.
The wallet data lives in the `data` field as a list of wallet entries:

```json
{
  "type": "sync-ready",
  "version": "1.0.0",
  "deadline": 1700000060000,
  "data": [
    {
      "type": "Mnemonic",
      "mnemonic": "<base64-encoded recovery phrase>",
      "name": "Wallet 1",
      "isPrimary": true,
      "groups": [
        { "groupIndex": 0, "name": "Account 1", "pinned": true },
        { "groupIndex": 2, "name": "Hidden Account", "hidden": true }
      ]
    },
    {
      "type": "PrivateKey",
      "privateKey": "<base64-encoded private key>",
      "name": "Imported Account"
    }
  ]
}
```

**Field notes:**

| Field | Meaning |
|---|---|
| `type: "Mnemonic"` | A Secret Recovery Phrase (SRP) wallet |
| `type: "PrivateKey"` | A single imported account |
| `mnemonic` / `privateKey` | Encoded secrets (not plain text) |
| `name` | Wallet or account display name |
| `isPrimary` | Marks the main SRP wallet (only one) |
| `groups` | Which accounts from that SRP wallet to restore |
| `groupIndex` | Account position in the wallet (Account 1 = 0) |
| `hidden` / `pinned` | UI state — only included when `true` |
| `deadline` | Time limit for mobile to accept the data |

## **Changelog**

CHANGELOG entry: Added the ability to sync selected wallets and accounts
from the extension to MetaMask Mobile via QR code pairing in Settings.

## **Related issues**

Fixes:

## **Manual testing steps**

1. Set `ADD_DEVICE_SYNC_ENABLED=true` in `.metamaskrc` and rebuild the
extension.
2. Load the extension and go to **Settings → Sync with mobile**.
3. On MetaMask Mobile, start the sync flow and scan the QR code shown in
the extension.
4. Enter the verification code from mobile into the extension.
5. Wait for the wallet selection screen to appear.
6. Enter your MetaMask password and select one or more wallets (SRP
and/or imported accounts).
7. Tap **Continue** and confirm the loading screen appears, then the
success screen.
8. On mobile, verify the imported accounts match the names and count you
selected in the extension.
9. Repeat with multiple wallets and confirm only syncable wallets appear
(no Ledger/Trezor/Snap wallets in the list).
10. Test cancellation: close the flow mid-way and confirm you return to
the home screen without errors.

## **Screenshots/Recordings**

### **Before**

N/A — new feature behind `ADD_DEVICE_SYNC_ENABLED` flag.

### **After**

<!-- Add screenshots/recordings of: QR screen, OTP entry, wallet picker,
loading, and success screen -->

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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]
> **High Risk**
> Changes how mnemonics and private keys are exported and encoded for
mobile sync, which is security-critical and contract-sensitive for the
MWP payload.
> 
> **Overview**
> Completes the extension **Sync with mobile** export path by moving
secret packaging into a new **`QrSyncDataService`** and driving
selection by **account group IDs** instead of entropy IDs.
> 
> **`syncAccounts`** now calls
`QrSyncDataService:buildWalletExportEntries` and sends a revised
**`sync-ready`** envelope: `deadline` at the message level and `data` as
`Mnemonic` / `PrivateKey` entries with wallet names, `isPrimary`, and
per-account `groups` metadata (names, hidden/pinned). Controller state
tracks **`qrSyncSelectedAccountGroupIds`** and drops the old
selected/imported account ID fields.
> 
> The Settings **add-device** flow passes **`selectedAccountGroupIds`**
through to the background, filters the picker to syncable wallets (SRP,
HD keyring, imported private key), and uses **whole-wallet** checkboxes
only. QR sync timeouts are split into **`QR_SYNC_TIMEOUT_MS`**
(offer/completion/MWP session).
> 
> Messenger init registers **`QrSyncDataService`**; the QR sync
controller messenger delegates export to the data service, which talks
to account tree and keyring actions.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
bbf9796. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Ganesh Suresh Patra <ganesh.patra@consensys.net>
Co-authored-by: Lionell Briones <llenoil@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: MetaMask Bot <metamaskbot@users.noreply.github.com>
## **Description**

During custom mUSD convert, pending child transactions are created
alongside the parent “Converting to mUSD” row.

This PR hides these internal transactions, so only the top-level convert
row shows while the flow is pending.

## **Changelog**

CHANGELOG entry: Fixed extra pending row during mUSD conversion flow

## **Related issues**

Fixes:
https://consensyssoftware.atlassian.net/browse/CEUX-1170

## **Manual testing steps**

1. Open the extension Activity list (redesign).
2. Start a custom convert to mUSD flow and leave it pending/signing.
3. Confirm only one row appears: “Converting to mUSD” (no “Interaction
in progress” / “With USDC” sibling).
4. Confirm the convert details Summary still shows the internal
send/receive steps as before.

## **Screenshots/Recordings**

### **Before**
<img width="259" height="202" alt="image"
src="https://github.com/user-attachments/assets/97616dd9-0916-48fb-b8a9-f94bb8ab5999"
/>


### **After**

<img width="222" height="147" alt="image"
src="https://github.com/user-attachments/assets/1f24906b-7d5d-4e80-8a50-19ccda333475"
/>

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/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**
> Activity-list filtering only; convert details still use
required-transaction data elsewhere. Low risk of hiding unrelated txs
unless they are linked via `requiredTransactionIds`.
> 
> **Overview**
> Fixes duplicate pending rows during **mUSD convert** by treating
required child transactions as internal-only in the Activity list.
> 
> **`selectLocalTransactions`** now drops entries whose **id** or
**hash** appears in the parent’s `requiredTransactionIds` set (not just
hash), so unsigned/pending relay steps no longer show as separate rows
while the parent “Converting to mUSD” row is still pending. The same
internal-required filter is applied to **smart transactions**, including
type exclusions via `EXCLUDED_TRANSACTION_TYPES`.
> 
> **`musdRelayDeposit`** is added to `EXCLUDED_TRANSACTION_TYPES` so
relay deposit steps stay out of unified lists. Minor JSDoc was added for
`smartTransactionsListSelector`.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
0fd16c1. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
<!--
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**

Jira Link: https://consensyssoftware.atlassian.net/browse/TO-874

Renames the QR account-sync feature from "Add device" to "Sync accounts"
and promotes it from a nested settings sub-tab to a standalone top-level
`/sync-accounts` route with its own full-page layout and back button.
This is a naming/relocation refactor built on top of
`feat/qr-sync-controller`; no sync behavior changes.

## Changes
- **Routing**
- Replaced `ADD_DEVICE_ROUTE` (`/settings/add-device`) with top-level
`SYNC_ACCOUNTS_ROUTE` (`/sync-accounts`).
- Registered the new lazy-loaded `SyncAccounts` route in
`routes.component.tsx`, still gated behind
`getIsAddDeviceSyncEnabled()`.
- Hid the app header on the sync-accounts page via `hideAppHeader` in
`routes/utils.js`.
- **Page/component rename** — moved `ui/pages/settings/add-device-tab/`
→ `ui/pages/settings/sync-accounts/`, renaming `AddDeviceSettings` →
`SyncAccountsSettings`, `AddDeviceSettingsStep` → `SyncAccountsStep`,
and related types.
- **New `SyncAccountsTab`** — full-page `Page`/`Header`/`Content`
wrapper with a back button that resets the controller state
(`QrSyncController:resetState`) and navigates to `DEFAULT_ROUTE`.
- **Settings registry & search** — updated `settings-registry.ts` and
`search-config.ts` to point at the new route/labels (`addDevice` →
`syncAccounts`, `ADD_DEVICE_ITEMS` → `SYNC_ACCOUNTS_ITEMS`).
- **Localization** — renamed the `addDevice` message key to
`syncAccounts` ("Sync with mobile") in `en` and `en_GB`.
- **Tests** — added `sync-accounts-tab.test.tsx` (renders settings +
back button) and renamed/updated existing settings and component tests
to match new names.

<!--
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: Moved account-sync flow from settings sub-page to top
level route.

## **Related issues**

Fixes:

## **Manual testing steps**

1. Go to Menu > Settings > "Sync with mobile"
2. Click on the navigation link
3. Should redirect outside settings to a `/sync-accounts`
4. Back button should redirect back to settings page

## **Screenshots/Recordings**

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

### **Before**

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

### **After**


https://github.com/user-attachments/assets/d5a39fe1-bbf3-4d93-a8b6-42af54e5aa90


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

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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**
> Routing and naming refactor only; QR sync logic is unchanged and
remains feature-flagged.
> 
> **Overview**
> Renames the QR mobile account-sync feature from **Add device** to
**Sync accounts** and moves it off the nested settings path to a
standalone **`/sync-accounts`** route, still behind
`getIsAddDeviceSyncEnabled()`.
> 
> The former `add-device-tab` module becomes **`sync-accounts`**
(`SyncAccountsSettings`, `SyncAccountsStep`, etc.). A new
**`SyncAccountsTab`** wraps the flow in a full-page layout with a back
control that calls `QrSyncController:resetState` and returns to
**Settings**. Settings registry gains an **`externalRoute`** flag so
this tab stays in the settings menu but is mounted by the app router
(not the nested `/settings/*` router), with **`hideAppHeader`** updated
for the new path.
> 
> i18n drops **`addDevice`** across locales and adds **`syncAccounts`**
(“Sync with mobile”) in English locales; search/registry keys follow the
rename. Tests and Jest console baselines are updated for the new paths
and names—no sync controller behavior changes in this diff.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
562fd60. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Ganesh Suresh Patra <ganesh.patra@consensys.net>
Co-authored-by: lwin <lwin.kyaw@consensys.net>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: MetaMask Bot <metamaskbot@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**
Adds structured error handling and error UI to the QR account-sync flow.
Instead of silently exiting when a sync session reaches a terminal
state, the flow now surfaces a dedicated error screen with retry/cancel,
and routes recoverable errors (expired QR, expired OTP, too many OTP
attempts) back to the relevant step so the user can recover in place.

## Changes

- **Error codes & routing** (`shared/constants/qr-sync.ts`)
- Added `QR_EXPIRED` and `OTP_ATTEMPTS_EXCEEDED` error codes and a
`QrSyncErrorCode` type.
- Added `QR_SYNC_ERROR_PHASE_OVERRIDES`, mapping certain error codes to
the step that should render: `QR_EXPIRED` -> QR scan,
`OTP_EXPIRED`/`OTP_ATTEMPTS_EXCEEDED` -> OTP input.
- **Controller error resolution** (`app/scripts/controllers/qr-sync/`)
- Refactored `#setError` to accept `{ error, code, message }` and
resolve the final code from the raw error via a new detector registry,
falling back to the provided code/message.
- Added `utils.ts` helpers: `MWP_REQUEST_EXPIRED_CODE`,
`isQrExpiredError`, `QR_SYNC_ERROR_DETECTORS`, and
`resolveQrSyncErrorCode` (maps the MWP `REQUEST_EXPIRED` error to
`QR_EXPIRED`).
- Added controller and utils unit tests for the expired-handshake paths.
- **Sync flow orchestration** (`sync-accounts-settings.tsx`)
- Replaced the auto-exit-on-terminal-phase effect with a rendered
`SyncError` screen for `CANCELLED`/`FAILED`.
- `renderStep` now derives an `effectivePhase` from the override map,
and a shared `handleRetry` resets controller state.
- **New `SyncError` component** — danger icon, title,
error-code-specific message (with a generic fallback), and Try again /
Cancel actions; exported from the components barrel.
- **`EnterVerificationCode`** — now driven by an `onRestart` prop
(parent resets the session instead of the component calling
`createSession`), reads `qrSyncError`, shows OTP-expired and
max-attempts messages, disables inputs and hides the countdown when
attempts are exhausted, and consolidates error text into a single
`errorMessage`.
- **`QrCodeScan`** — retains the last QR payload so an expired QR stays
visible instead of collapsing to a skeleton, and applies dim + blur on
expiry; removed the controller-error dimming/scan-error message path.
- **i18n** (`en`, `en_GB`) — added `add_device_error_*` strings,
`add_device_try_again`, and `enter_verification_code_max_attempts`;
removed the now-unused `qrCodeScanError`.
- **Tests** — new `sync-error.test.tsx`; updated
`enter-verification-code.test.tsx` (Redux provider + max-attempts case),
`qr-code-scan.test.tsx` (payload retention), and
`sync-accounts-settings.test.tsx` (override routing + retry/cancel).


<!--
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: QR Sync flow should now show step specific error and
global errors on a dedicated error view

## **Related issues**

Fixes:

## **Manual testing steps**

1. Go to Menu > Settings > "Sync with mobile"
2. Should redirect to QR Sync flow
3. Test QR sync expiry. Wait until QR expires
4. Restart Flow
5. Complete the QR Scan flow
6. Should show "OTP verification view"
7. Test OTP expiry. Wait until OTP expires
8. Should show OTP error.

Please refer to screenshot for the global error. 
Some known incomplete flows/behavior are not implemented here, but
another PR for controllers.
- There is a controller error on reset after QR Expiration, so it does
not show yet on QR scan page.
- OT Expiry is not handled on controller side yet so, resetting the QR
Sync after this error does not work properly yet
- Only UI for max OTP attempt error is added, not controller handling
yet.

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

QR Expired
<img width="608" height="933" alt="Screenshot 2026-07-07 at 9 32 11 PM"
src="https://github.com/user-attachments/assets/38ee10e9-e030-4080-8d7d-2f6abcf6e431"
/>


OTP Expired
<img width="611" height="931" alt="Screenshot 2026-07-07 at 9 33 37 PM"
src="https://github.com/user-attachments/assets/4af56756-d5eb-4c53-8f02-a3b062c4a637"
/>


Global Account Sync Error
<img width="613" height="934" alt="Screenshot 2026-07-07 at 9 27 07 PM"
src="https://github.com/user-attachments/assets/7f7d7441-3768-435a-9713-b62a844df98c"
/>



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

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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 account-sync UX and controller error classification for wallet
pairing; mistakes could mis-route users or mishandle expired sessions,
but changes are mostly UI and error mapping with tests.
> 
> **Overview**
> Replaces **auto-exit on terminal QR sync phases** with in-flow error
handling: a new **`SyncError`** screen (Try again / Cancel) for
`CANCELLED`/`FAILED`, and **`QR_SYNC_ERROR_PHASE_OVERRIDES`** so
recoverable codes (`QR_EXPIRED`, `OTP_EXPIRED`, `OTP_ATTEMPTS_EXCEEDED`)
still render the QR or OTP step instead of the generic error view.
> 
> **`QrSyncController`** now resolves error codes via
**`resolveQrSyncErrorCode`** / **`isQrExpiredError`**, mapping MWP
**`REQUEST_EXPIRED`** to **`QR_EXPIRED`**. **`EnterVerificationCode`**
uses parent **`onRestart`**, Redux **`qrSyncError`**, and max-attempts
messaging; **`QrCodeScan`** keeps the last QR visible on expiry
(dim/blur) and drops the old scan-error path. English i18n adds
**`add_device_error_*`** strings and removes **`qrCodeScanError`**.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
08ff1c2. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Ganesh Suresh Patra <ganesh.patra@consensys.net>
Co-authored-by: lwin <lwin.kyaw@consensys.net>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: MetaMask Bot <metamaskbot@users.noreply.github.com>
Use CAIP-19 paths for fungible asset navigation and deep links, resolve
wallet and metadata-backed tokens on the asset page, and harden route
building against invalid ids and malformed URL params.

<!--
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:  migrate asset routes to CAIP-19 identifiers

## **Related issues**

Fixes:

## **Manual testing steps**

Try visiting tokens that you have networks you have connected, and
chains you don't have connected.
This should allow users to now visit assets they do not own (but have
network for). Defaults to home screen if a user does not have a valid
network.

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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



https://github.com/user-attachments/assets/32d4caf9-61ff-4f11-96af-bfb92e2ac05b



## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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 core navigation, deep-link interstitial policy for unsigned
asset URLs, and external token metadata fetching; mis-routing or bypass
behavior would be user-visible across chains.
> 
> **Overview**
> Fungible asset URLs move from hex chain id + contract address to
**CAIP-19** paths (`/asset/{caip-chain}/{encoded-asset-id}`), with
shared helpers in `shared/lib/asset-route` for building paths, decoding
route params (including Chrome vs Firefox fragment behavior), and
normalizing lookups for EVM, Solana, Tron, and NFT-style routes.
> 
> **Deep links and in-app navigation** now generate and expect those
paths (`buildAssetRoutePath`), including the `/asset?assetId=…` handler.
**`/asset` is added to the deep-link interstitial bypass list** so
unsigned asset links open directly, aligned with mobile; deferred
deep-link handling is covered by tests.
> 
> The **asset details page** resolves holdings via
`getFungibleAssetForRoute` and, when the user does not own the token,
loads display metadata through `buildTokenFromCaipAssetId` /
`useRouteAssetToken` (with loading and redirect-on-failure). Token list,
bridge flows, and e2e bridge navigation are updated to pass and wait on
CAIP-19 routes.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
cbcf34b. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
#44383)

The google.svg file was removed in #44227 as part of a legacy icon
cleanup. However, it is still actively referenced by the onboarding
login options and reveal-SRP list flows.

- Restore the original Google brand icon SVG
- Move it from app/images/icons/ to app/images/ to keep it separate from
the legacy icon set that is being deprecated
- Update all src references in login-options.tsx and reveal-srp-list.tsx

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

JIRA LINK : https://consensyssoftware.atlassian.net/browse/TO-896

## **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: restore google.svg and relocate to app/images/

## **Related issues**

Fixes:
- #44334
- #44340

## **Manual testing steps**

1. Go to this page...
2.
3.

## **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="1333" height="991" alt="Screenshot 2026-07-13 at 12 33
06 PM"
src="https://github.com/user-attachments/assets/ad9b782b-fc83-4185-9045-2382ae424048"
/>

<img width="1287" height="990" alt="Screenshot 2026-07-13 at 12 40
53 PM"
src="https://github.com/user-attachments/assets/13f821f4-93d7-40a2-8de9-5267cfc16965"
/>


## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/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]
> **Low Risk**
> Static asset and path-only UI updates with no auth, data, or
business-logic changes.
> 
> **Overview**
> Restores the **Google brand icon** that was removed during legacy icon
cleanup but is still required for onboarding and account flows.
> 
> Adds `app/images/google.svg` (outside the deprecated `icons/` tree)
and updates image `src` paths in **login-options** and
**reveal-srp-list** from `images/icons/google.svg` to
`images/google.svg` so the Google login button and SRP reveal list show
the icon again.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
574bb38. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description**

This PR wires the `'tron'` case into `withFixtures` and adds a smoke
script so a Tron local node can be started and consumed from a test
fixture. It is one reviewable step of a linear stack and replaces
#44139. Together with PRs 03-05 it supersedes #43722. Based on a fresh
`main` and under 1000 changed lines.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Part of the local-blockchain E2E initiative (WPN-536).
Replaces #44139; together with the preceding Tron node PRs (config,
seeder, bootstrap) supersedes #43722.

## **Manual testing steps**

1. `yarn build:test`
2. Run the Tron fixtures smoke script and confirm the `'tron'` fixture
case boots a local node and tears it down cleanly.

## **Screenshots/Recordings**

N/A — test infrastructure only, no user-facing UI change.

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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**
> Test-only fixture and smoke tooling; the Anvil guard is a small
behavioral fix for mixed local-node fixtures.
> 
> **Overview**
> E2E fixtures can now boot a **Tron** local node via `localNodeOptions:
'tron'` (or `{ type: 'tron', options: ... }`), using the existing
`TronNode` seeder alongside the Anvil path.
> 
> **Accounts API v5** native-balance sync from `localNodes[0]` is
limited to **Anvil** only, so a Tron-first fixture no longer calls
`getBalance()` on a non-EVM node.
> 
> A new **`test:e2e:smoke:local-node-ports`** script starts two
java-tron networks on spaced ports, hits `getnowblock`, and tears
down—sanity check for port allocation and multi-node startup.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
c91ac63. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Fixes: https://github.com/MetaMask/MetaMask-planning/issues/7467
CHANGELOG entry: null

Confirmation-flow hooks and components were creating new object
references and inline selector lambdas on every render, causing
unnecessary downstream re-renders and Redux re-subscriptions.

## Changes

### `useGasFeeToken.ts`
- Replace inline `(state) => selectTransactionAvailableBalance(state,
id, chainId)` lambda with a `useMemo`-created stable selector
- Wrap `useNativeGasFeeToken` and `useGasFeeToken` return objects in
`useMemo`; extract `transferTransaction` into its own `useMemo`

### `smart-transactions-banner-alert.tsx`
- Hoist `alertEnabled` inline typed selector lambda to a stable
`selectAlertEnabled` function outside the component
- Convert `getMarginStyle()` (called at render time) to a
`useMemo`-computed `marginStyle` value

### `transaction-details-account-row.tsx`
- Extract parameter-free selectors (`selectAccountGroupId`,
`selectFirstAccountGroupName`) as stable module-level functions
- Replace two parameter-dependent inline selector lambdas with
`useMemo`-created selectors keyed on `from` and `selectedAccountGroupId`
respectively
- Wrap `displayName` derivation in `useMemo`

```ts
// Before — new function reference every render
const balance = useSelector((state) =>
  selectTransactionAvailableBalance(state, transactionId, chainId),
);

// After — stable reference; recreated only when deps change
const selectBalance = useMemo(
  () => (state: unknown) =>
    selectTransactionAvailableBalance(state, transactionId, chainId),
  [transactionId, chainId],
);
const balance = useSelector(selectBalance);
```


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Render/identity optimizations only; displayed account names, gas fee
tokens, and banner visibility logic are unchanged.
> 
> **Overview**
> Reduces unnecessary re-renders in the confirmation flow by stabilizing
Redux subscriptions and object identities.
> 
> **`useGasFeeToken.ts`** — Parameterized `useSelector` callbacks are
built with `useMemo` (e.g. balance by `transactionId`/`chainId`).
`transferTransaction` and the objects returned from `useGasFeeToken` /
`useNativeGasFeeToken` are wrapped in `useMemo` so consumers do not see
new references every render.
> 
> **`transaction-details-account-row.tsx`** — Stateless selectors
(`selectAccountGroupId`, `selectFirstAccountGroupName`) and
`getMultichainAccountsState` move to module scope. Selectors that depend
on `from` or `selectedAccountGroupId` use `useMemo`; `displayName` is
memoized from the resolved names.
> 
> **`smart-transactions-banner-alert.tsx`** — The smart-transactions
migration alert enabledness check is hoisted to a stable
`selectAlertEnabled` used with `useSelector` instead of an inline
lambda.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
3de6688. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: dddddanica <zhaodanica@gmail.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**

Bump Snaps packages to enable `Blob` global in the execution
environment.

## **Changelog**

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

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

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

CHANGELOG entry: Add support for `Blob` global in Snaps

## **Related issues**

https://consensyssoftware.atlassian.net/browse/WPC-1126

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes the isolated iframe where all Snaps run and bumps core Snaps
libraries, so regressions could affect every installed snap; scope is
limited to a coordinated version bump with no extension app logic
changes.
> 
> **Overview**
> Bumps Snaps platform dependencies so the extension loads the
**11.2.0** hosted iframe execution environment instead of **11.1.1**,
aligning runtime with the new package versions.
> 
> **`package.json`** updates `@metamask/snaps-execution-environments` to
`^11.2.0` and `@metamask/snaps-utils` to `^12.4.0`; **`yarn.lock`**
reflects the resolved tree (including transitive bumps on
snaps-sdk/superstruct inside execution-environments). **`builds.yml`**
sets `IFRAME_EXECUTION_ENVIRONMENT_URL` to
`https://execution.metamask.io/iframe/11.2.0/index.html` for **main**,
**beta**, **experimental**, and **flask** so each build type points at
the matching remote iframe.
> 
> Per the PR description, this enables the **`Blob` global** inside the
Snaps execution environment for snaps that rely on it.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
c334097. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
… comparison (#44400)

## **Description**

`trackImportEvent` was not being used properly in failure scenarios and
it's string comparison against strategy type was wrong.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: N/A

## **Manual testing steps**

1. Run tests
2. Confirm they pass

## **Screenshots/Recordings**

N/A

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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]
> **Low Risk**
> Analytics-only fix in the import account UI with no auth or import
logic changes beyond event payloads.
> 
> **Overview**
> Fixes **MetaMetrics** tracking when account import fails in
`import-account.js`. On catch, `trackImportEvent` now receives
**`false`** instead of the error message string, so failures emit
**`AccountAddFailed`** instead of being misclassified as success.
> 
> **`trackImportEvent`** now compares `strategy` to **`'privateKey'`**
(not `'Private Key'`), matching the values passed from the import flow,
so **`account_import_type`** is **`PrivateKey`** vs **Json** on
failures.
> 
> Tests inject a mock **`trackEvent`** and assert failed private-key and
JSON imports fire **`AccountAddFailed`** with the expected
**`account_import_type`** and related properties.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
a65c69d. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…#44386)

<!--
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 Cursor Skill to automatically add new EVM networks to swaps

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

## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/SWAPS-4775

## **Manual testing steps**

1. Go to this page...
2.
3.

## **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
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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**
> Documentation-only; no product code, auth, or data-path changes.
> 
> **Overview**
> Adds **agent-facing documentation** for onboarding new **EVM** chains
into the **unified swaps/bridge** flow, mirroring the existing non-EVM
standard pattern.
> 
> **`docs/add-evm-swaps-bridge-network.md`** is the SSOT: prerequisites
(`network.ts`, `@metamask/bridge-controller`), the two-layer allowlist
(hard list + `bridgeConfigV2.chainRanking`), step-by-step edits
(`shared/constants/bridge.ts`, `ui/pages/bridge/utils/stablecoins.ts`,
LaunchDarkly `bridgeConfigV2`), optional popular-network enablement,
validation checklist, and targeted unit tests (`selectors.test.ts`,
`useSmartSlippage.test.ts`). Reference PRs called out are MegaETH and
Robinhood Chain.
> 
> **`AGENTS.md`** gains an **EVM Swaps/Bridge Agent Entrypoints**
section linking that doc and the Cursor skill at
`.cursor/skills/mms-add-evm-swaps-bridge-network/SKILL.md`.
> 
> No runtime bridge or swaps code changes in this diff—documentation and
discoverability for agents only.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
dfb93f5. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Removes the headless `smartTransaction:showSmartTransactionStatusPage`
approval mechanism. The approval was created inside
`submitSmartTransactionHook`/`submitBatchSmartTransactionHook` and
immediately resolved by a UI-side shim with no more UI consuming it
after removing the post STX page.

Removed:
- Approval request creation, update, and end-flow in
`smart-transactions.ts`
- `useResolveSmartTransactionApprovals` 
- STX filter in `selectPendingApprovalsForNavigation`
- STX exclusion in `getAttentionRequiredApprovalCount`
- STX rate-limit exemption in `getApprovalControllerInstanceOptions`
- STX pending-approval rejection loop in `resetAccount` (there is no
matching approval to reject)
- Now-unused constants


## **Changelog**

CHANGELOG entry: null

## **Related issues**

<!--
Fixes:
-->

## **Manual testing steps**

1. Submit a smart transaction
2. Verify the transaction submits, completes, and the existing toast
lifecycle still fires

<!--
## **Screenshots/Recordings**

### **Before**

### **After**
-->

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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 smart transaction submit hooks and approval/navigation
behavior; incorrect removal could affect badges or toasts, though
transaction toasts remain on `useTransactionEventToasts`.
> 
> **Overview**
> Removes the headless
**`smartTransaction:showSmartTransactionStatusPage`** approval path that
was created during smart transaction submit and auto-resolved in the UI
with no confirmation screen.
> 
> **`SmartTransactionHook`** no longer calls
`ApprovalController:addRequest` / `updateRequestState`, drops
`shouldShowStatusPage` and transaction-type gating for that flow, and
the hook messenger no longer depends on approval actions. Submit/batch
still wait for hashes via **`SmartTransactionsController`** events.
> 
> Related cleanup: **`SMART_TRANSACTION_CONFIRMATION_TYPES`** and UI
helpers (`useResolveSmartTransactionApprovals`,
`useSmartTransactionToasts`, `selectSmartTransactions`, toast type
exclusions) are deleted. **`getAttentionRequiredApprovalCount`** counts
all pending approvals; navigation no longer filters STX status approvals
or the skip feature flag. **`resetAccount`** no longer rejects matching
STX pending approvals; approval rate-limit exclusions and tests are
updated accordingly.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
f6ded04. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
## **Description**

Migrates remaining legacy `MetaMetricsContext.trackEvent` /
`trackMetaMetricsEvent` call sites in the **Web3Auth (recovery phrase,
passkey, consent, password)** domain to `useAnalytics()` +
`createEventBuilder` (or `trackAnalyticsEvent` for Redux thunks).

Part of umbrella tracker #43885 (**15d · Web3Auth onboarding gaps**).

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

1. Build and load the extension (`yarn start`).
2. Exercise the flows touched by this PR (see changed files).
3. With MetaMetrics debug enabled, confirm events still fire with the
same names and properties.

<!--
## **Screenshots/Recordings**
### **Before**
### **After**
-->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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**
> Analytics instrumentation refactor only; no changes to wallet, auth,
or password/passkey business logic beyond how events are emitted.
> 
> **Overview**
> Replaces remaining **`MetaMetricsContext`** `trackEvent` usage in
Web3Auth-related UI (basic functionality modal, change password,
marketing consent, passkey troubleshoot, reveal SRP) with
**`useAnalytics()`** and **`createEventBuilder().build()`**, keeping the
same event names and properties.
> 
> **Passkey troubleshoot** now pulls **page title** for support-link
events from **`useSegmentContext`** instead of the legacy
second-argument context merge.
> 
> Tests for **reveal recovery phrase** (and related setup) mock
**`useAnalytics`** and assert **`trackEvent`** receives the built
payload shape (`name`, `properties`, `sensitiveProperties`) on SRP
export success and failure paths.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
47b7b93. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
<!--
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?
-->

Move status-icon so we can restore the "ui/icon" path in the list

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

1. Go to this page...
2.
3.

## **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
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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**
> Import-path and lint-rule changes only; no behavior change to
StatusIcon, toast, or activity UI beyond module location.
> 
> **Overview**
> **Moves `StatusIcon` out of the deprecated `ui/icon` tree** into
`ui/status-icon/status-icon`, and updates imports in toast, pending
activity rows, and the toast unit test mock to match.
> 
> **Re-enables the fitness rule** that treats `ui/icon` as a blocked
import path in `prevent-deprecated-imports.ts` (it had been commented
out while `status-icon` still lived under `ui/icon`).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
ecb7db9. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…#44408)

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

Change `CODEOWNERS` to bring outstanding `ramps` code under [team
money-movement](https://github.com/orgs/MetaMask/teams/money-movement)

<!--
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:
[TRAM-3745](https://consensyssoftware.atlassian.net/browse/TRAM-3745)


## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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.


[TRAM-3745]:
https://consensyssoftware.atlassian.net/browse/TRAM-3745?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Repository governance only; no runtime or product behavior changes.
> 
> **Overview**
> Expands **Money Movement** ownership in `.github/CODEOWNERS` so more
ramps-related paths require `@MetaMask/money-movement` review, alongside
the existing `**/ramps/**` rule.
> 
> Adds explicit patterns for `ui/hooks/ramps/`,
`ui/selectors/rampsController/`,
`ui/store/controller-actions/ramps-controller*`,
`app/scripts/messenger-client-init/ramps-*` and `messengers/ramps-*`,
and `test/e2e/tests/btc/mocks/ramps.ts`.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
c0d234c. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
Upgrades React and React DOM from v17 to v18 and cleans up related
legacy patterns across the extension.

- Bump `react` and `react-dom` from `^17.0.2` to `^18.2.0`
- Remove the React 17 webpack `react/jsx-runtime` alias workaround in
`development/webpack/webpack.config.ts`
- Update LavaMoat policies for the dependency change
- Remove `LegacyRouteMessengerProvider` and update `routes/test` helpers
to use context-based providers
- Replace deprecated defaultProps on function components with default
parameters (UI components, `test/storybook` I18nProvider copies)
- Fix async test patterns (`useCarouselManagement`, integration alerts,
etc.)
- Refactor `@rive-app/react-canvas` jest mock

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

## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

Fixes: MetaMask/MetaMask-planning#6925

## **Manual testing steps**

1. Go to this page...
2.
3.

## **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
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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]
> **High Risk**
> A core UI runtime upgrade touches the entire extension surface;
regressions would affect rendering, concurrency, and user flows even
though most code changes are tests and build policy.
> 
> **Overview**
> Upgrades **`react`** and **`react-dom`** from v17 to **v18.2.0**,
which drives the rest of the diff: build, supply-chain policy, and test
harness updates so CI and E2E stay stable under React 18’s rendering and
async behavior.
> 
> **Build & LavaMoat:** Drops the webpack **`react/jsx-runtime`** alias
that only existed for React 17 ESM resolution. Regenerates LavaMoat
policies so **`react`**, **`react-dom`**, and **`scheduler`** match the
new package graph (e.g. **`object-assign`** paths, scheduler
globals/packages).
> 
> **Tests & tooling:** Integration setup mocks **Rive** `RuntimeLoader`
so `act()` does not hang in jsdom; several notification/confirmation
integration tests stop wrapping everything in **`act()`** and rely on
**`waitFor`/`findBy`**. E2E helpers handle stale DOM nodes, drawer
motion, send-alert modals, and notification flows. Unit/UI fixes include
**`CheckBox`** **`aria-checked`**, **`useCountdownTimer`** functional
updates, lighter **`useTokenSearchResults`** tests, and refreshed Jest
console/snapshot baselines.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
421b31f. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: MetaMask Bot <metamaskbot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…44373)

## **Description**

The `enableMV3TimestampSave` debug preference is obsolete now that MV3
keep-alive runs unconditionally from service worker startup (see
[comment](#44348 (comment))).
This PR removes the preference from controller state, UI, and persisted
fixtures, and adds migration 217 to drop the field from existing
profiles.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:

Related: #44348
Related: #43773

## **Manual testing steps**

1. Run `yarn start` and load the extension in Chrome.
2. Open **Settings → Advanced → Developer options** and confirm the
**Service worker keep-alive** toggle is no longer shown.
3. Unlock MetaMask and confirm normal background behavior is unchanged.
4. (Optional) Upgrade from a profile that had `enableMV3TimestampSave:
false` and confirm migration 217 removes the field without errors.

<!--
## **Screenshots/Recordings**

### **Before**

### **After**
-->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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.

Made with [Cursor](https://cursor.com)

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description**

### Context

Fixes
[#44068](#44068) —
an intermittent E2E failure in `reset-wallet.spec.ts` during the
**second** onboarding pass after wallet reset. The failure surfaces as:

```
OnboardingFlow: failed to create new account Error: Keyring not found
Error creating password Error: Keyring not found
```

`Keyring not found` is thrown from
`KeyringController.exportSeedPhrase()` when the HD keyring has been
cleared from memory mid-export (`keyrings[0]?.keyring` is falsy). On the
create-wallet path this happens via `createNewVaultAndGetSeedPhrase` →
`getSeedPhrase` → `exportSeedPhrase`.

### Root cause (confirmed)

This was **reproduced locally** with the same error signature as CI.

MetaMask can have **multiple UI surfaces** open at once (main window +
side panel). They share one background, but each has its **own Redux
store**.

On second-pass onboarding password submit, the main window:

1. `createNewVault` — creates the vault and unlocks it
2. `getSeedPhrase` — exports the recovery phrase

Previously these were **two separate background RPCs** with
`createVaultMutex` released between them. Meanwhile, a **stale side
panel** (left open after first onboarding) could react to `isUnlocked:
true` while onboarding was still incomplete. Its routing reaches the
onboarding **lock trap** (`OnboardingFlowSwitch` → `LOCK_ROUTE` →
`setLocked`), which clears in-memory keyrings **during** step 2 →
`Keyring not found`.

**Why it flakes in CI / reset-wallet E2E:** The spec runs reset and
second onboarding back-to-back with no human delay. The side panel can
lag on `/unlock` or `/` while the main window races ahead to password
submit. The dangerous window also exists in production whenever crypto
work widens the gap between create and export, or when any new surface
boots at `/` during export.

**In short:** the main window exports the seed phrase while another
surface locks the wallet.

### Fix

**1. Background — atomic vault + export under one mutex**

- Added `createNewVaultAndGetSeedPhrase(password)` — holds
`createVaultMutex` through vault creation **and** seed export.
- Added `unlockAndGetSeedPhrase(password)` — same mutex through unlock +
export (import rehydration path).
- Refactored vault creation into
`_createNewVaultAndKeychainUnderLock(password)`;
`createNewVaultAndKeychain` delegates to it (behavior unchanged).
- Passed `createVaultMutex` into `LegacyBackgroundApiService` so
**`setLocked` also acquires it** — lock requests wait until vault
create/export completes.

**2. UI — single RPC thunks**

- `createNewVaultAndGetSeedPhrase` → one background call (was
`createNewVault` + `getSeedPhrase`).
- `unlockAndGetSeedPhrase` → one background call (was `submitPassword` +
`getSeedPhrase`).
- `createNewVaultAndSyncWithSocial` → uses
`createNewVaultAndGetSeedPhrase`, then social backup.

**3. UI — side panel mitigation**

- Added `useCloseSidePanelOnWalletReset` (wired in
`routes.component.tsx`).
- When the side panel sees `isWalletResetInProgress` from shared
background state, it calls `window.close()` so a stale panel cannot
enter the onboarding lock trap during second-pass onboarding.

**4. UI — duplicate submit guard**

- `create-password.tsx`: `isSubmitting` state + `loading` on the form to
block double password submit.

**5. Tests**

- `metamask-controller.actions.test.js` —
`createNewVaultAndGetSeedPhrase`, `unlockAndGetSeedPhrase`.
- `ui/store/actions.test.js` — single-RPC thunks, updated social-create
path.
- `ui/hooks/useCloseSidePanelOnWalletReset.test.ts` — side panel close
behavior.
- `create-password.test.tsx` — submit guard.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: #44068

## **Manual testing steps**

1. Build a test extension: `yarn build:test`
2. Run the failing E2E spec (repeat to check for flakiness):
   ```bash
yarn test:e2e:single test/e2e/tests/reset-wallet/reset-wallet.spec.ts
--browser=chrome
   ```
3. **Standard create-wallet onboarding**
   - Fresh profile → complete onboarding with new SRP.
   - Confirm password creation succeeds and SRP backup appears.
4. **Reset-wallet flow (main repro scenario)**
- Complete first onboarding (side panel left open from onboarding
completion).
- Lock wallet → Forgot password → "I don't know my Recovery Phrase" →
Reset wallet.
   - Complete second onboarding with a new password.
   - Confirm onboarding completes without `Keyring not found`.
   - Confirm side panel closes when reset starts (if still open).
5. **Import unlock path**
   - Start import onboarding, submit password on unlock step.
   - Confirm no `Keyring not found` during seed retrieval.
6. Confirm create-password submit is disabled while the request is in
flight (double-click does not fire a second submission).

<!--
## **Screenshots/Recordings**
### **Before**
### **After**
-->

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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]
> **High Risk**
> Changes vault creation, unlock, seed export, and locking serialization
across background and UI—security-sensitive keyring paths where races
previously caused data-loss-class failures.
> 
> **Overview**
> Fixes an intermittent **Keyring not found** failure during second-pass
onboarding when vault creation and seed export were separate RPCs and
another UI surface could lock the wallet in between.
> 
> The background now exposes **`createNewVaultAndGetSeedPhrase`** and
**`unlockAndGetSeedPhrase`**, each holding **`createVaultMutex`**
through vault work and seed export.
**`LegacyBackgroundApiService:setLocked`** also acquires that mutex so
locks wait until create/export finishes. UI thunks call the single-RPC
methods instead of create/unlock then **`getSeedPhrase`**, with shared
**`encodeSeedPhraseForBackground`** /
**`decodeSeedPhraseFromBackground`** for seed bytes over the port.
> 
> **`useCloseSidePanelOnWalletReset`** closes the side panel when
**`isWalletResetInProgress`** is set so a stale panel cannot hit the
onboarding lock trap. Create-password adds **`isSubmitting`** / form
**`loading`** to block double submit.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
a740b42. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…scriptions to parent (#44295)

Fixes: https://github.com/MetaMask/MetaMask-planning/issues/7465
CHANGELOG entry: null


Each row in the token list independently subscribed to `getMarketData`,
`getCurrencyRates`, and `getNetworkConfigurationsByChainId` — triggering
O(n) Redux subscriptions for data that is identical across all rows.
This batch lifts those reads to the parent and memoizes derived values
throughout the token list hot path.

## `token-list-item.tsx` — conditional selector lift

Added optional `marketData`, `currencyRates`, `networkConfigurations`
props. When the parent provides them, the component switches to a stable
no-op selector so it does not subscribe to those Redux slices at all:

```ts
// Module-level — typed to match the real selector so useSelector infers the
// return type without unsafe `as` casts
const EMPTY_MARKET_DATA: MarketDataMap = {};
const selectEmptyMarketData: typeof getMarketData = () => EMPTY_MARKET_DATA;

// Inside the component — boolean flag keeps the useMemo dep array honest
// without referencing the object reference (which changes every render) and
// without an eslint-disable comment (which blocks React Compiler)
const isMarketDataPropProvided = marketDataProp !== undefined;
const marketDataSelector = useMemo(
  () => (isMarketDataPropProvided ? selectEmptyMarketData : getMarketData),
  [isMarketDataPropProvided],
);
const marketDataFromStore = useSelector(marketDataSelector);
const multiChainMarketData = marketDataProp ?? marketDataFromStore;
```

Fully backwards-compatible — all new props are optional; callers that
don't pass them fall back to the existing direct `useSelector` path.

## `token-list.tsx` — stable callbacks

Wrapped `handleTokenClick` and `renderTokenListItem` in `useCallback`
with correct dependency arrays. Inlined the inner `renderTokenCell`
helper to eliminate an unnecessary closure layer.

## `percentage-and-amount-change.tsx` — stale-closure fix

The `useMemo` dep array was `[marketData]` while the callback also
captured `balanceValue`, `conversionRate`, `currentChainId`,
`fiatCurrency`, and `nativeCurrency`. The computed balance-change value
would not update when those variables changed.

## `network-filter.tsx` — memoized derived values

`handleFilter` wrapped in `useCallback`; `allAddedPopularNetworks` and
`filter` wrapped in `useMemo` to stabilise references passed to
children.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Performance and memoization-only changes with a backwards-compatible
optional-prop API; the percentage change fix corrects stale UI rather
than altering business rules.
> 
> **Overview**
> This PR reduces redundant work on the home **token list** and related
UI by stabilizing callbacks/derived values and preparing rows to avoid
**O(n) Redux subscriptions** for shared global data.
> 
> **`TokenListItem`** gains optional `marketData`, `currencyRates`, and
`networkConfigurations` props. When a parent supplies them, each row
switches to stable no-op selectors so it does not subscribe to
`getMarketData`, `getCurrencyRates`, or
`getNetworkConfigurationsByChainId`; otherwise behavior stays the same
via store fallbacks.
> 
> **`token-list.tsx`** wraps `handleTokenClick` and
`renderTokenListItem` in `useCallback` and inlines the former
`renderTokenCell` helper so virtualized list render props stay stable.
> 
> **`percentage-and-amount-change.tsx`** expands the `balanceChange`
`useMemo` dependency list so fiat/balance/conversion inputs actually
refresh the computed change (previously only `marketData` was listed).
> 
> **`network-filter.tsx`** memoizes `handleFilter`,
`allAddedPopularNetworks`, and the effective `filter` object passed to
children.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
5486ab2. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: dddddanica <zhaodanica@gmail.com>
## **Description**

Migrates remaining legacy `MetaMetricsContext.trackEvent` /
`trackMetaMetricsEvent` call sites in the **Platform (metametrics
toggle, clear data, A/B test hook)** domain to `useAnalytics()` +
`createEventBuilder` (or `trackAnalyticsEvent` for Redux thunks).

Part of umbrella tracker #43885 (**15e · Platform metrics UI**).

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

1. Build and load the extension (`yarn start`).
2. Exercise the flows touched by this PR (see changed files).
3. With MetaMetrics debug enabled, confirm events still fire with the
same names and properties.

<!--
## **Screenshots/Recordings**
### **Before**
### **After**
-->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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**
> Refactor-only analytics instrumentation with tests locking event
shape; no changes to metrics opt-in, deletion tasks, or user data
handling behavior.
> 
> **Overview**
> **Platform settings analytics** in the clear-metrics modal and
participate-in-metrics toggle now go through `useAnalytics()` and
`createEventBuilder` instead of `MetaMetricsContext.trackEvent`. Event
names, categories, properties, and options such as
`excludeMetaMetricsId` on deletion flows are unchanged—only the wiring
API differs.
> 
> Tests mock `useAnalytics` and assert the built event payloads for
enable/disable toggles, deletion requests, and deletion failures. The
shared actions mock adds a no-op `trackAnalyticsEvent` for Redux/thunk
callers.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
1e1609b. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description**

Migrates remaining legacy `MetaMetricsContext.trackEvent` /
`trackMetaMetricsEvent` call sites in the **Settings (smart account
suggestion and smart transactions opt-in thunks)** domain to
`useAnalytics()` + `createEventBuilder` (or `trackAnalyticsEvent` for
Redux thunks).

Part of umbrella tracker #43885 (**15g · Settings Redux thunks**).

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

1. Build and load the extension (`yarn start`).
2. Exercise the flows touched by this PR (see changed files).
3. With MetaMetrics debug enabled, confirm events still fire with the
same names and properties.

<!--
## **Screenshots/Recordings**
### **Before**
### **After**
-->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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**
> Mechanical telemetry refactor with unchanged event names and
properties; preference dispatch logic is untouched.
> 
> **Overview**
> Continues the analytics migration in **Settings Redux thunks** by
replacing legacy `trackMetaMetricsEvent` payloads with
`trackAnalyticsEvent` + `createEventBuilder` in `ui/store/actions.ts`.
> 
> **`setDismissSmartAccountSuggestionEnabled`** and
**`setSmartTransactionsPreferenceEnabled`** still emit `SettingsUpdated`
under the Settings category with the same property keys
(`dismiss_smt_acc_suggestion_enabled` / `prev_*` and `stx_opt_in` /
`prev_stx_opt_in`); only the construction path changes. The file now
imports `createEventBuilder` (not just types) from
`shared/lib/analytics/create-event-builder`.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
cdabb3b. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

MV3 keep-alive timestamp polling previously started in `background.js`,
only after persisted state was loaded. That left a gap during early
service worker startup, before the dynamic `background.js` import
finished.

This change moves the existing `saveTimestamp` + `setInterval` logic
into the MV3 service worker entry points (`service-worker.ts` for
webpack dev, `app-init.js` for browserify prod/E2E) so polling starts at
module load.

Install `event.waitUntil` for background script loading is handled
separately in #44189.

Removal of the obsolete `enableMV3TimestampSave` debug preference is
tracked in #44373.

1. What is the reason for the change?
- Keep-alive activity should begin as early as possible in the MV3
service worker lifecycle.
2. What is the improvement/solution?
- Inline the existing keep-alive polling in both service worker entry
points.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: #43773

## **Manual testing steps**

1. Run `yarn start` and load the extension in Chrome.
2. Open `chrome://extensions`, click **Service worker** for MetaMask,
and run:
`let { timestamp } = await chrome.storage.session.get('timestamp');
console.log(timestamp)`
3. Verify a recent ISO timestamp is logged immediately after startup.
4. Reload the extension and confirm the timestamp continues updating
every ~2 seconds.
5. Unlock MetaMask and perform basic actions (open popup, switch
accounts) to confirm normal background behavior is unchanged.

<!--
## **Screenshots/Recordings**

### **Before**

### **After**
-->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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**
> Behavior is unchanged aside from earlier polling start; no auth,
vault, or transaction logic is touched—only duplicated keep-alive code
in known MV3 entry files.
> 
> **Overview**
> **MV3 keep-alive** now starts at service worker module load instead of
waiting until `background.js` finishes loading persisted state.
> 
> The existing `saveTimestamp` + 2s `setInterval` that writes an ISO
`timestamp` to `chrome.storage.session` is **inlined** in both MV3 entry
points (`service-worker.ts` for webpack dev, `app-init.js` for
browserify prod/E2E) and **removed** from `background.js` /
`initialize()`.
> 
> That closes the early-startup window where the worker could idle
before the dynamic `background.js` import completed.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
8a73c71. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
<!--
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**

Renders the QR sync code as an `<img>` generated from a data URL instead
of the table-based `QRCode` component. This ensures the QR code displays
correctly on small viewports such as the side-panel view, where the
previous rendering did not scale reliably. The Skeleton loader now
matches the QR code's dimensions so there is no layout shift while the
payload loads.

## Changes

- **`qr-code-scan.tsx`**
- Replaced the `QRCodeImage` component with a QR data URL generated
directly via `qrcode-generator`, rendered as an `<img>` (340×340) so it
displays properly on small screens like the side panel.
- Memoized QR generation with `useMemo` keyed on the displayed payload
to avoid regenerating on every render.
- Sized the `Skeleton` loader to the same 340×340 dimensions as the QR
code to prevent layout shift between the loading and loaded states.
- Added a centered MetaMask fox logo overlay on a fixed white background
(theme-independent) over the QR code.
- **`qr-code-scan.test.tsx`**
- Updated mocks to stub `qrcode-generator` (returning a mock data URL)
instead of mocking the removed `QRCodeImage` component.

## Motivation

The table-based `QRCode` did not render/scale reliably in the
constrained side-panel viewport. Using an image sourced from a generated
data URL renders consistently across screen sizes.


<!--
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: display 1:1 proportion of qr code for smaller screen

## **Related issues**

Fixes:

## **Manual testing steps**

1. Open MetaMask extension on side panel mode
2. Go to Menu > Settings > Sync with mobile
3. Check QR code image 

## **Screenshots/Recordings**

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

### **Before**
<img width="357" height="694" alt="Screenshot 2026-07-14 at 1 01 28 PM"
src="https://github.com/user-attachments/assets/0cf23a6b-551e-4d34-b494-01bd302c6b6a"
/>


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

### **After**
<img width="355" height="577" alt="Screenshot 2026-07-14 at 1 08 29 PM"
src="https://github.com/user-attachments/assets/84b8a8a7-6284-49a6-919d-5474ba3549a6"
/>


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

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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**
> Localized UI change on the sync-accounts QR screen with no auth or
persistence impact; deeplink QR still uses the existing table-based
component.
> 
> **Overview**
> **Sync-with-mobile QR** no longer uses the shared `QRCodeImage` table
renderer; it builds a **data URL** with `qrcode-generator`
(`createDataURL` instead of `createTableTag`) and shows a fixed
**340×340** `<img>` so the code scales reliably in the side panel.
> 
> QR generation is **memoized** on the displayed payload, the loading
**skeleton** matches the same size to avoid layout shift, and a
**centered MetaMask fox** sits on a theme-independent white badge over
the code. Tests now mock **`qrcode-generator`** instead of
`QRCodeImage`.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
bdfe05e. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

After a local EVM transaction confirms, the activity list can show local
state until the API query cache is refreshed after a stale time window.

This PR invalidates the query cache on confirmation

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

1. Open the extension and ensure you have at least two accounts.
2. From Account A, send a small amount of native ETH to Account B.
3. While the tx is pending, open the Activity tab — confirm the pending
row appears.
4. Wait for the tx to confirm.
5. Open the confirmed tx details — verify the **Network Fee** row is
present immediately after confirmation (previously it would be missing
until the next stale refetch or window focus).
6. Optionally check an older confirmed tx to confirm the Network Fee row
is still present there too.

<!--
## **Screenshots/Recordings**

### **Before**

### **After**
-->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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.

Made with [Cursor](https://cursor.com)

Co-authored-by: Cursor <cursoragent@cursor.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**

Tiny PR to add the filled candlestick version icon for Perps on the
bottom nav when the tab is active. Behind feature flag.

active
<img width="443" height="72" alt="image"
src="https://github.com/user-attachments/assets/3080a292-929b-463b-9c5b-af4c7f3df499"
/>

inactive
<img width="440" height="75" alt="image"
src="https://github.com/user-attachments/assets/8d42fac9-76ac-40bb-92a9-a1df2352b528"
/>


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

1. Go to this page...
2.
3.

## **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
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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.
)

<!--
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?
-->
```markdown
## [1.31.0]

### Changed

- Use a `37 TRX` fallback fee when the network fee cannot be estimated for a transaction ([#344](MetaMask/snap-tron-wallet#344))

## [1.30.0]

### Changed

- Increase cronjob interval for account syncing from 30s to 60s ([#356](MetaMask/snap-tron-wallet#356))
```

## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

Related to: https://consensyssoftware.atlassian.net/browse/WPN-1598

## **Manual testing steps**

1. Open **offscreen.html** devtools, switch to the network tab
2. Filter by "trongrid"
3. Observe calls firing every 60 seconds 

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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**
> No extension source changes; only a version pin update with a
behavioral tweak inside the snap (less frequent sync), which is low risk
for core wallet flows.
> 
> **Overview**
> Bumps the preinstalled **`@metamask/tron-wallet-snap`** dependency
from **`^1.29.1`** to **`^1.31.0`** in `package.json` and refreshes
**`yarn.lock`** so the extension ships the newer snap build.
> 
> Per the linked snap release notes, this line includes slowing the
**account-sync cron** from **30s to **60s**, which should cut
**TronGrid** polling frequency in the offscreen snap context.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
e5bd2c1. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Migrates the mUSD claim toast from the custom `MerklClaimToast`
component to the app-wide toast listener.

This prevents overlapping toasts and keeps this mUSD toast UI consistent
with other transaction toasts.

## **Changelog**

CHANGELOG entry: null

<!--
## **Related issues**

Fixes:
-->

## **Manual testing steps**

1. From the Tokens list, claim an mUSD bonus
2. Confirm the pending toast shows "Claiming rewards..."
3. Confirm the success toast shows "Rewards claimed!" after confirmation

<!--
## **Screenshots/Recordings**

### **Before**

### **After**
-->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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.

Made with [Cursor](https://cursor.com)

Co-authored-by: Cursor <cursoragent@cursor.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**

QrSync (Settings → Sync accounts) depends on a mobile wallet scanning a
QR code and exchanging messages over the Mobile Wallet Protocol (MWP)
relay. That makes the happy path difficult to cover in extension E2E
tests without a real mobile client or relay.

This PR adds an **in-extension MWP mock stack** for test builds and
wires it into the existing E2E harness:

- **`mwp-dapp-client-factory`** selects the production MWP stack
(`WebSocketTransport` + `SessionStore`) in normal builds, and an
**`E2eMwpMockClient`** + **`MobileWalletSimulator`** when `IN_TEST` is
set and Jest is not running.
- **`qr-sync-e2e-bridge`** registers the simulator and handles a new
background-socket command, **`qrSyncSimulate`**, so Mocha tests can
drive mobile-side events (scan → OTP → sync offer → sync
completed/cancel/error).
- **`QrSyncController`** now initializes MWP through `getMwpDappClient`
instead of wiring transport/session store inline.
- **Test ergonomics:** shorter `QR_SYNC_TIMEOUT_MS` values in test
builds; test builds force `ADD_DEVICE_SYNC_ENABLED` so the Sync accounts
entry is available in E2E.
- **E2E coverage:** page objects, `data-testid` hooks on sync-accounts
UI steps, and a happy-path spec (`syncs a single HD wallet to mobile`).
- **Unit tests** for `E2eMwpMockClient` and `MobileWalletSimulator`.

Production behavior is unchanged outside extension test builds.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

1. Build and load a **non-test** dev extension (`yarn start`), unlock
the wallet, and confirm the extension starts without QrSync/MWP
initialization errors in the background console.
2. Build and load a **test** extension (`yarn build:test`), unlock the
wallet, open **Settings → Sync accounts**, and confirm the QR code
screen renders and the step UI (OTP, password, wallet selection,
loading, success) displays correctly.
3. With the test build loaded, walk through **Settings → Sync accounts**
and confirm each step transitions as expected when mobile events are
simulated (OTP entry with `123456`, password entry, wallet selection,
sync confirmation).

<!--
## **Screenshots/Recordings**

### **Before**

### **After**
-->

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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**
> Refactors QrSync MWP initialization on a wallet-export path;
production stack is preserved but any factory regression could break
real relay pairing, while the mock stack only activates in extension
test builds.
> 
> **Overview**
> Adds **extension E2E coverage** for Settings → Sync accounts by
introducing a **test-build MWP mock** and wiring it through the existing
background-socket harness, while **refactoring** how `QrSyncController`
boots the Mobile Wallet Protocol client.
> 
> **`mwp-dapp-client-factory`** centralizes MWP setup: normal builds
still use `WebSocketTransport` + `SessionStore` + `DappClient`, but when
`IN_TEST` is set **and Jest is not running**, it loads an
**`E2eMwpMockClient`** and **`MobileWalletSimulator`** (via dynamic
`require` so test helpers stay out of production bundles).
`QrSyncController` now calls **`getMwpDappClient`** instead of owning
transport/session fields inline.
> 
> E2E tests drive the mobile side with a new **`qrSyncSimulate`**
background-socket command handled by **`qr-sync-e2e-bridge`** (scan →
OTP → sync offer → completed/cancel/error). **`QR_SYNC_TIMEOUT_MS`**
uses shorter values under `IN_TEST` so flows finish quickly.
> 
> The compile-time flag is renamed **`ADD_DEVICE_SYNC_ENABLED` →
`QR_SYNC_ENABLED`** (`.metamaskrc`, `builds.yml`, `environment.ts`,
docs). **Test builds force `QR_SYNC_ENABLED=true`** so the Sync accounts
tab is available in E2E.
> 
> Supporting changes: **`data-testid`** hooks across sync-accounts UI
steps, settings/sync page objects, a happy-path **`qr-sync.spec.ts`**,
and unit tests for the factory (Jest still uses the production stack
mocks).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
0a84dab. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Signed-off-by: lwin <lwin.kyaw@consensys.net>
Co-authored-by: Ganesh Suresh Patra <ganesh.patra@consensys.net>
Co-authored-by: Lionell Briones <llenoil@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: MetaMask Bot <metamaskbot@users.noreply.github.com>
…o metamask-ci (#44387)

## **Description**

The GitHub App `mm-token-exchange-service` (App ID `3202397`) is being
renamed to `metamask-ci` in the MetaMask org. On rename, its bot login
changes from `mm-token-exchange-service[bot]` to `metamask-ci[bot]`.
This PR updates the one place in this repo that hardcodes the old bot
slug:

- `.github/workflows/cla.yml`: CLA `allowlist:` entry
`mm-token-exchange-service[bot]` → `metamask-ci[bot]` (no other entries
changed).

**⚠️ Merge in lockstep with the app rename — merge this immediately
*after* TechOps renames the app, not before.** Tracked in INFRA-3680 /
INFRA-3764. This ordering is deliberate and security-relevant: merging
at/after the rename means `metamask-ci[bot]` is trusted only once we
actually own that name, and the old `mm-token-exchange-service[bot]` is
dropped the instant its name is freed — so there is no window where an
unowned/freed GitHub App name is trusted by the CLA allowlist. This PR
is kept review-ready so the merge is a single click during the
coordinated cutover window.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Refs: https://consensyssoftware.atlassian.net/browse/INFRA-3680
Refs: https://consensyssoftware.atlassian.net/browse/INFRA-3763

## **Manual testing steps**

1. After TechOps renames the app to `metamask-ci` and this merges, have
`metamask-ci[bot]` open a PR / post an automated comment.
2. Confirm the CLA check auto-approves it via the updated allowlist (no
CLA failure on the bot's contribution).

Note: CI/config-only change; rename behavior validated in a
`Consensys-test` dry-run (bot login updates in place, App ID unchanged)
— see INFRA-3762.

## **Screenshots/Recordings**

N/A — CI workflow configuration change; no extension UI or runtime
behavior is affected.

### **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
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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-extension/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.
@metamask-ci

metamask-ci Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor
Builds ready [8423f22]
⚡ Performance Benchmarks (Total: 🟢 12 pass · 🟡 8 warn · 🔴 4 fail)

Baseline (latest main): 88e20cf | Date: 7/23/2026 | Pipeline: 30048257323 | Baseline logs

Metricschrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🔴 [CI log]🔴 [CI log]
onboardingNewWallet
[Sentry log · main/release]
🔴 longTaskCount(p95) [CI log]🔴 [CI log]

Regressions (🔴 4 failures)

Interaction Benchmarks · Samples: 5
Benchmarkchrome-webpackfirefox-webpack
loadNewAccount
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
confirmTx
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
bridgeUserActions
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]

📈 Results compared to the previous 5 runs on main

  • loadNewAccount/inp: -15%
  • confirmTx/inp: +21%
  • confirmTx/lcp: -12%
  • bridgeUserActions/bridge_load_asset_picker: -17%
  • bridgeUserActions/longTaskCount: -44%
  • bridgeUserActions/longTaskTotalDuration: -39%
  • bridgeUserActions/tbt: -19%
  • bridgeUserActions/total: -10%
  • loadNewAccount/load_new_account: +10%
  • loadNewAccount/total: +10%
  • loadNewAccount/inp: -15%
  • loadNewAccount/fcp: +19%
  • loadNewAccount/lcp: +1264%
  • confirmTx/confirm_tx: +11%
  • confirmTx/longTaskCount: -100%
  • confirmTx/longTaskTotalDuration: -100%
  • confirmTx/longTaskMaxDuration: -100%
  • confirmTx/tbt: -100%
  • confirmTx/total: +11%
  • confirmTx/inp: +59%
  • confirmTx/fcp: +10%
  • confirmTx/lcp: +1204%
  • bridgeUserActions/bridge_load_page: +201%
  • bridgeUserActions/bridge_load_asset_picker: +46%
  • bridgeUserActions/longTaskCount: -100%
  • bridgeUserActions/longTaskTotalDuration: -100%
  • bridgeUserActions/longTaskMaxDuration: -100%
  • bridgeUserActions/tbt: -100%
  • bridgeUserActions/total: +14%
  • bridgeUserActions/inp: -25%
  • bridgeUserActions/fcp: -44%
  • bridgeUserActions/lcp: +1253%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 loadNewAccount/FCP: p75 2.0s
  • 🟡 confirmTx/FCP: p75 1.9s
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
🟡 loadScripts
startupPowerUserHome
[Sentry log · main/release]
🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/lcp: -32%
  • startupStandardHome/uiStartup: +16%
  • startupStandardHome/load: +15%
  • startupStandardHome/domContentLoaded: +15%
  • startupStandardHome/domInteractive: +61%
  • startupStandardHome/backgroundConnect: +13%
  • startupStandardHome/firstReactRender: +19%
  • startupStandardHome/initialActions: +11%
  • startupStandardHome/loadScripts: +16%
  • startupStandardHome/setupStore: +144%
  • startupStandardHome/fcp: +56%
  • startupStandardHome/lcp: +15%
  • startupPowerUserHome/uiStartup: -12%
  • startupPowerUserHome/domInteractive: -12%
  • startupPowerUserHome/fcp: -12%
  • startupPowerUserHome/lcp: -10%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 startupPowerUserHome/INP: p75 224ms
  • 🟡 startupPowerUserHome/LCP: p75 2.9s
User Journey Benchmarks · Samples: 5 · real API 🔴 4
Benchmarkchrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🔴 [CI log]
🔴 doneButtonToHomeScreen
🔴 total
🔴 [CI log]
🔴 total
onboardingNewWallet
[Sentry log · main/release]
🔴 [CI log]
🔴 total
🔴 [CI log]
🔴 total
assetDetails
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
solanaAssetDetails
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
importSrpHome
[Sentry log · main/release]
🟡 [CI log]🟢 [CI log]
sendTransactions
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]
swap
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]

📈 Results compared to the previous 5 runs on main

  • onboardingImportWallet/srpButtonToSrpForm: -14%
  • onboardingImportWallet/confirmSrpToPwForm: -22%
  • onboardingImportWallet/pwFormToMetricsScreen: -24%
  • onboardingImportWallet/metricsToWalletReadyScreen: -22%
  • onboardingImportWallet/doneButtonToHomeScreen: -38%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: -21%
  • onboardingImportWallet/longTaskCount: -26%
  • onboardingImportWallet/longTaskTotalDuration: -26%
  • onboardingImportWallet/longTaskMaxDuration: -24%
  • onboardingImportWallet/tbt: -23%
  • onboardingImportWallet/total: -31%
  • onboardingNewWallet/longTaskCount: +18%
  • onboardingNewWallet/longTaskTotalDuration: +15%
  • onboardingNewWallet/tbt: +13%
  • importSrpHome/loginToHomeScreen: +15%
  • importSrpHome/homeAfterImportWithNewWallet: -10%
  • importSrpHome/longTaskMaxDuration: +14%
  • importSrpHome/inp: +20%
  • importSrpHome/lcp: -62%
  • sendTransactions/openSendPageFromHome: +172%
  • sendTransactions/reviewTransactionToConfirmationPage: -63%
  • sendTransactions/longTaskCount: +67%
  • sendTransactions/longTaskTotalDuration: +72%
  • sendTransactions/longTaskMaxDuration: +72%
  • sendTransactions/tbt: +108%
  • sendTransactions/total: -62%
  • sendTransactions/cls: -17%
  • swap/openSwapPageFromHome: +37%
  • swap/fetchAndDisplaySwapQuotes: -20%
  • swap/longTaskMaxDuration: +11%
  • swap/tbt: +32%
  • swap/total: -18%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 importSrpHome/INP: p75 384ms
  • 🟡 sendTransactions/INP: p75 240ms
  • 🟡 solanaAssetDetails/FCP: p75 1.9s
  • 🟡 sendTransactions/FCP: p75 2.0s
  • 🟡 sendTransactions/LCP: p75 2.6s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]
Bundle size diffs
  • background: 210 Bytes (0%)
  • ui: 90 Bytes (0%)
  • common: 0 Bytes (0%)
  • other: 0 Bytes (0%)
  • contentScripts: 0 Bytes (0%)
  • zip: 109 Bytes (0%)

🍒 What's in this RC

Cherry-picks (2 commits)
Commit Description
8423f220d3 release: release-changelog/13.42.0 (#44798)
0c93b31dd8 Merge release/13.41.0 into release/13.42.0

Changelog (223 commits from main at RC cut)
Commit Description
446c5a25b5 fix: apply bg-alternative to legacy Popover in pure black theme (#44730)
c2c37a8a68 fix: apply border-muted to global menu drawer in pure black theme (#44729)
7e15155002 chore: remove unused legacy modals from ui/components/app/modals (#44731)
b03252588b fix: add device response timeout to Trezor bridges (#44626)
9ee3d987a7 feat: show skeleton for the whole balance block if the balance is not cached (#44703)
960369d180 fix: require interstitial for CAIP-19 asset deep links (#44639)
ef34172a99 refactor: migrate formatters to client-utils (#44624)
88c41e5489 test: cover Wallet Creation Attempted Segment event (#44673)
7a14cd7f6c feat: Updated the styles for swaps page (#44762)
ad64202e93 test: MMQA - 2035 - Fix antipatterns in sendPage which can lead to flakiness (#44640)
845b4a8f4a feat: updated avatarbase and banner alert to use DS (#44763)
3802fdba7c chore: migrate AvatarFavicon to MMDS (#44764)
a1b13be185 feat: seedless controller v10.1.0 (#44771)
864f5e5294 fix: patch bridge controller to exclude Stellar and Arc cp-13.41.0 (#44749)
ab4fbefa8d fix: non-evm bridge activity (#44751)
62fd747287 chore: removed deprecated checkbox with DS (#44765)
643d4d57cc test: added e2e tests for the new logic showing energy and bandwidth in sign transaction confirmation (#44756)
0fd8198e4b chore: remove border from pages (#44721)
1910a59ff9 feat(ledger): wire ledgerDmk flag to offscreen mode switching (#43488)
56f0a34156 chore: introduce bulk error suppression (#44739)
bd13fb6ec3 chore: updated networks for hardware accounts (#44531)
ab79e887a9 fix: updated search to be sticky and banner to scroll cp-13.41.0 (#44696)
34148d362e test(tron): prepare daily resources for E2E coverage (#44162)
4cd1d95222 chore: bump @metamask/tron-wallet-snap to ^1.33.1 (#44716)
906fee2c9d chore: bump assets controllers and remove patches (#44713)
dad0511577 test: fix flaky QrSync multi-SRP import confirm staleness timeout (#44700)
d50de2fac4 fix(metametrics): silence unmatched route Sentry noise for known paths (#44718)
4103808cae fix(ci): Remove "What's in this RC ...and more changes" section to match Extension RC Slack message to Mobile layout cp-13.41.0 (#44740)
7b2c1b2665 chore: update to ESLint v9 (#44734)
9faf0a6b5d feat: apply bg-alternative and border-muted to legacy Modal in pure black mode (#44726)
969f5c2aaa chore: update swap row labels (#44637)
2aa9b938e0 feat: apply bg-alternative and border-muted to ModalContent dialog in pure black mode (#44720)
9e40a87367 chore: New Crowdin Translations by GitHub Action cp-13.41.0 (#44595)
3ea61fd698 chore: remove unused ESLint directives from shared (#44679)
07651ccf9c chore: remove unused ESLint directives from ui/components (#44683)
0b58311684 chore: remove unused ESLint directives from remaining ui (#44685)
148b0844e4 bump: sharp to 0.35.3 (#44688)
ad1bbf43ce feat: show verified badge on swaps token button (#44623)
d5047c3a86 chore: replace sub tab screen opened metrics (#44093)
bb150a4058 feat: added skeleton for token list after stale open (#44705)
1d3f77fb38 ci: Harden absolute benchmark gate against within-noise breaches (#44609)
f3bd7f870e chore: align dapp connection bar styling with Figma spec (#44539)
42315a4087 feat: navigate users to batch sell through deeplink (#44671)
396263b848 chore: remove unneeded styles (#44693)
2acd3840a2 refactor(activity): use native dialog for transaction details (#44599)
65292d06fb bump: immutable to 5.1.9, fast-uri to 3.1.4, dompurify to 3.4.12, sass-embedded to 1.100.0 cp-13.41.0 (#44678)
57638a9616 chore: remove unused ESLint ignore directives from development (#44676)
7cb3eb6037 chore: split eslint ignore react-compiler directives (#44686)
14c815595a chore: remove unused ESLint directives from ui/pages (#44684)
8eac23857c chore: remove unused ESLint ignore directives from app (#44674)
8d99a5f7d3 test: fix flaky tests Add wallet Import wallet... (#44649)
4a1c57b063 test: fix flaky test Add account added account should persist after wallet lock (#44712)
2b218f3e77 chore(eslint): ignore .yarn and webpack build directory (#44666)
67b21b1e1b chore: update transaction controller (#44656)
77c6773132 chore: adds handler for top-traders (Follow Trading) deeplink redirect (#44660)
bceab0bb1e chore: bump @metamask/tron-wallet-snap to ^1.33.0 (#44698)
fa3885cf81 feat: setup for new defi flag (#44652)
0afcd07800 test: refactor snap-account-abstraction page object to remove references to other page objects (#44690)
3051cf4133 test: refactor account-list page object to remove references to other page objects (#44651)
edb7daa756 fix: clear orphaned advancedGasFee preference (migration 216) (#44205)
59f15bc6b0 fix: remove useAssetActivation test to unblock assets controllers bump up (#44699)
52b4b3d877 feat: removed back transitions unused selector (#44691)
f9f5e1dc48 fix: update slider step to one in batch sell (#44648)
a7847a0538 fix: do not render assets without quotes in review modal (#44650)
efa96b445e refactor: use modern clipboard api (#44622)
80b66e6c4e chore: removed sidepanel viewport max width constraint (#44647)
6d970c423d test: encryption and decryption Segment events (#44607)
1ff9bf422b chore: remove unused ESLint ignore directives from test directory (#44669)
2518a3727c feat(ui): add pure-black dark mode behind build-time flag (#44183)
d07ea1771f test: update swaps unit test mocks (#44627)
c6fc026ec2 chore: refactor ESLint overrides (#44663)
6fb3e32f55 bump: valibot to 1.4.2, body-parser to 1.20.6 and 2.3.0 (#44664)
b8c3584c53 fix(notifications): keep announcement home link in tab (#43419)
6e0219f5d6 chore: skip linting Jest snapshots (#44665)
a84d6539f5 feat: render high rate alert modal in batch sell review page (#44646)
0d81022be0 feat: integrate STX failTransaction fix (bridge stuck-pending) (#44372)
8f66b8fc55 feat: add bottom nav bar source to perps view events (#44611)
6fb1d6ba46 chore: update @metamask/gator-permissions-snap to version 2.4.0 (#44499)
9b12c19790 test: cover Empty Buy Banner Displayed event (#44617)
6c0217c496 feat: add bottom nav transitions (#44641)
8ae5ce634e chore: use same toaster-bottom-offset var for legacy toasts (#44654)
5da5008a3a test: MMQA - 1975 - Enhance feature flag validation/drift PR to omit re-orders without value change (#43814)
261773c0bb test: fix flaky tests Check balance For a non 0 balance account... (#44479)
5207d27d9c feat: add bottom nav experiment display logic and e2e tests (#44403)
1f66fc6cd7 release: Bump main version to 13.42.0 (#44642)
9962ac769f feat: implement close positions with limit orders (#44466)
477be3b0bc feat(e2e): add Tron test fixtures and environment helpers (#44160)
ffd91160c9 fix: various fixes and improvements on batch sell select page (#44603)
e091fe0b04 fix(assets): wire tempMigrateAssetsInfoMetadataAssets3346 into AssetsController init (#44303)
b685e6bf62 test: MMQA - 2034 - Fix antipatterns in qr-sync.spec.ts (#44600)
1548788667 bump: multiple to fix audit cp-13.41.0 (#44634)
6647504ca3 feat: consume backend-suggested slippage in unified swap/bridge (#44537)
e29c451b29 feat: import alias via node subpath imports (#44621)
f7f67d320b feat(ramps): add provider selection page with async quotes (#44553)
e9b745e8e5 chore: remove dead code (#44612)
bb5e12f804 refactor: migrate multichain review permissions toast (#44505)
fc5d600b60 refactor: add useEventListener (#44596)
d8c683d6c9 feat(e2e): add Tron swap token registry and quote fixtures (#44159)
39d6aa6899 refactor: migrate buy button toast (#44510)
4fa405c7e6 fix: dedicated convert mUSD details cp-13.41.0 (#44586)
a6942d1c60 feat(support): replace raw profile params with customer service token (#44482)
d4987093b8 refactor: migrate delete metametrics toast (#44503)
22c64b7f3f refactor: migrate permissions disconnect-all toast (#44504)
227a3644f0 feat(ramps): show per-method quotes on payment selection (#44526)
abc8a8267c feat: update bottom bar navigation to swaps page (#44233)
3784ae3945 feat: added decimal validation for custom token import flow cp-13.41.0 (#44602)
b495bf455d chore: patch @metamask/assets-controller for suggested occurrence floors (#44525)
88bc6591dc feat(ci): add Runway orchestrator starter and store submission CODEOWNERS (#44017)
1894816b17 refactor(analytics): remove MetaMetricsController shims and finish background migration (#44380)
c4af8823c1 feat(hardware-wallets): add signing page orchestrator (#43943)
e8baf89ff4 fix(ci): align Extension RC Slack notes with Mobile Runway changelog (#44597)
7bfc16cfc0 bump: Upgrade @sentry/browser from 8.33.1 to 10.38.0 (#42867)
a25c6a5b07 chore(6932): convert final legacy context consumers to useI18nContext for React 19 (#44493)
9b908f58d4 test: fix Add wallet Import wallet using json file - TimeoutError: Waiting for element to be located By(css selector, [data-testid="choose-wallet-type-import-account"]) (#44464)
6183003c90 refactor: resolve activity list redesign (#44365)
576a79fa6d chore: allow history navigate on activity details (#44467)
593690c0f7 chore: remove browserify (#44433)
1456a2100a fix: keep bridge activity item as pending until dest tx resolves cp-13.40.0 (#44536)
aa09362f39 fix: don't hold the KeyringController lock during hardware wallets reads (#44483)
0f5ef841a3 refactor(activity): handle swaps missing destination token (#44501)
5d12649353 test: fix flakyTest Snap getEntropy can use snap_getEntropy inside a snap (#44458)
ad3fb497ce refactor(confirmations): address send asset picker review follow-ups (#44431)
b6449df15d feat(ramps): update remaining entrypoints to use goToBuy (#44440)
8a1ccdc82c feat: gate scam questionnaire behind LaunchDarkly flag cp-13.40.0 (#44496)
c0e7a119d7 fix: mascot being rendered twice in onboarding unlock page (#44533)
4c7819aff3 fix: prevent duplicate events during tab switch (#44528)
360bc7d616 fix: bump network enablement controller to v5.6.0 (#44371)
e2f4454072 feat(ramps): add payment method selection page (#44437)
d11fa4a85a refactor: migrate gas fee token toast (#44468)
b48258de3b feat(e2e): add Tron local node mock proxy (#44157)
e149e9c519 feat: update bridge status controller to latest release (#44515)
2ba671463a bump: websocket-driver to fix audit (#44513)
8b843741f8 fix(ramps): wait for selected token before leaving token selection (#44497)
449919f484 fix: crash when typing a comma in the MM Pay custom amount input (#44521)
81ed3e6cb7 fix(ramps): keep provider label while quotes load on build quote (#44491)
e294e5fbc3 chore(tokens): remove stale token cache fallbacks (#44522)
b3a729e909 build: remove submodule added by mistake (#44514)
40f4844d3e feat: sentry for QrSync (#44487)
173e9e7a04 feat: added transitions to manage tokens page (#44484)
be631b56fa refactor: switch activity mappers to @metamask/client-utils (#44366)
41ca3b93c3 fix: Bump react-data-query (#44520)
0cd688b4bf refactor(analytics): migrate orphan multichain accounts UI events (#44376)
4400dd58c1 feat: added skeleton fr balance loading state (#44429)
397c4485f0 chore: use skeleton on loading activity screen (#44423)
29b6f2e924 chore: Revert "chore(6926): migrate ReactDOM.render to createRoot (#43872)" (#44517)
743cccdd2a refactor(analytics): migrate orphan account overview tabs events (#44375)
9efc6d62ed chore(6926): migrate ReactDOM.render to createRoot (#43872)
83d763aaa4 perf(6600): fix asset selector cache thrashing for NFTs and token scan results (#44473)
21c3992646 feat: added transitions to Dapp connections pages (#44481)
1d44802063 fix: consume local history data for bridges on activity items (#44488)
bf71e30756 refactor(analytics): migrate orphan UX contacts and chrome events (#44374)
f1c3e4103c feat(e2e): extend Tron mocks with swap tokens, stateful accounts, and parameterized fixtures (#44485)
8c0fa5b830 perf(6601): fix parameterized selector cache thrashing for chain-checking selectors (#44474)
c255a1a983 feat(perps): show ticker next to volume and fix symbol display consistency (#44478)
b169cbc8fc fix: updated analytis for add token (#44486)
d0a5db3726 feat(ramps): add build quote page with quote fetching (#44409)
4eabcbe89b chore(6931): migrate class components from defaultProps to default params (#44299)
56e0cbf45f perf(6929): harden UI effects for React 18 StrictMode double-mount (#44298)
55e0419dce perf(6602): prevent cache thrashing in parameterized network lookups (#44475)
72c5dccaa4 chore(6930): update React Compiler target to v18 (#44476)
9b7cd98c49 feat: updated CODEOWNERS for QrSync (#44465)
f2018259e3 test: QrSync e2e for multi SRP flows (#44438)
dc5bc8dc93 test(e2e): add Bitcoin send flow against local regtest node (#44156)
e34d7e67bb test: Add E2E max balance validation test (#43821)
2ff51fd902 fix: ensure stellar assets show correctly in token details page (#44444)
77cf93f811 chore: tiny header adjustments on new bottom nav pages (#44470)
fe2bc9df7d test: MMQA - 1971 - Fix missnamed test tokens/nft/filter-nfts.spec.ts same as view-nft-details.spec.ts (View NFT details) (#44086)
f5d4634e8b perf(7475): adopt useDeferredValue for search and filter surfaces (#44443)
23a9a0e228 feat(e2e): add Bitcoin regtest node wrapper using @metamask/bitcoin-regtest-up (#44155)
1986666442 feat: updated token management toggle button (#44434)
a74972d532 feat: ux improvemnets for add via chainlist feature (#44424)
bfb0b29226 test: fix flaky test Vault Corruption does not reset metamask state when recovery is not confirmed (#44435)
ccadeeeccd chore: New Crowdin Translations by GitHub Action cp-13.40.0 (#44329)
3f7584b6f0 fix: QR Sync session timeout and cancellation (#44422)
8b02f4a613 chore: reduce Sentry trace sampling cp-13.40.0 (#44451)
7cd63e4d54 perf(6778): add useStateSyncHealth hook for stale sync auto-recovery (#44389)
80a76d63d4 bump: ws to fix audit (#44459)
f602fae822 refactor: migrate perps withdraw transaction toast (#44419)
81bacd28ee fix(sentry): Resolve AggregatedBalanceSelector transaction volume spike by not passing trace into getAggregatedBalanceForAccount cp-13.40.0 (#44449)
ba18ce10ac feat(ramps): intent routing in goToBuy + stub buy pages (#44404)
2e477542ab ci(token-exchange): migrate FIXTURE_UPDATE_TOKEN to token exchange service (#43838)
2ff80c450e test(e2e): run Solana send flow against local validator (#44154)
baab980461 fix: resolve Perps deposit confirmation stuck on loading skeleton on first open (#44247)
a9f826964b ci: remove requirement for "auto-rc-builds" label (#44421)
3e52ec5ffb perf(7467): memoize composite derived state in home container and dapp bar (#44354)
8846ae56e5 feat(ramps): geo-blocking UI for ramps entry points (#44351)
c496204040 feat(e2e): add Solana local validator wrapper using @metamask/solana-… (#44426)
71f9467411 feat: reintroduce saved gas settings (#43317)
25d7175ff4 chore: nav to perps funding screen on perps funded activity details (#44427)
7657dcc0da fix: render in flight perps deposit/withdraw activity details (#44425)
78908aa279 fix(confirmations): address enforced simulations papercuts (#44343)
4b01eb4a84 feat(ramps): add in-extension token selection page (#44349)
eb3b6f521a fix(perps): mask open order size and value in privacy mode (#44432)
c6c99ecced ci(INFRA-3680): rename bot reference from mm-token-exchange-service to metamask-ci (#44387)
594bbd6f6c test: QrSync E2E (main flow) (#44381)
612334352b refactor: migrate musd claim toast (#44414)
d22a7b6118 chore: bump @metamask/tron-wallet-snap to ^1.31.0 cp-13.40.0 (#44385)
a396544397 chore: use candlestick filled icon when perps bottom nav active (#44388)
70a302b923 feat: refresh activity list after confirm (#44333)
ea74194fd2 feat: sync-accounts use image for qr code (#44417)
4631b6103f fix(mv3): move keep-alive polling to service worker startup (#44348)
5dd78ebf23 refactor(analytics): migrate settings thunk MetaMetrics events (#44379)
b400e49380 refactor(analytics): migrate orphan platform metrics UI events (#44378)
1e0188a092 perf(7465): memoize token list derivations and lift per-row Redux subscriptions to parent (#44295)
e9d9c6cd75 fix: fixed race condition on vault creation and get seedphrase (#44276)
5418dedc88 chore(preferences): remove enableMV3TimestampSave debug preference (#44373)
5bfa8fe8fb chore(6925): upgrade react & react-dom to v18 (#42997)
d3fa3dd51b chore: update CODEOWNERS bringing more code under team money-movement (#44408)
485109f500 chore: deprecated import path (#43242)
dec283a8fe refactor(analytics): migrate orphan Web3Auth onboarding events (#44377)
5291e67aa5 refactor: remove headless STX status page approval (#44301)
909c8d60b2 docs: Add Cursor Skill to automatically add new EVM networks to swaps (#44386)
4a4948b41b fix: update trackImportEvent usage to use correct params and string comparison (#44400)
355bc49105 feat: Bump Snaps packages (#44396)
cd8907a7aa perf(7467): memoize hooks/components with multiple selectors (#44297)
7c8966dd69 feat(e2e): wire Tron local node into fixtures (#44152)
82af0c7e26 fix(assets): restore google.svg and relocate to app/images/ cp-13.40.0 (#44383)
b977317023 feat(asset): migrate asset routes to CAIP-19 identifiers (#44114)
0ebadf7dd6 feat: QR sync error UI (#44081)
615c3a8fe1 feat: rename add-device to sync-accounts (#43870)
a329b0473b fix: extra pending row from local state cp-13.40.0 (#44359)
b7c7eef85a feat: wallet metadata and imported account sync via QR (#44047)
b426596c9c perf: add useMemo/useCallback memoization to home balance components (#44294)

AI Test Plan

Risk Score High Risk Medium Risk Files Changed Commits
59/100 7 7 1681 124
Release Scenarios (14)

High Risk Scenarios (7)

1. State Migrations – Core data integrity (accounts, networks, tokens/NFTs)

Risk Level: HIGH

Why This Matters: Migrations 217–219 were added; any schema or state transformation can cause data loss or corrupted lists affecting core wallet functionality.

Test Steps:

  1. Start from a pre-13.42.0 profile (e.g., 13.38–13.41) with: 3 accounts (standard, imported PK, hardware), 2 custom networks (custom RPC + L2), several custom ERC-20s and NFTs added; lock wallet.
  2. Upgrade to 13.42.0 and open the extension to trigger migrations; then unlock.
  3. Verify all accounts exist with correct labels/order; hardware account still recognized; balances load.
  4. Confirm custom networks still exist, current network selection persists, and custom RPC URLs/chain IDs are unchanged.
  5. Check tokens/NFTs per-network are preserved with no duplicates; hidden assets remain hidden.

2. State Migrations – Connected sites and permissions

Risk Level: HIGH

Why This Matters: Permissions/connection mappings may be reshaped by migrations and are critical for dapp connectivity and the unconnected-account alert logic.

Test Steps:

  1. Pre-upgrade: connect Site A to Account 1 and Site B to Account 2; ensure both sites can request accounts and sign.
  2. Upgrade to 13.42.0; open both sites post-upgrade.
  3. Verify auto-connect uses the same mapped account per site and that switching to an unconnected account shows an appropriate alert.
  4. Trigger eth_requestAccounts from each site and confirm correct permission prompts/auto-connect behavior.
  5. Remove a site connection in Settings and confirm it does not auto-connect after reload.

3. State Migrations – Settings and feature flags

Risk Level: HIGH

Why This Matters: Settings schema changes can silently reset critical privacy/security preferences or analytics consent.

Test Steps:

  1. Pre-upgrade: enable test networks, toggle phishing protection, and opt-in to MetaMetrics.
  2. Upgrade to 13.42.0 and open Settings.
  3. Verify toggles persist; test network list visibility matches the toggle.
  4. Navigate to a known phishing test URL to confirm the blocklist behavior matches the setting.
  5. Confirm analytics toggle state persists and events are only sent when opted in.

4. Token Management – Assets Controller v11: token discovery and watchAsset

Risk Level: HIGH

Why This Matters: A major Assets Controller bump commonly affects token metadata, decimals, and persistence; regressions break balances and swaps.

Test Steps:

  1. On Mainnet, use Import Tokens search to detect and add a popular ERC‑20; verify balance/fiat value accuracy; then hide it.
  2. Use wallet_watchAsset from a dapp to add a custom ERC‑20 with non‑standard decimals (e.g., 8); confirm correct formatting and persistence.
  3. Switch networks and ensure token lists are scoped per network with no leakage of Mainnet tokens.
  4. Change fiat currency display and verify token fiat values update accordingly.

5. NFT Management – Assets Controller v11: detection, metadata, and transfers

Risk Level: HIGH

Why This Matters: NFT indexing/metadata often changes across assets controller updates; broken metadata or transfer handling impacts key user flows.

Test Steps:

  1. Add one ERC‑721 and one ERC‑1155 NFT to the active account.
  2. Open the NFTs tab and verify images/metadata load and group correctly.
  3. Hide an NFT, then unhide it from Hidden NFTs; confirm state persists across reload.
  4. Send an ERC‑721 to another address and confirm it is removed post-confirmation.

6. Bridge – Quote, approvals, switching, and status tracking

Risk Level: HIGH

Why This Matters: Bridge controller changes can disrupt quoting, approvals, network switching, and status polling, leading to failed or stuck transfers.

Test Steps:

  1. Open Bridge, select ETH from Ethereum Mainnet to Arbitrum (or other L2) and request a quote.
  2. Approve (if required) and submit the bridge transaction; accept any chain-switch prompts.
  3. Track status until completion and verify final destination balance reflects the bridged amount.
  4. Reject a subsequent bridge attempt to verify clear error handling and recoverability (retry/close).

7. Network Management – Dapp-driven add/switch chain

Risk Level: HIGH

Why This Matters: Network enablement controller changes risk breaking dapp workflows that add/switch chains, impacting many ecosystem integrations.

Test Steps:

  1. From a dapp, call wallet_addEthereumChain to add a new test chain; verify the approval details and successful addition.
  2. From the same dapp, call wallet_switchEthereumChain and confirm the permission prompt, then the active network changes.
  3. Attempt to switch to a chain that isn't added and verify the correct error and no stuck prompt.
  4. Toggle 'Show test networks' off and ensure hidden networks do not appear in UI suggestions.

Medium Risk Scenarios (7)

1. Message Encryption – eth_getEncryptionPublicKey and eth_decrypt

Risk Level: MEDIUM

Why This Matters: Small controller changes here can silently break EIP‑1024 flows used by secure messaging features.

Test Steps:

  1. From a test dapp, request eth_getEncryptionPublicKey for the active account and approve.
  2. Have the dapp encrypt a message and request eth_decrypt; approve and verify the plaintext matches.
  3. Switch to an unconnected account, repeat request, and confirm the unconnected-account alert appears; connect and retry successfully.
  4. Cancel a decrypt request and confirm the dapp receives a clear error.

2. Alert System – Unconnected account alert

Risk Level: MEDIUM

Why This Matters: Alert-system code changed; incorrect alerts can block signing or confuse users about which account is connected.

Test Steps:

  1. Connect Site A to Account 1 only; then switch the active account in the extension to Account 2.
  2. On Site A, initiate a signature or transaction; verify the unconnected account alert appears with clear actions.
  3. Use the alert’s CTA to switch to Account 1 and complete the action.
  4. Verify no alert appears when Account 1 is active for Site A.

3. Alert System – Multiple alerts and confirmation modals

Risk Level: MEDIUM

Why This Matters: Refactors to alert components can cause modal stacking and lifecycle issues that hide critical prompts.

Test Steps:

  1. Create overlapping prompts (e.g., a pending signature, a network switch request, and a general warning).
  2. Verify the multiple-alert modal shows all alerts with sensible ordering and distinct actions.
  3. Dismiss one alert and confirm others remain actionable and not lost.
  4. In a confirm-alert modal, verify both Cancel and Confirm behave correctly without leaving the UI in a stuck state.

4. API Error Handling – RPC/network failures

Risk Level: MEDIUM

Why This Matters: api-error-handler changes must surface actionable errors; failures here strand users with spinners and no recovery path.

Test Steps:

  1. Set the current network RPC URL to an invalid endpoint; open the portfolio/tokens view.
  2. Verify a clear inline error with a Retry option is shown instead of an infinite spinner.
  3. Restore a valid RPC and click Retry; confirm the UI recovers and data loads.
  4. Against a rate-limited RPC, trigger a 429 and verify a friendly message and no lock-up.

5. Swaps – Quote, allowance, slippage, and execution

Risk Level: MEDIUM

Why This Matters: Assets controller changes affect token metadata and allowances used in swaps; regressions can misprice or fail swaps.

Test Steps:

  1. On Mainnet, swap a small amount of a token requiring approval to another token; confirm a single allowance approval then swap execution.
  2. Verify min-received, slippage warnings, and fiat values render correctly before and after the swap.
  3. Repeat a swap on another network (e.g., Polygon) and ensure correct token metadata/decimals and per-network asset lists.
  4. Validate post-swap balances and activity items are correct.

6. Permissions Management – Connected sites UI

Risk Level: MEDIUM

Why This Matters: Migrations and alert changes rely on accurate permissions state; UI regressions can misrepresent connections.

Test Steps:

  1. In Settings > Security & Privacy > Connected sites, remove an existing site.
  2. Reload that site and verify it does not auto-connect and that eth_requestAccounts prompts for permission.
  3. Reconnect the site selecting a different account and verify it appears correctly in the list and works in-page.
  4. Lock/unlock the wallet and confirm the mapping remains intact.

7. Performance/UX – Popup and assets rendering at scale

Risk Level: MEDIUM

Why This Matters: Large-scale UI refactors can degrade performance and responsiveness, impacting everyday use.

Test Steps:

  1. Use a profile with 200+ tokens and 50+ NFTs across 4 networks.
  2. Measure time to open the popup and render the Assets tab; scroll through long lists.
  3. Switch networks repeatedly and verify no freezes, missing thumbnails, or extreme jank.
  4. Open Activity and NFTs tabs and confirm smooth navigation.

Teams Sign-off Status

Signed off: None yet

Awaiting sign-off (9):
Accounts, Assets, Confirmations, Networks, Permissions, Settings, Swaps, Swaps and Bridge, Wallet Integrations


Generated by AI Test Plan Analyzer (gpt-5) at 2026-07-23T22:39:17.116Z

AI generated test plan (JSON): test-plan-13.42.0.json

@HowardBraham

Copy link
Copy Markdown
Contributor

@SocketSecurity ignore npm/@metamask/gator-permissions-snap@2.4.0
@SocketSecurity ignore npm/@sentry-internal/feedback@10.38.0
@SocketSecurity ignore npm/@sentry/browser@10.38.0
@SocketSecurity ignore npm/@sentry/core@10.38.0
@SocketSecurity ignore npm/@sentry/node-core@10.38.0
@SocketSecurity ignore npm/@parcel/watcher@2.5.6
@SocketSecurity ignore npm/sharp@0.35.3
@SocketSecurity ignore npm/content-type@2.0.0
@SocketSecurity ignore npm/type-is@2.1.0
@SocketSecurity ignore npm/@parcel/watcher@2.5.6
@SocketSecurity ignore npm/unrs-resolver@1.12.2
@SocketSecurity ignore npm/@metamask/solana-test-validator-up@1.0.0
@SocketSecurity ignore npm/@metamask/transaction-controller@69.2.1
@SocketSecurity ignore npm/@metamask/transaction-pay-controller@24.1.0
@SocketSecurity ignore npm/@sentry-internal/replay-canvas@10.38.0
@SocketSecurity ignore npm/ajv@6.15.0
@SocketSecurity ignore npm/es-module-lexer@1.7.0
@SocketSecurity ignore npm/import-in-the-middle@2.0.6
@SocketSecurity ignore npm/js-yaml@3.15.0
@SocketSecurity ignore npm/node-addon-api@7.1.1

@metamask-ci

metamask-ci Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor
Builds ready [189763c]
⚡ Performance Benchmarks (Total: 🟢 12 pass · 🟡 8 warn · 🔴 4 fail)

Baseline (latest main): c42c6cb | Date: 7/23/2026 | Pipeline: 30053029046 | Baseline logs

Metricschrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🔴 metricsToWalletReadyScreen(p95) [CI log]🔴 [CI log]
onboardingNewWallet
[Sentry log · main/release]
🔴 longTaskCount(p95) [CI log]🔴 [CI log]

Regressions (🔴 4 failures)

Interaction Benchmarks · Samples: 5
Benchmarkchrome-webpackfirefox-webpack
loadNewAccount
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
🟡 load_new_account
confirmTx
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
bridgeUserActions
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • bridgeUserActions/bridge_load_asset_picker: -21%
  • bridgeUserActions/longTaskCount: -44%
  • bridgeUserActions/longTaskTotalDuration: -35%
  • bridgeUserActions/tbt: -17%
  • loadNewAccount/load_new_account: +14%
  • loadNewAccount/total: +14%
  • loadNewAccount/inp: -12%
  • loadNewAccount/fcp: -40%
  • loadNewAccount/lcp: +1521%
  • confirmTx/confirm_tx: +12%
  • confirmTx/longTaskCount: -100%
  • confirmTx/longTaskTotalDuration: -100%
  • confirmTx/longTaskMaxDuration: -100%
  • confirmTx/tbt: -100%
  • confirmTx/total: +12%
  • confirmTx/inp: -15%
  • confirmTx/fcp: -49%
  • confirmTx/lcp: +1191%
  • bridgeUserActions/bridge_load_page: +182%
  • bridgeUserActions/bridge_load_asset_picker: +96%
  • bridgeUserActions/longTaskCount: -100%
  • bridgeUserActions/longTaskTotalDuration: -100%
  • bridgeUserActions/longTaskMaxDuration: -100%
  • bridgeUserActions/tbt: -100%
  • bridgeUserActions/total: +29%
  • bridgeUserActions/inp: -25%
  • bridgeUserActions/lcp: +1189%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 loadNewAccount/LCP: p75 2.8s
  • 🟡 bridgeUserActions/FCP: p75 1.8s
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
startupPowerUserHome
[Sentry log · main/release]
🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/uiStartup: -15%
  • startupStandardHome/load: -13%
  • startupStandardHome/domContentLoaded: -14%
  • startupStandardHome/domInteractive: -12%
  • startupStandardHome/backgroundConnect: -18%
  • startupStandardHome/firstReactRender: -15%
  • startupStandardHome/initialActions: -29%
  • startupStandardHome/loadScripts: -14%
  • startupStandardHome/longTaskCount: -29%
  • startupStandardHome/longTaskTotalDuration: -20%
  • startupStandardHome/longTaskMaxDuration: -15%
  • startupStandardHome/tbt: -18%
  • startupStandardHome/inp: -10%
  • startupStandardHome/fcp: -14%
  • startupStandardHome/lcp: +142%
  • startupStandardHome/uiStartup: -22%
  • startupStandardHome/load: -22%
  • startupStandardHome/domContentLoaded: -22%
  • startupStandardHome/domInteractive: -42%
  • startupStandardHome/backgroundConnect: -20%
  • startupStandardHome/firstReactRender: -22%
  • startupStandardHome/initialActions: -44%
  • startupStandardHome/loadScripts: -22%
  • startupStandardHome/setupStore: -25%
  • startupStandardHome/fcp: -35%
  • startupStandardHome/lcp: -22%
  • startupPowerUserHome/setupStore: +23%
  • startupPowerUserHome/inp: +19%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 startupPowerUserHome/INP: p75 248ms
  • 🟡 startupPowerUserHome/LCP: p75 3.4s
User Journey Benchmarks · Samples: 5 · real API 🔴 4
Benchmarkchrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🔴 [CI log]
🔴 doneButtonToHomeScreen
🔴 total
🔴 [CI log]
🔴 total
onboardingNewWallet
[Sentry log · main/release]
🔴 [CI log]
🔴 total
🔴 [CI log]
🔴 total
assetDetails
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
solanaAssetDetails
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
importSrpHome
[Sentry log · main/release]
🟡 [CI log]🟢 [CI log]
sendTransactions
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]
swap
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • onboardingImportWallet/doneButtonToHomeScreen: -34%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: -75%
  • onboardingImportWallet/longTaskCount: -26%
  • onboardingImportWallet/longTaskTotalDuration: +10%
  • onboardingImportWallet/tbt: +18%
  • onboardingImportWallet/total: -37%
  • onboardingNewWallet/longTaskCount: -17%
  • onboardingNewWallet/longTaskTotalDuration: -19%
  • onboardingNewWallet/tbt: -25%
  • solanaAssetDetails/assetClickToPriceChart: +19%
  • solanaAssetDetails/total: +19%
  • importSrpHome/homeAfterImportWithNewWallet: -15%
  • importSrpHome/longTaskCount: +18%
  • importSrpHome/tbt: -17%
  • importSrpHome/total: -14%
  • importSrpHome/lcp: -77%
  • sendTransactions/selectTokenToSendFormLoaded: -34%
  • sendTransactions/reviewTransactionToConfirmationPage: -28%
  • sendTransactions/longTaskCount: +25%
  • sendTransactions/longTaskTotalDuration: +28%
  • sendTransactions/longTaskMaxDuration: +28%
  • sendTransactions/tbt: +39%
  • sendTransactions/total: -28%
  • sendTransactions/lcp: -65%
  • sendTransactions/cls: -29%
  • swap/openSwapPageFromHome: -25%
  • swap/fetchAndDisplaySwapQuotes: -37%
  • swap/longTaskTotalDuration: -16%
  • swap/longTaskMaxDuration: -10%
  • swap/tbt: -30%
  • swap/total: -37%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 importSrpHome/INP: p75 328ms
  • 🟡 sendTransactions/INP: p75 232ms
  • 🟡 solanaAssetDetails/FCP: p75 1.9s
  • 🟡 sendTransactions/FCP: p75 2.0s
  • 🟡 sendTransactions/LCP: p75 2.5s
  • 🟡 swap/FCP: p75 1.9s
  • 🟡 swap/LCP: p75 2.5s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]
Bundle size diffs
  • background: 210 Bytes (0%)
  • ui: 117 Bytes (0%)
  • common: 0 Bytes (0%)
  • other: 0 Bytes (0%)
  • contentScripts: 0 Bytes (0%)
  • zip: 122 Bytes (0%)

🍒 What's in this RC

Cherry-picks (3 commits)
Commit Description
189763ce27 release(cp): cherry-pick fix(assets): include tokens with large balances and few decimals in aggregated balance cp-13.41.0
8423f220d3 release: release-changelog/13.42.0 (#44798)
0c93b31dd8 Merge release/13.41.0 into release/13.42.0

Changelog (223 commits from main at RC cut)
Commit Description
446c5a25b5 fix: apply bg-alternative to legacy Popover in pure black theme (#44730)
c2c37a8a68 fix: apply border-muted to global menu drawer in pure black theme (#44729)
7e15155002 chore: remove unused legacy modals from ui/components/app/modals (#44731)
b03252588b fix: add device response timeout to Trezor bridges (#44626)
9ee3d987a7 feat: show skeleton for the whole balance block if the balance is not cached (#44703)
960369d180 fix: require interstitial for CAIP-19 asset deep links (#44639)
ef34172a99 refactor: migrate formatters to client-utils (#44624)
88c41e5489 test: cover Wallet Creation Attempted Segment event (#44673)
7a14cd7f6c feat: Updated the styles for swaps page (#44762)
ad64202e93 test: MMQA - 2035 - Fix antipatterns in sendPage which can lead to flakiness (#44640)
845b4a8f4a feat: updated avatarbase and banner alert to use DS (#44763)
3802fdba7c chore: migrate AvatarFavicon to MMDS (#44764)
a1b13be185 feat: seedless controller v10.1.0 (#44771)
864f5e5294 fix: patch bridge controller to exclude Stellar and Arc cp-13.41.0 (#44749)
ab4fbefa8d fix: non-evm bridge activity (#44751)
62fd747287 chore: removed deprecated checkbox with DS (#44765)
643d4d57cc test: added e2e tests for the new logic showing energy and bandwidth in sign transaction confirmation (#44756)
0fd8198e4b chore: remove border from pages (#44721)
1910a59ff9 feat(ledger): wire ledgerDmk flag to offscreen mode switching (#43488)
56f0a34156 chore: introduce bulk error suppression (#44739)
bd13fb6ec3 chore: updated networks for hardware accounts (#44531)
ab79e887a9 fix: updated search to be sticky and banner to scroll cp-13.41.0 (#44696)
34148d362e test(tron): prepare daily resources for E2E coverage (#44162)
4cd1d95222 chore: bump @metamask/tron-wallet-snap to ^1.33.1 (#44716)
906fee2c9d chore: bump assets controllers and remove patches (#44713)
dad0511577 test: fix flaky QrSync multi-SRP import confirm staleness timeout (#44700)
d50de2fac4 fix(metametrics): silence unmatched route Sentry noise for known paths (#44718)
4103808cae fix(ci): Remove "What's in this RC ...and more changes" section to match Extension RC Slack message to Mobile layout cp-13.41.0 (#44740)
7b2c1b2665 chore: update to ESLint v9 (#44734)
9faf0a6b5d feat: apply bg-alternative and border-muted to legacy Modal in pure black mode (#44726)
969f5c2aaa chore: update swap row labels (#44637)
2aa9b938e0 feat: apply bg-alternative and border-muted to ModalContent dialog in pure black mode (#44720)
9e40a87367 chore: New Crowdin Translations by GitHub Action cp-13.41.0 (#44595)
3ea61fd698 chore: remove unused ESLint directives from shared (#44679)
07651ccf9c chore: remove unused ESLint directives from ui/components (#44683)
0b58311684 chore: remove unused ESLint directives from remaining ui (#44685)
148b0844e4 bump: sharp to 0.35.3 (#44688)
ad1bbf43ce feat: show verified badge on swaps token button (#44623)
d5047c3a86 chore: replace sub tab screen opened metrics (#44093)
bb150a4058 feat: added skeleton for token list after stale open (#44705)
1d3f77fb38 ci: Harden absolute benchmark gate against within-noise breaches (#44609)
f3bd7f870e chore: align dapp connection bar styling with Figma spec (#44539)
42315a4087 feat: navigate users to batch sell through deeplink (#44671)
396263b848 chore: remove unneeded styles (#44693)
2acd3840a2 refactor(activity): use native dialog for transaction details (#44599)
65292d06fb bump: immutable to 5.1.9, fast-uri to 3.1.4, dompurify to 3.4.12, sass-embedded to 1.100.0 cp-13.41.0 (#44678)
57638a9616 chore: remove unused ESLint ignore directives from development (#44676)
7cb3eb6037 chore: split eslint ignore react-compiler directives (#44686)
14c815595a chore: remove unused ESLint directives from ui/pages (#44684)
8eac23857c chore: remove unused ESLint ignore directives from app (#44674)
8d99a5f7d3 test: fix flaky tests Add wallet Import wallet... (#44649)
4a1c57b063 test: fix flaky test Add account added account should persist after wallet lock (#44712)
2b218f3e77 chore(eslint): ignore .yarn and webpack build directory (#44666)
67b21b1e1b chore: update transaction controller (#44656)
77c6773132 chore: adds handler for top-traders (Follow Trading) deeplink redirect (#44660)
bceab0bb1e chore: bump @metamask/tron-wallet-snap to ^1.33.0 (#44698)
fa3885cf81 feat: setup for new defi flag (#44652)
0afcd07800 test: refactor snap-account-abstraction page object to remove references to other page objects (#44690)
3051cf4133 test: refactor account-list page object to remove references to other page objects (#44651)
edb7daa756 fix: clear orphaned advancedGasFee preference (migration 216) (#44205)
59f15bc6b0 fix: remove useAssetActivation test to unblock assets controllers bump up (#44699)
52b4b3d877 feat: removed back transitions unused selector (#44691)
f9f5e1dc48 fix: update slider step to one in batch sell (#44648)
a7847a0538 fix: do not render assets without quotes in review modal (#44650)
efa96b445e refactor: use modern clipboard api (#44622)
80b66e6c4e chore: removed sidepanel viewport max width constraint (#44647)
6d970c423d test: encryption and decryption Segment events (#44607)
1ff9bf422b chore: remove unused ESLint ignore directives from test directory (#44669)
2518a3727c feat(ui): add pure-black dark mode behind build-time flag (#44183)
d07ea1771f test: update swaps unit test mocks (#44627)
c6fc026ec2 chore: refactor ESLint overrides (#44663)
6fb3e32f55 bump: valibot to 1.4.2, body-parser to 1.20.6 and 2.3.0 (#44664)
b8c3584c53 fix(notifications): keep announcement home link in tab (#43419)
6e0219f5d6 chore: skip linting Jest snapshots (#44665)
a84d6539f5 feat: render high rate alert modal in batch sell review page (#44646)
0d81022be0 feat: integrate STX failTransaction fix (bridge stuck-pending) (#44372)
8f66b8fc55 feat: add bottom nav bar source to perps view events (#44611)
6fb1d6ba46 chore: update @metamask/gator-permissions-snap to version 2.4.0 (#44499)
9b12c19790 test: cover Empty Buy Banner Displayed event (#44617)
6c0217c496 feat: add bottom nav transitions (#44641)
8ae5ce634e chore: use same toaster-bottom-offset var for legacy toasts (#44654)
5da5008a3a test: MMQA - 1975 - Enhance feature flag validation/drift PR to omit re-orders without value change (#43814)
261773c0bb test: fix flaky tests Check balance For a non 0 balance account... (#44479)
5207d27d9c feat: add bottom nav experiment display logic and e2e tests (#44403)
1f66fc6cd7 release: Bump main version to 13.42.0 (#44642)
9962ac769f feat: implement close positions with limit orders (#44466)
477be3b0bc feat(e2e): add Tron test fixtures and environment helpers (#44160)
ffd91160c9 fix: various fixes and improvements on batch sell select page (#44603)
e091fe0b04 fix(assets): wire tempMigrateAssetsInfoMetadataAssets3346 into AssetsController init (#44303)
b685e6bf62 test: MMQA - 2034 - Fix antipatterns in qr-sync.spec.ts (#44600)
1548788667 bump: multiple to fix audit cp-13.41.0 (#44634)
6647504ca3 feat: consume backend-suggested slippage in unified swap/bridge (#44537)
e29c451b29 feat: import alias via node subpath imports (#44621)
f7f67d320b feat(ramps): add provider selection page with async quotes (#44553)
e9b745e8e5 chore: remove dead code (#44612)
bb5e12f804 refactor: migrate multichain review permissions toast (#44505)
fc5d600b60 refactor: add useEventListener (#44596)
d8c683d6c9 feat(e2e): add Tron swap token registry and quote fixtures (#44159)
39d6aa6899 refactor: migrate buy button toast (#44510)
4fa405c7e6 fix: dedicated convert mUSD details cp-13.41.0 (#44586)
a6942d1c60 feat(support): replace raw profile params with customer service token (#44482)
d4987093b8 refactor: migrate delete metametrics toast (#44503)
22c64b7f3f refactor: migrate permissions disconnect-all toast (#44504)
227a3644f0 feat(ramps): show per-method quotes on payment selection (#44526)
abc8a8267c feat: update bottom bar navigation to swaps page (#44233)
3784ae3945 feat: added decimal validation for custom token import flow cp-13.41.0 (#44602)
b495bf455d chore: patch @metamask/assets-controller for suggested occurrence floors (#44525)
88bc6591dc feat(ci): add Runway orchestrator starter and store submission CODEOWNERS (#44017)
1894816b17 refactor(analytics): remove MetaMetricsController shims and finish background migration (#44380)
c4af8823c1 feat(hardware-wallets): add signing page orchestrator (#43943)
e8baf89ff4 fix(ci): align Extension RC Slack notes with Mobile Runway changelog (#44597)
7bfc16cfc0 bump: Upgrade @sentry/browser from 8.33.1 to 10.38.0 (#42867)
a25c6a5b07 chore(6932): convert final legacy context consumers to useI18nContext for React 19 (#44493)
9b908f58d4 test: fix Add wallet Import wallet using json file - TimeoutError: Waiting for element to be located By(css selector, [data-testid="choose-wallet-type-import-account"]) (#44464)
6183003c90 refactor: resolve activity list redesign (#44365)
576a79fa6d chore: allow history navigate on activity details (#44467)
593690c0f7 chore: remove browserify (#44433)
1456a2100a fix: keep bridge activity item as pending until dest tx resolves cp-13.40.0 (#44536)
aa09362f39 fix: don't hold the KeyringController lock during hardware wallets reads (#44483)
0f5ef841a3 refactor(activity): handle swaps missing destination token (#44501)
5d12649353 test: fix flakyTest Snap getEntropy can use snap_getEntropy inside a snap (#44458)
ad3fb497ce refactor(confirmations): address send asset picker review follow-ups (#44431)
b6449df15d feat(ramps): update remaining entrypoints to use goToBuy (#44440)
8a1ccdc82c feat: gate scam questionnaire behind LaunchDarkly flag cp-13.40.0 (#44496)
c0e7a119d7 fix: mascot being rendered twice in onboarding unlock page (#44533)
4c7819aff3 fix: prevent duplicate events during tab switch (#44528)
360bc7d616 fix: bump network enablement controller to v5.6.0 (#44371)
e2f4454072 feat(ramps): add payment method selection page (#44437)
d11fa4a85a refactor: migrate gas fee token toast (#44468)
b48258de3b feat(e2e): add Tron local node mock proxy (#44157)
e149e9c519 feat: update bridge status controller to latest release (#44515)
2ba671463a bump: websocket-driver to fix audit (#44513)
8b843741f8 fix(ramps): wait for selected token before leaving token selection (#44497)
449919f484 fix: crash when typing a comma in the MM Pay custom amount input (#44521)
81ed3e6cb7 fix(ramps): keep provider label while quotes load on build quote (#44491)
e294e5fbc3 chore(tokens): remove stale token cache fallbacks (#44522)
b3a729e909 build: remove submodule added by mistake (#44514)
40f4844d3e feat: sentry for QrSync (#44487)
173e9e7a04 feat: added transitions to manage tokens page (#44484)
be631b56fa refactor: switch activity mappers to @metamask/client-utils (#44366)
41ca3b93c3 fix: Bump react-data-query (#44520)
0cd688b4bf refactor(analytics): migrate orphan multichain accounts UI events (#44376)
4400dd58c1 feat: added skeleton fr balance loading state (#44429)
397c4485f0 chore: use skeleton on loading activity screen (#44423)
29b6f2e924 chore: Revert "chore(6926): migrate ReactDOM.render to createRoot (#43872)" (#44517)
743cccdd2a refactor(analytics): migrate orphan account overview tabs events (#44375)
9efc6d62ed chore(6926): migrate ReactDOM.render to createRoot (#43872)
83d763aaa4 perf(6600): fix asset selector cache thrashing for NFTs and token scan results (#44473)
21c3992646 feat: added transitions to Dapp connections pages (#44481)
1d44802063 fix: consume local history data for bridges on activity items (#44488)
bf71e30756 refactor(analytics): migrate orphan UX contacts and chrome events (#44374)
f1c3e4103c feat(e2e): extend Tron mocks with swap tokens, stateful accounts, and parameterized fixtures (#44485)
8c0fa5b830 perf(6601): fix parameterized selector cache thrashing for chain-checking selectors (#44474)
c255a1a983 feat(perps): show ticker next to volume and fix symbol display consistency (#44478)
b169cbc8fc fix: updated analytis for add token (#44486)
d0a5db3726 feat(ramps): add build quote page with quote fetching (#44409)
4eabcbe89b chore(6931): migrate class components from defaultProps to default params (#44299)
56e0cbf45f perf(6929): harden UI effects for React 18 StrictMode double-mount (#44298)
55e0419dce perf(6602): prevent cache thrashing in parameterized network lookups (#44475)
72c5dccaa4 chore(6930): update React Compiler target to v18 (#44476)
9b7cd98c49 feat: updated CODEOWNERS for QrSync (#44465)
f2018259e3 test: QrSync e2e for multi SRP flows (#44438)
dc5bc8dc93 test(e2e): add Bitcoin send flow against local regtest node (#44156)
e34d7e67bb test: Add E2E max balance validation test (#43821)
2ff51fd902 fix: ensure stellar assets show correctly in token details page (#44444)
77cf93f811 chore: tiny header adjustments on new bottom nav pages (#44470)
fe2bc9df7d test: MMQA - 1971 - Fix missnamed test tokens/nft/filter-nfts.spec.ts same as view-nft-details.spec.ts (View NFT details) (#44086)
f5d4634e8b perf(7475): adopt useDeferredValue for search and filter surfaces (#44443)
23a9a0e228 feat(e2e): add Bitcoin regtest node wrapper using @metamask/bitcoin-regtest-up (#44155)
1986666442 feat: updated token management toggle button (#44434)
a74972d532 feat: ux improvemnets for add via chainlist feature (#44424)
bfb0b29226 test: fix flaky test Vault Corruption does not reset metamask state when recovery is not confirmed (#44435)
ccadeeeccd chore: New Crowdin Translations by GitHub Action cp-13.40.0 (#44329)
3f7584b6f0 fix: QR Sync session timeout and cancellation (#44422)
8b02f4a613 chore: reduce Sentry trace sampling cp-13.40.0 (#44451)
7cd63e4d54 perf(6778): add useStateSyncHealth hook for stale sync auto-recovery (#44389)
80a76d63d4 bump: ws to fix audit (#44459)
f602fae822 refactor: migrate perps withdraw transaction toast (#44419)
81bacd28ee fix(sentry): Resolve AggregatedBalanceSelector transaction volume spike by not passing trace into getAggregatedBalanceForAccount cp-13.40.0 (#44449)
ba18ce10ac feat(ramps): intent routing in goToBuy + stub buy pages (#44404)
2e477542ab ci(token-exchange): migrate FIXTURE_UPDATE_TOKEN to token exchange service (#43838)
2ff80c450e test(e2e): run Solana send flow against local validator (#44154)
baab980461 fix: resolve Perps deposit confirmation stuck on loading skeleton on first open (#44247)
a9f826964b ci: remove requirement for "auto-rc-builds" label (#44421)
3e52ec5ffb perf(7467): memoize composite derived state in home container and dapp bar (#44354)
8846ae56e5 feat(ramps): geo-blocking UI for ramps entry points (#44351)
c496204040 feat(e2e): add Solana local validator wrapper using @metamask/solana-… (#44426)
71f9467411 feat: reintroduce saved gas settings (#43317)
25d7175ff4 chore: nav to perps funding screen on perps funded activity details (#44427)
7657dcc0da fix: render in flight perps deposit/withdraw activity details (#44425)
78908aa279 fix(confirmations): address enforced simulations papercuts (#44343)
4b01eb4a84 feat(ramps): add in-extension token selection page (#44349)
eb3b6f521a fix(perps): mask open order size and value in privacy mode (#44432)
c6c99ecced ci(INFRA-3680): rename bot reference from mm-token-exchange-service to metamask-ci (#44387)
594bbd6f6c test: QrSync E2E (main flow) (#44381)
612334352b refactor: migrate musd claim toast (#44414)
d22a7b6118 chore: bump @metamask/tron-wallet-snap to ^1.31.0 cp-13.40.0 (#44385)
a396544397 chore: use candlestick filled icon when perps bottom nav active (#44388)
70a302b923 feat: refresh activity list after confirm (#44333)
ea74194fd2 feat: sync-accounts use image for qr code (#44417)
4631b6103f fix(mv3): move keep-alive polling to service worker startup (#44348)
5dd78ebf23 refactor(analytics): migrate settings thunk MetaMetrics events (#44379)
b400e49380 refactor(analytics): migrate orphan platform metrics UI events (#44378)
1e0188a092 perf(7465): memoize token list derivations and lift per-row Redux subscriptions to parent (#44295)
e9d9c6cd75 fix: fixed race condition on vault creation and get seedphrase (#44276)
5418dedc88 chore(preferences): remove enableMV3TimestampSave debug preference (#44373)
5bfa8fe8fb chore(6925): upgrade react & react-dom to v18 (#42997)
d3fa3dd51b chore: update CODEOWNERS bringing more code under team money-movement (#44408)
485109f500 chore: deprecated import path (#43242)
dec283a8fe refactor(analytics): migrate orphan Web3Auth onboarding events (#44377)
5291e67aa5 refactor: remove headless STX status page approval (#44301)
909c8d60b2 docs: Add Cursor Skill to automatically add new EVM networks to swaps (#44386)
4a4948b41b fix: update trackImportEvent usage to use correct params and string comparison (#44400)
355bc49105 feat: Bump Snaps packages (#44396)
cd8907a7aa perf(7467): memoize hooks/components with multiple selectors (#44297)
7c8966dd69 feat(e2e): wire Tron local node into fixtures (#44152)
82af0c7e26 fix(assets): restore google.svg and relocate to app/images/ cp-13.40.0 (#44383)
b977317023 feat(asset): migrate asset routes to CAIP-19 identifiers (#44114)
0ebadf7dd6 feat: QR sync error UI (#44081)
615c3a8fe1 feat: rename add-device to sync-accounts (#43870)
a329b0473b fix: extra pending row from local state cp-13.40.0 (#44359)
b7c7eef85a feat: wallet metadata and imported account sync via QR (#44047)
b426596c9c perf: add useMemo/useCallback memoization to home balance components (#44294)

AI Test Plan

Risk Score High Risk Medium Risk Files Changed Commits
61/100 8 5 1684 125
Release Scenarios (13)

High Risk Scenarios (8)

1. State Migrations (217–219): Core wallet state on upgrade

Risk Level: HIGH

Why This Matters: Multiple new migrations can corrupt or reset critical user state (accounts, networks, assets, permissions) if misapplied.

Test Steps:

  1. On 13.41.x, create 2 accounts, import 1 account via private key, add 1 custom network (EVM), connect 2 dapps (different sites) to different accounts, add 3 custom tokens and 1 NFT on two networks.
  2. Upgrade to 13.42.0 and unlock; do not clear storage.
  3. Verify accounts and labels persist, balances load, custom network is present and selected state is remembered.
  4. Confirm tokens/NFTs still appear on the correct networks with correct balances/metadata; portfolio total loads without errors.
  5. Open Connected Sites and verify per-account permissions are intact; attempt a tx/signature from a previously connected site to confirm it still works.

2. Permissions migration: Connected Sites per-account integrity

Risk Level: HIGH

Why This Matters: Migrations that touch permissions risk cross-account leakage or broken connections, directly impacting security and dapp usability.

Test Steps:

  1. Before upgrade, connect Site A to Account 1 and Site B to Account 2; keep both tabs open.
  2. Upgrade to 13.42.0, unlock, and visit both tabs.
  3. Switch active account and verify the site shows the correct connected account (or unconnected warning) without silent re-permission.
  4. From Site A (should be connected to Account 1), request eth_accounts and send a simple personal_sign; confirm the right account is used.
  5. From Site B (Account 2), attempt a transaction; confirm the confirmation shows the correct origin and connected account.

3. Token Management: Assets Controller v11 – auto-detect and manual add

Risk Level: HIGH

Why This Matters: A major Assets Controller bump can change detection, metadata, and fiat price handling—errors here misrepresent balances and can trigger user loss.

Test Steps:

  1. On Ethereum Mainnet, ensure token auto-detection is enabled; hold a low-cap ERC-20 and a popular ERC-20; refresh and verify both appear with correct symbol/decimals.
  2. Manually add a custom ERC-20 by contract address; confirm correct symbol/decimals pre-fill and it appears without duplication.
  3. Switch to a secondary network (e.g., Polygon) with different holdings; verify network-scoped token lists and balances are correct.
  4. Remove/hide a token and re-enable detection; confirm it doesn’t reappear unless explicitly restored.
  5. Verify fiat conversion displays for detected and manually added tokens, and totals update after a balance change.

4. NFTs: Detection, metadata, and visibility

Risk Level: HIGH

Why This Matters: Changes in asset controllers can break NFT indexing or metadata resolution, leading to missing or incorrect collectibles.

Test Steps:

  1. Hold one ERC-721 and one ERC-1155 on Mainnet; enable NFT detection and open the NFTs tab.
  2. Verify tokens appear with correct images, names, and quantities; use Refresh Metadata and confirm assets update correctly.
  3. Hide an NFT and verify it no longer appears; unhide and confirm it re-displays correctly.
  4. Switch to another network with no NFTs; confirm no cross-network bleed-through.
  5. Open the NFT details screen and confirm actions (send, view on explorer) behave correctly.

5. Security: Unconnected account alert during approvals/signatures

Risk Level: HIGH

Why This Matters: Updated alert components and tests target this flow; regressions here can cause accidental approvals from unintended accounts.

Test Steps:

  1. Connect Site A to Account 1; in the extension, switch the active account to Account 2.
  2. From Site A, initiate a transaction or a sign request; wait for the confirmation/approval screen.
  3. Verify the Unconnected Account alert appears and clearly indicates the mismatch.
  4. Switch to the connected account from the confirmation screen (if supported) or cancel and retry with the connected account; verify the alert no longer shows.
  5. Confirm the action succeeds only when using the connected account and is blocked/warned otherwise.

6. Message encryption flows: eth_getEncryptionPublicKey and eth_decrypt

Risk Level: HIGH

Why This Matters: Controller changes in decrypt/encryption flows directly affect sensitive cryptographic operations and data privacy.

Test Steps:

  1. From a test dapp, request eth_getEncryptionPublicKey for the active account; confirm a clear permission prompt, approve, and verify a valid key is returned.
  2. Use the returned key to encrypt a message; call eth_decrypt and approve the request; verify the original plaintext is returned.
  3. Switch to a different active account; repeat decrypt for the same ciphertext and verify the request fails gracefully.
  4. Reject the permission or decrypt request and confirm the dapp receives a well-formed error and no data leak.
  5. Revoke site permissions and retry to confirm re-prompting works as expected.

7. Network Management: dapp-triggered add/switch network (addEthereumChain/switch)

Risk Level: HIGH

Why This Matters: Controller patches around network enablement can break or weaken validation, causing failed switches or unsafe network additions.

Test Steps:

  1. From a dapp, call wallet_addEthereumChain with a new chain (valid RPC, explorer, currency); verify a clear, safe approval screen and add the network.
  2. Confirm chain icon/name/currency render correctly and RPC is reachable (account balance loads).
  3. From the same dapp, call wallet_switchEthereumChain to the newly added network; verify the switch prompt and that the active network changes.
  4. Attempt an invalid addEthereumChain (malformed chainId or missing RPC); verify the error UI and no partial network entry is created.
  5. Remove the added network from settings and verify it disappears and can be re-added.

8. Transaction submission: RPC/gas errors surfaced via API Error Handler

Risk Level: HIGH

Why This Matters: Changes to API error handling can leave users stuck during critical send flows or mask important failure details.

Test Steps:

  1. Initiate a send on Mainnet to a valid address; temporarily use a failing RPC endpoint or force a gas estimation error.
  2. On the confirmation screen, verify descriptive inline/banner error messaging appears (not a silent spinner or generic error).
  3. Edit gas settings to a safe preset or custom; verify errors clear when valid and the action can proceed.
  4. Submit the tx and confirm failure surfaces a clear reason with a retry path; cancel behaves cleanly without leaving stale UI.
  5. Restore a healthy RPC and confirm normal flow succeeds.

Medium Risk Scenarios (5)

1. Signature requests: personal_sign and typed data (EIP-712)

Risk Level: MEDIUM

Why This Matters: Large UI and controller diffs risk regressing signature rendering or account-context handling.

Test Steps:

  1. From a dapp, trigger a personal_sign request; verify the confirmation shows origin, account, readable message, and correct warnings.
  2. Trigger an EIP-712 signTypedData_v4; verify domain, message, and chain are rendered correctly.
  3. Reject then reattempt and approve; confirm results are returned accurately to the dapp.
  4. Switch accounts between requests and confirm the confirmation matches the active/connected account information.

2. Alerts system: stacking, dismissal, and confirm flows

Risk Level: MEDIUM

Why This Matters: Broad changes to alert components and utilities can cause missing alerts, incorrect stacking, or action misfires.

Test Steps:

  1. Trigger multiple alert types in quick succession (e.g., insufficient funds, unconnected account, network mismatch).
  2. Verify alerts stack/order properly in the multiple-alert modal and inline contexts.
  3. Dismiss one alert and confirm others remain and their actions still function.
  4. Use a confirm alert modal (e.g., reset account nonce or clear activity); verify confirm/cancel paths behave correctly and state updates accordingly.

3. Bridge: quote retrieval and handoff

Risk Level: MEDIUM

Why This Matters: Bridge controller patching can break quote fetching or routing, stranding users mid-flow.

Test Steps:

  1. Open the Bridge entry in the extension (if available) and search quotes for a supported asset from Chain A to Chain B.
  2. Verify quotes load with correct routes and fees; change amount and observe quote refresh correctness.
  3. Select a quote and proceed; confirm handoff to the appropriate provider or external UI works (no blank screens).
  4. Trigger an error case (unsupported asset or unreachable API) and verify a clear error is shown with recovery guidance.

4. Portfolio/Fiat display: token price and totals

Risk Level: MEDIUM

Why This Matters: Asset controller changes can affect pricing sources and conversion logic, risking misleading balances.

Test Steps:

  1. With several tokens on one network, open the Assets tab and confirm each token shows fiat values and a correct portfolio total.
  2. Switch primary currency (e.g., USD to EUR) and verify all conversions update consistently.
  3. Switch networks and verify totals are network-scoped (where applicable) and do not double-count.
  4. Temporarily disconnect from the internet and reopen the Assets tab; verify graceful degradation (cached values or clear messaging).

5. Network switching within the extension (picker and per-account)

Risk Level: MEDIUM

Why This Matters: Controller and UI refactors can subtly break network-context state, confusing users and dapps.

Test Steps:

  1. Use the network picker to switch between Mainnet and a custom network; verify the active network indicator updates immediately.
  2. Change the active account and switch networks again; confirm state stays consistent (no token list leakage across networks).
  3. Return to a previously used network and verify last-selected token/NFT tab persists appropriately.

Teams Sign-off Status

Signed off: None yet

Awaiting sign-off (9):
Accounts, Assets, Networks, Permissions, Security, Swaps and Bridge, Transactions, Wallet, Wallet Integrations


Generated by AI Test Plan Analyzer (gpt-5) at 2026-07-23T23:55:51.210Z

AI generated test plan (JSON): test-plan-13.42.0.json

…lower viewport cp-13.42.0 (#44854)

- feat: keep the balance left aligned for lower viewport cp-13.42.0
(#44791)

This PR is to make sure that the balance is left aligned for smaller
viewports


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

## **Related issues**

Fixes:

## **Manual testing steps**

1. Go to this page...
2.
3.

## **Screenshots/Recordings**

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

### **Before**

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

### **After**




https://github.com/user-attachments/assets/91524f4d-55e2-44ca-8f00-71a89b3c2f98


## **Pre-merge author checklist**

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

Standards](https://github.com/MetaMask/metamask-extension/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-extension/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**
> Presentation-only layout changes in wallet overview with no auth,
data, or business-logic impact.
> 
> **Overview**
> **Wallet overview balance alignment** is updated so the sidepanel
keeps the balance **left-aligned** when the viewport is at or below
**490px**, while fullscreen/sidepanel layouts still **center** the
balance on wider widths.
> 
> Adds a **`wallet-overview-sidepanel`** class on the sidepanel
environment and a shared SCSS mixin that applies `start` alignment under
that breakpoint for the balance block, coin overview balance, and
loading skeleton. Inline Tailwind alignment on the balance wrapper and
skeleton is removed in favor of these styles, and the sidepanel
max-width is centralized as a SCSS variable.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
e2e6500. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
[5d2cff8](5d2cff8)

Co-authored-by: Nidhi Kumari <nidhi.kumari@consensys.net>
… cp-13.42.0 (#44856)

- fix(activity): transaction details width (#44853)

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

Align the activity transaction details max-width with the recently
updated app max width

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: #44840

## **Manual testing steps**

1. Open Activity and click a transaction.
2. Resize the window through narrow, mid (~600–900px), and wide widths.
3. Confirm details always match the app content width with no Activity
showing around the edges.
4. Repeat in sidepanel while resizing the panel.

<!--
## **Screenshots/Recordings**

### **Before**

### **After**
-->

## **Pre-merge author checklist**

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

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

guidelines](https://github.com/MetaMask/metamask-extension/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.

Made with [Cursor](https://cursor.com)

Co-authored-by: Cursor <cursoragent@cursor.com>
[b6619a9](b6619a9)

Co-authored-by: Francis Nepomuceno <n3ps@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@metamask-ci

metamask-ci Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor
Builds ready [5738947]
⚡ Performance Benchmarks (Total: 🟢 16 pass · 🟡 4 warn · 🔴 4 fail)

Baseline (latest main): b6619a9 | Date: 7/24/2026 | Pipeline: 30110927837 | Baseline logs

Metricschrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🔴 metricsToWalletReadyScreen(p95) [CI log]🔴 [CI log]
onboardingNewWallet
[Sentry log · main/release]
🔴 srpButtonToPwForm(p95) [CI log]🔴 [CI log]

Regressions (🔴 4 failures)

Interaction Benchmarks · Samples: 5
Benchmarkchrome-webpackfirefox-webpack
loadNewAccount
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
confirmTx
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
bridgeUserActions
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • loadNewAccount/inp: -20%
  • loadNewAccount/fcp: -13%
  • loadNewAccount/lcp: +711%
  • confirmTx/longTaskTotalDuration: -22%
  • confirmTx/longTaskMaxDuration: -30%
  • confirmTx/tbt: -41%
  • confirmTx/inp: -29%
  • confirmTx/fcp: -22%
  • bridgeUserActions/bridge_load_page: -26%
  • bridgeUserActions/bridge_load_asset_picker: -31%
  • bridgeUserActions/longTaskCount: -38%
  • bridgeUserActions/longTaskTotalDuration: -42%
  • bridgeUserActions/longTaskMaxDuration: -20%
  • bridgeUserActions/tbt: -54%
  • bridgeUserActions/inp: -21%
  • bridgeUserActions/fcp: -20%
  • loadNewAccount/inp: -28%
  • loadNewAccount/fcp: -55%
  • loadNewAccount/lcp: +1192%
  • confirmTx/confirm_tx: +15%
  • confirmTx/longTaskCount: -100%
  • confirmTx/longTaskTotalDuration: -100%
  • confirmTx/longTaskMaxDuration: -100%
  • confirmTx/tbt: -100%
  • confirmTx/total: +15%
  • confirmTx/fcp: -46%
  • confirmTx/lcp: +1215%
  • bridgeUserActions/bridge_load_page: +285%
  • bridgeUserActions/bridge_load_asset_picker: +164%
  • bridgeUserActions/longTaskCount: -100%
  • bridgeUserActions/longTaskTotalDuration: -100%
  • bridgeUserActions/longTaskMaxDuration: -100%
  • bridgeUserActions/tbt: -100%
  • bridgeUserActions/total: +202%
  • bridgeUserActions/inp: -29%
  • bridgeUserActions/lcp: +1175%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 bridgeUserActions/FCP: p75 1.9s
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
startupPowerUserHome
[Sentry log · main/release]
🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/uiStartup: +19%
  • startupStandardHome/load: +17%
  • startupStandardHome/domContentLoaded: +18%
  • startupStandardHome/domInteractive: +13%
  • startupStandardHome/firstPaint: +17%
  • startupStandardHome/backgroundConnect: +18%
  • startupStandardHome/firstReactRender: +21%
  • startupStandardHome/loadScripts: +18%
  • startupStandardHome/setupStore: +19%
  • startupStandardHome/longTaskTotalDuration: +18%
  • startupStandardHome/longTaskMaxDuration: +16%
  • startupStandardHome/tbt: +20%
  • startupStandardHome/inp: +20%
  • startupStandardHome/fcp: +16%
  • startupStandardHome/lcp: -23%
  • startupStandardHome/domInteractive: +55%
  • startupStandardHome/initialActions: +11%
  • startupStandardHome/fcp: +56%
  • startupPowerUserHome/backgroundConnect: +29%
  • startupPowerUserHome/setupStore: +127%
  • startupPowerUserHome/inp: +11%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 startupPowerUserHome/INP: p75 232ms
  • 🟡 startupPowerUserHome/LCP: p75 3.6s
User Journey Benchmarks · Samples: 5 · real API 🔴 4
Benchmarkchrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🔴 [CI log]
🔴 doneButtonToHomeScreen
🔴 total
🔴 [CI log]
🔴 total
onboardingNewWallet
[Sentry log · main/release]
🔴 [CI log]
🔴 total
🔴 [CI log]
🔴 total
assetDetails
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
solanaAssetDetails
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
importSrpHome
[Sentry log · main/release]
🟡 [CI log]🟢 [CI log]
sendTransactions
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
swap
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]

📈 Results compared to the previous 5 runs on main

  • onboardingImportWallet/metricsToWalletReadyScreen: +38%
  • onboardingImportWallet/doneButtonToHomeScreen: -38%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: -70%
  • onboardingImportWallet/longTaskCount: -33%
  • onboardingImportWallet/total: -41%
  • onboardingNewWallet/srpButtonToPwForm: +10%
  • onboardingNewWallet/doneButtonToAssetList: +13%
  • onboardingNewWallet/longTaskTotalDuration: +21%
  • onboardingNewWallet/longTaskMaxDuration: +12%
  • onboardingNewWallet/tbt: +19%
  • onboardingNewWallet/total: +13%
  • solanaAssetDetails/assetClickToPriceChart: -14%
  • solanaAssetDetails/longTaskCount: -100%
  • solanaAssetDetails/longTaskTotalDuration: -100%
  • solanaAssetDetails/longTaskMaxDuration: -100%
  • solanaAssetDetails/total: -14%
  • solanaAssetDetails/inp: -13%
  • importSrpHome/homeAfterImportWithNewWallet: -17%
  • importSrpHome/longTaskMaxDuration: +20%
  • importSrpHome/tbt: +11%
  • importSrpHome/total: -17%
  • importSrpHome/inp: -16%
  • sendTransactions/selectTokenToSendFormLoaded: -36%
  • sendTransactions/reviewTransactionToConfirmationPage: -81%
  • sendTransactions/longTaskCount: -100%
  • sendTransactions/longTaskTotalDuration: -100%
  • sendTransactions/longTaskMaxDuration: -100%
  • sendTransactions/tbt: -100%
  • sendTransactions/total: -79%
  • sendTransactions/inp: -37%
  • sendTransactions/fcp: -20%
  • sendTransactions/lcp: +605%
  • swap/openSwapPageFromHome: -34%
  • swap/fetchAndDisplaySwapQuotes: -35%
  • swap/longTaskCount: -100%
  • swap/longTaskTotalDuration: -100%
  • swap/longTaskMaxDuration: -100%
  • swap/tbt: -100%
  • swap/total: -34%
  • swap/inp: -22%
  • swap/fcp: -28%
  • swap/lcp: -24%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 importSrpHome/INP: p75 280ms
  • 🟡 importSrpHome/FCP: p75 1.8s
  • 🟡 solanaAssetDetails/FCP: p75 1.9s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]
Bundle size diffs
  • background: 210 Bytes (0%)
  • ui: 126 Bytes (0%)
  • common: 0 Bytes (0%)
  • other: 0 Bytes (0%)
  • contentScripts: 0 Bytes (0%)
  • zip: 214 Bytes (0%)

🍒 What's in this RC

Cherry-picks (5 commits)
Commit Description
5738947439 release(runway): cherry-pick fix(activity): transaction details width cp-13.42.0 (#44856)
a8682562fc release(runway): cherry-pick feat: keep the balance left aligned for lower viewport cp-13.42.0 (#44854)
189763ce27 release(cp): cherry-pick fix(assets): include tokens with large balances and few decimals in aggregated balance cp-13.41.0
8423f220d3 release: release-changelog/13.42.0 (#44798)
0c93b31dd8 Merge release/13.41.0 into release/13.42.0

Changelog (223 commits from main at RC cut)
Commit Description
446c5a25b5 fix: apply bg-alternative to legacy Popover in pure black theme (#44730)
c2c37a8a68 fix: apply border-muted to global menu drawer in pure black theme (#44729)
7e15155002 chore: remove unused legacy modals from ui/components/app/modals (#44731)
b03252588b fix: add device response timeout to Trezor bridges (#44626)
9ee3d987a7 feat: show skeleton for the whole balance block if the balance is not cached (#44703)
960369d180 fix: require interstitial for CAIP-19 asset deep links (#44639)
ef34172a99 refactor: migrate formatters to client-utils (#44624)
88c41e5489 test: cover Wallet Creation Attempted Segment event (#44673)
7a14cd7f6c feat: Updated the styles for swaps page (#44762)
ad64202e93 test: MMQA - 2035 - Fix antipatterns in sendPage which can lead to flakiness (#44640)
845b4a8f4a feat: updated avatarbase and banner alert to use DS (#44763)
3802fdba7c chore: migrate AvatarFavicon to MMDS (#44764)
a1b13be185 feat: seedless controller v10.1.0 (#44771)
864f5e5294 fix: patch bridge controller to exclude Stellar and Arc cp-13.41.0 (#44749)
ab4fbefa8d fix: non-evm bridge activity (#44751)
62fd747287 chore: removed deprecated checkbox with DS (#44765)
643d4d57cc test: added e2e tests for the new logic showing energy and bandwidth in sign transaction confirmation (#44756)
0fd8198e4b chore: remove border from pages (#44721)
1910a59ff9 feat(ledger): wire ledgerDmk flag to offscreen mode switching (#43488)
56f0a34156 chore: introduce bulk error suppression (#44739)
bd13fb6ec3 chore: updated networks for hardware accounts (#44531)
ab79e887a9 fix: updated search to be sticky and banner to scroll cp-13.41.0 (#44696)
34148d362e test(tron): prepare daily resources for E2E coverage (#44162)
4cd1d95222 chore: bump @metamask/tron-wallet-snap to ^1.33.1 (#44716)
906fee2c9d chore: bump assets controllers and remove patches (#44713)
dad0511577 test: fix flaky QrSync multi-SRP import confirm staleness timeout (#44700)
d50de2fac4 fix(metametrics): silence unmatched route Sentry noise for known paths (#44718)
4103808cae fix(ci): Remove "What's in this RC ...and more changes" section to match Extension RC Slack message to Mobile layout cp-13.41.0 (#44740)
7b2c1b2665 chore: update to ESLint v9 (#44734)
9faf0a6b5d feat: apply bg-alternative and border-muted to legacy Modal in pure black mode (#44726)
969f5c2aaa chore: update swap row labels (#44637)
2aa9b938e0 feat: apply bg-alternative and border-muted to ModalContent dialog in pure black mode (#44720)
9e40a87367 chore: New Crowdin Translations by GitHub Action cp-13.41.0 (#44595)
3ea61fd698 chore: remove unused ESLint directives from shared (#44679)
07651ccf9c chore: remove unused ESLint directives from ui/components (#44683)
0b58311684 chore: remove unused ESLint directives from remaining ui (#44685)
148b0844e4 bump: sharp to 0.35.3 (#44688)
ad1bbf43ce feat: show verified badge on swaps token button (#44623)
d5047c3a86 chore: replace sub tab screen opened metrics (#44093)
bb150a4058 feat: added skeleton for token list after stale open (#44705)
1d3f77fb38 ci: Harden absolute benchmark gate against within-noise breaches (#44609)
f3bd7f870e chore: align dapp connection bar styling with Figma spec (#44539)
42315a4087 feat: navigate users to batch sell through deeplink (#44671)
396263b848 chore: remove unneeded styles (#44693)
2acd3840a2 refactor(activity): use native dialog for transaction details (#44599)
65292d06fb bump: immutable to 5.1.9, fast-uri to 3.1.4, dompurify to 3.4.12, sass-embedded to 1.100.0 cp-13.41.0 (#44678)
57638a9616 chore: remove unused ESLint ignore directives from development (#44676)
7cb3eb6037 chore: split eslint ignore react-compiler directives (#44686)
14c815595a chore: remove unused ESLint directives from ui/pages (#44684)
8eac23857c chore: remove unused ESLint ignore directives from app (#44674)
8d99a5f7d3 test: fix flaky tests Add wallet Import wallet... (#44649)
4a1c57b063 test: fix flaky test Add account added account should persist after wallet lock (#44712)
2b218f3e77 chore(eslint): ignore .yarn and webpack build directory (#44666)
67b21b1e1b chore: update transaction controller (#44656)
77c6773132 chore: adds handler for top-traders (Follow Trading) deeplink redirect (#44660)
bceab0bb1e chore: bump @metamask/tron-wallet-snap to ^1.33.0 (#44698)
fa3885cf81 feat: setup for new defi flag (#44652)
0afcd07800 test: refactor snap-account-abstraction page object to remove references to other page objects (#44690)
3051cf4133 test: refactor account-list page object to remove references to other page objects (#44651)
edb7daa756 fix: clear orphaned advancedGasFee preference (migration 216) (#44205)
59f15bc6b0 fix: remove useAssetActivation test to unblock assets controllers bump up (#44699)
52b4b3d877 feat: removed back transitions unused selector (#44691)
f9f5e1dc48 fix: update slider step to one in batch sell (#44648)
a7847a0538 fix: do not render assets without quotes in review modal (#44650)
efa96b445e refactor: use modern clipboard api (#44622)
80b66e6c4e chore: removed sidepanel viewport max width constraint (#44647)
6d970c423d test: encryption and decryption Segment events (#44607)
1ff9bf422b chore: remove unused ESLint ignore directives from test directory (#44669)
2518a3727c feat(ui): add pure-black dark mode behind build-time flag (#44183)
d07ea1771f test: update swaps unit test mocks (#44627)
c6fc026ec2 chore: refactor ESLint overrides (#44663)
6fb3e32f55 bump: valibot to 1.4.2, body-parser to 1.20.6 and 2.3.0 (#44664)
b8c3584c53 fix(notifications): keep announcement home link in tab (#43419)
6e0219f5d6 chore: skip linting Jest snapshots (#44665)
a84d6539f5 feat: render high rate alert modal in batch sell review page (#44646)
0d81022be0 feat: integrate STX failTransaction fix (bridge stuck-pending) (#44372)
8f66b8fc55 feat: add bottom nav bar source to perps view events (#44611)
6fb1d6ba46 chore: update @metamask/gator-permissions-snap to version 2.4.0 (#44499)
9b12c19790 test: cover Empty Buy Banner Displayed event (#44617)
6c0217c496 feat: add bottom nav transitions (#44641)
8ae5ce634e chore: use same toaster-bottom-offset var for legacy toasts (#44654)
5da5008a3a test: MMQA - 1975 - Enhance feature flag validation/drift PR to omit re-orders without value change (#43814)
261773c0bb test: fix flaky tests Check balance For a non 0 balance account... (#44479)
5207d27d9c feat: add bottom nav experiment display logic and e2e tests (#44403)
1f66fc6cd7 release: Bump main version to 13.42.0 (#44642)
9962ac769f feat: implement close positions with limit orders (#44466)
477be3b0bc feat(e2e): add Tron test fixtures and environment helpers (#44160)
ffd91160c9 fix: various fixes and improvements on batch sell select page (#44603)
e091fe0b04 fix(assets): wire tempMigrateAssetsInfoMetadataAssets3346 into AssetsController init (#44303)
b685e6bf62 test: MMQA - 2034 - Fix antipatterns in qr-sync.spec.ts (#44600)
1548788667 bump: multiple to fix audit cp-13.41.0 (#44634)
6647504ca3 feat: consume backend-suggested slippage in unified swap/bridge (#44537)
e29c451b29 feat: import alias via node subpath imports (#44621)
f7f67d320b feat(ramps): add provider selection page with async quotes (#44553)
e9b745e8e5 chore: remove dead code (#44612)
bb5e12f804 refactor: migrate multichain review permissions toast (#44505)
fc5d600b60 refactor: add useEventListener (#44596)
d8c683d6c9 feat(e2e): add Tron swap token registry and quote fixtures (#44159)
39d6aa6899 refactor: migrate buy button toast (#44510)
4fa405c7e6 fix: dedicated convert mUSD details cp-13.41.0 (#44586)
a6942d1c60 feat(support): replace raw profile params with customer service token (#44482)
d4987093b8 refactor: migrate delete metametrics toast (#44503)
22c64b7f3f refactor: migrate permissions disconnect-all toast (#44504)
227a3644f0 feat(ramps): show per-method quotes on payment selection (#44526)
abc8a8267c feat: update bottom bar navigation to swaps page (#44233)
3784ae3945 feat: added decimal validation for custom token import flow cp-13.41.0 (#44602)
b495bf455d chore: patch @metamask/assets-controller for suggested occurrence floors (#44525)
88bc6591dc feat(ci): add Runway orchestrator starter and store submission CODEOWNERS (#44017)
1894816b17 refactor(analytics): remove MetaMetricsController shims and finish background migration (#44380)
c4af8823c1 feat(hardware-wallets): add signing page orchestrator (#43943)
e8baf89ff4 fix(ci): align Extension RC Slack notes with Mobile Runway changelog (#44597)
7bfc16cfc0 bump: Upgrade @sentry/browser from 8.33.1 to 10.38.0 (#42867)
a25c6a5b07 chore(6932): convert final legacy context consumers to useI18nContext for React 19 (#44493)
9b908f58d4 test: fix Add wallet Import wallet using json file - TimeoutError: Waiting for element to be located By(css selector, [data-testid="choose-wallet-type-import-account"]) (#44464)
6183003c90 refactor: resolve activity list redesign (#44365)
576a79fa6d chore: allow history navigate on activity details (#44467)
593690c0f7 chore: remove browserify (#44433)
1456a2100a fix: keep bridge activity item as pending until dest tx resolves cp-13.40.0 (#44536)
aa09362f39 fix: don't hold the KeyringController lock during hardware wallets reads (#44483)
0f5ef841a3 refactor(activity): handle swaps missing destination token (#44501)
5d12649353 test: fix flakyTest Snap getEntropy can use snap_getEntropy inside a snap (#44458)
ad3fb497ce refactor(confirmations): address send asset picker review follow-ups (#44431)
b6449df15d feat(ramps): update remaining entrypoints to use goToBuy (#44440)
8a1ccdc82c feat: gate scam questionnaire behind LaunchDarkly flag cp-13.40.0 (#44496)
c0e7a119d7 fix: mascot being rendered twice in onboarding unlock page (#44533)
4c7819aff3 fix: prevent duplicate events during tab switch (#44528)
360bc7d616 fix: bump network enablement controller to v5.6.0 (#44371)
e2f4454072 feat(ramps): add payment method selection page (#44437)
d11fa4a85a refactor: migrate gas fee token toast (#44468)
b48258de3b feat(e2e): add Tron local node mock proxy (#44157)
e149e9c519 feat: update bridge status controller to latest release (#44515)
2ba671463a bump: websocket-driver to fix audit (#44513)
8b843741f8 fix(ramps): wait for selected token before leaving token selection (#44497)
449919f484 fix: crash when typing a comma in the MM Pay custom amount input (#44521)
81ed3e6cb7 fix(ramps): keep provider label while quotes load on build quote (#44491)
e294e5fbc3 chore(tokens): remove stale token cache fallbacks (#44522)
b3a729e909 build: remove submodule added by mistake (#44514)
40f4844d3e feat: sentry for QrSync (#44487)
173e9e7a04 feat: added transitions to manage tokens page (#44484)
be631b56fa refactor: switch activity mappers to @metamask/client-utils (#44366)
41ca3b93c3 fix: Bump react-data-query (#44520)
0cd688b4bf refactor(analytics): migrate orphan multichain accounts UI events (#44376)
4400dd58c1 feat: added skeleton fr balance loading state (#44429)
397c4485f0 chore: use skeleton on loading activity screen (#44423)
29b6f2e924 chore: Revert "chore(6926): migrate ReactDOM.render to createRoot (#43872)" (#44517)
743cccdd2a refactor(analytics): migrate orphan account overview tabs events (#44375)
9efc6d62ed chore(6926): migrate ReactDOM.render to createRoot (#43872)
83d763aaa4 perf(6600): fix asset selector cache thrashing for NFTs and token scan results (#44473)
21c3992646 feat: added transitions to Dapp connections pages (#44481)
1d44802063 fix: consume local history data for bridges on activity items (#44488)
bf71e30756 refactor(analytics): migrate orphan UX contacts and chrome events (#44374)
f1c3e4103c feat(e2e): extend Tron mocks with swap tokens, stateful accounts, and parameterized fixtures (#44485)
8c0fa5b830 perf(6601): fix parameterized selector cache thrashing for chain-checking selectors (#44474)
c255a1a983 feat(perps): show ticker next to volume and fix symbol display consistency (#44478)
b169cbc8fc fix: updated analytis for add token (#44486)
d0a5db3726 feat(ramps): add build quote page with quote fetching (#44409)
4eabcbe89b chore(6931): migrate class components from defaultProps to default params (#44299)
56e0cbf45f perf(6929): harden UI effects for React 18 StrictMode double-mount (#44298)
55e0419dce perf(6602): prevent cache thrashing in parameterized network lookups (#44475)
72c5dccaa4 chore(6930): update React Compiler target to v18 (#44476)
9b7cd98c49 feat: updated CODEOWNERS for QrSync (#44465)
f2018259e3 test: QrSync e2e for multi SRP flows (#44438)
dc5bc8dc93 test(e2e): add Bitcoin send flow against local regtest node (#44156)
e34d7e67bb test: Add E2E max balance validation test (#43821)
2ff51fd902 fix: ensure stellar assets show correctly in token details page (#44444)
77cf93f811 chore: tiny header adjustments on new bottom nav pages (#44470)
fe2bc9df7d test: MMQA - 1971 - Fix missnamed test tokens/nft/filter-nfts.spec.ts same as view-nft-details.spec.ts (View NFT details) (#44086)
f5d4634e8b perf(7475): adopt useDeferredValue for search and filter surfaces (#44443)
23a9a0e228 feat(e2e): add Bitcoin regtest node wrapper using @metamask/bitcoin-regtest-up (#44155)
1986666442 feat: updated token management toggle button (#44434)
a74972d532 feat: ux improvemnets for add via chainlist feature (#44424)
bfb0b29226 test: fix flaky test Vault Corruption does not reset metamask state when recovery is not confirmed (#44435)
ccadeeeccd chore: New Crowdin Translations by GitHub Action cp-13.40.0 (#44329)
3f7584b6f0 fix: QR Sync session timeout and cancellation (#44422)
8b02f4a613 chore: reduce Sentry trace sampling cp-13.40.0 (#44451)
7cd63e4d54 perf(6778): add useStateSyncHealth hook for stale sync auto-recovery (#44389)
80a76d63d4 bump: ws to fix audit (#44459)
f602fae822 refactor: migrate perps withdraw transaction toast (#44419)
81bacd28ee fix(sentry): Resolve AggregatedBalanceSelector transaction volume spike by not passing trace into getAggregatedBalanceForAccount cp-13.40.0 (#44449)
ba18ce10ac feat(ramps): intent routing in goToBuy + stub buy pages (#44404)
2e477542ab ci(token-exchange): migrate FIXTURE_UPDATE_TOKEN to token exchange service (#43838)
2ff80c450e test(e2e): run Solana send flow against local validator (#44154)
baab980461 fix: resolve Perps deposit confirmation stuck on loading skeleton on first open (#44247)
a9f826964b ci: remove requirement for "auto-rc-builds" label (#44421)
3e52ec5ffb perf(7467): memoize composite derived state in home container and dapp bar (#44354)
8846ae56e5 feat(ramps): geo-blocking UI for ramps entry points (#44351)
c496204040 feat(e2e): add Solana local validator wrapper using @metamask/solana-… (#44426)
71f9467411 feat: reintroduce saved gas settings (#43317)
25d7175ff4 chore: nav to perps funding screen on perps funded activity details (#44427)
7657dcc0da fix: render in flight perps deposit/withdraw activity details (#44425)
78908aa279 fix(confirmations): address enforced simulations papercuts (#44343)
4b01eb4a84 feat(ramps): add in-extension token selection page (#44349)
eb3b6f521a fix(perps): mask open order size and value in privacy mode (#44432)
c6c99ecced ci(INFRA-3680): rename bot reference from mm-token-exchange-service to metamask-ci (#44387)
594bbd6f6c test: QrSync E2E (main flow) (#44381)
612334352b refactor: migrate musd claim toast (#44414)
d22a7b6118 chore: bump @metamask/tron-wallet-snap to ^1.31.0 cp-13.40.0 (#44385)
a396544397 chore: use candlestick filled icon when perps bottom nav active (#44388)
70a302b923 feat: refresh activity list after confirm (#44333)
ea74194fd2 feat: sync-accounts use image for qr code (#44417)
4631b6103f fix(mv3): move keep-alive polling to service worker startup (#44348)
5dd78ebf23 refactor(analytics): migrate settings thunk MetaMetrics events (#44379)
b400e49380 refactor(analytics): migrate orphan platform metrics UI events (#44378)
1e0188a092 perf(7465): memoize token list derivations and lift per-row Redux subscriptions to parent (#44295)
e9d9c6cd75 fix: fixed race condition on vault creation and get seedphrase (#44276)
5418dedc88 chore(preferences): remove enableMV3TimestampSave debug preference (#44373)
5bfa8fe8fb chore(6925): upgrade react & react-dom to v18 (#42997)
d3fa3dd51b chore: update CODEOWNERS bringing more code under team money-movement (#44408)
485109f500 chore: deprecated import path (#43242)
dec283a8fe refactor(analytics): migrate orphan Web3Auth onboarding events (#44377)
5291e67aa5 refactor: remove headless STX status page approval (#44301)
909c8d60b2 docs: Add Cursor Skill to automatically add new EVM networks to swaps (#44386)
4a4948b41b fix: update trackImportEvent usage to use correct params and string comparison (#44400)
355bc49105 feat: Bump Snaps packages (#44396)
cd8907a7aa perf(7467): memoize hooks/components with multiple selectors (#44297)
7c8966dd69 feat(e2e): wire Tron local node into fixtures (#44152)
82af0c7e26 fix(assets): restore google.svg and relocate to app/images/ cp-13.40.0 (#44383)
b977317023 feat(asset): migrate asset routes to CAIP-19 identifiers (#44114)
0ebadf7dd6 feat: QR sync error UI (#44081)
615c3a8fe1 feat: rename add-device to sync-accounts (#43870)
a329b0473b fix: extra pending row from local state cp-13.40.0 (#44359)
b7c7eef85a feat: wallet metadata and imported account sync via QR (#44047)
b426596c9c perf: add useMemo/useCallback memoization to home balance components (#44294)

AI Test Plan

Risk Score High Risk Medium Risk Files Changed Commits
57/100 7 5 1684 127
Cherry-Pick Scenarios (1)

Medium Risk Scenarios (1)

1. Activity Transaction Details Width (responsive fix)

Risk Level: MEDIUM

Why This Matters: Cherry-pick 44856 fixes a layout issue in transaction details; regressions here can make critical information (amounts, addresses, CTAs) inaccessible on small viewports.

Test Steps:

  1. Open Activity and expand details for a send, swap, and bridge entry; progressively narrow the extension window to small widths.
  2. Verify no horizontal scrollbars, clipped text, or off-screen buttons; links and CTAs remain accessible and readable.
  3. Switch between multiple detail entries rapidly and confirm the panel resizes correctly without overlapping content.
  4. Toggle between light/dark mode (if available) to ensure no contrast regressions with the new width behavior.

Release Scenarios (11)

High Risk Scenarios (7)

1. State Migrations (217–219)

Risk Level: HIGH

Why This Matters: Migrations can corrupt or drop user data (accounts, networks, assets, preferences). Early detection prevents data loss and broken UX post-upgrade.

Test Steps:

  1. Start on 13.41.x with a profile that has: 2+ accounts, at least one custom network (e.g., Polygon), token detection ON, 1–2 custom (manually added) ERC-20s, and at least one NFT (ERC-721 or ERC-1155).
  2. Upgrade the same profile to 13.42.0 and unlock.
  3. Verify all accounts, custom networks, token visibility (including hidden tokens), and NFT collections persist with correct balances and images.
  4. Confirm user preferences (token/NFT autodetection, Show test networks, advanced gas settings) remain unchanged.
  5. Open Activity and Settings; ensure no migration error banners/toasts and no duplicated/missing assets.

2. Token Management (Assets Controller v11 upgrade)

Risk Level: HIGH

Why This Matters: A major Assets Controller bump can affect detection, balances, metadata, and chain scoping—core wallet functionality users rely on daily.

Test Steps:

  1. On Mainnet with token detection ON, verify common tokens auto-appear with correct symbol/decimals/logo and accurate balances.
  2. Manually add a custom ERC-20 with unusual decimals; confirm balance math and fiat conversion are correct.
  3. Toggle token detection OFF; verify auto-detected tokens disappear while manually added tokens remain.
  4. Switch between Mainnet and a custom/test network; confirm token lists are chain-scoped and persist per network.
  5. Refresh/relaunch; ensure token logos/metadata remain stable and no duplicate entries appear.

3. NFTs (Collectibles) Detection and Transfers

Risk Level: HIGH

Why This Matters: NFT logic depends on asset metadata and balances; controller or UI changes can break detection, display, and transfer accuracy.

Test Steps:

  1. Enable NFT autodetection and import at least one ERC-721 and one ERC-1155 collection; confirm images/metadata load.
  2. Send an ERC-721 to another address; verify confirmation UI details and post-transaction the NFT is removed from the sender.
  3. Send a single unit of an ERC-1155 with quantity >1; confirm quantity decrements correctly.
  4. Hide/unhide an NFT; switch accounts and networks; verify visibility persists as expected.
  5. Check Activity entries for NFT sends have accurate titles, icons, and status.

4. Network Enablement and Chain Switching

Risk Level: HIGH

Why This Matters: Network enablement gating and switching are core to cross-chain usage; regressions can strand users or cause incorrect chain interactions.

Test Steps:

  1. From a dapp, trigger wallet_addEthereumChain for a new chain; confirm the Add Network prompt shows accurate details/warnings and successfully adds/switches on approval.
  2. From the same or another dapp, trigger wallet_switchEthereumChain to both an added and a not-yet-added chain; verify correct prompts and outcomes (add + switch vs. switch only).
  3. Toggle Show test networks in Settings; ensure visibility updates in the network menu immediately.
  4. Remove a custom network and reattempt a dapp-initiated switch; verify correct prompts and error handling on deny.
  5. Confirm connected site permissions reflect the new network after switching.

5. Send Flow and EIP-1559 (Speed Up/Cancel)

Risk Level: HIGH

Why This Matters: Any regression in EIP-1559 or replacement flows can cause failed or stuck transactions and user fund risk.

Test Steps:

  1. Send native ETH with Advanced gas open; set custom Max fee/Max priority; submit and verify pending status in Activity.
  2. Use Speed Up; confirm replacement tx is created with higher gas and the original is replaced.
  3. For another pending tx, use Cancel; verify the cancel replacement is submitted and original tx no longer confirms.
  4. Confirm final statuses (Succeeded/Cancelled) and fee details are correct in Activity details.
  5. Validate error surfaces if custom gas selection is too low or invalid.

6. Dapp Transaction Confirmation and Typed Data Signing

Risk Level: HIGH

Why This Matters: Confirmation surfaces and typed data rendering must be accurate to prevent phishing or signing the wrong data.

Test Steps:

  1. Connect a test dapp; initiate a sendTransaction; verify confirmation UI (recipient, amount, gas) and successful submission.
  2. From the dapp, request eth_signTypedData_v4; inspect the structured data rendering; approve and verify the signature is returned correctly.
  3. Repeat typed data request and Reject; confirm the dapp receives a clear user-rejected error.
  4. Attempt both flows from an unconnected account and confirm proper connection prompts or unconnected warnings.

7. Bridge Flow (Bridge Controller update)

Risk Level: HIGH

Why This Matters: Bridge logic is multi-step and cross-chain; controller or UI regressions can create failed moves of funds or confusing states.

Test Steps:

  1. Open the Bridge feature; select source (e.g., Ethereum) and destination (e.g., Polygon) and a token; request a quote.
  2. If not on source chain, confirm a switch prompt appears; approve switching and proceed to allowance (if needed) and the bridge transaction.
  3. Submit the bridge transaction; verify clear pending status and subsequent completion (or failure) messaging.
  4. Inspect Activity details for the bridge entry: correct networks, token amounts, and status.
  5. Deny at each step (switch, allowance, bridge) once to ensure graceful error and no stuck UI.

Medium Risk Scenarios (4)

1. Activity Feed and Transaction Details (general)

Risk Level: MEDIUM

Why This Matters: Large UI updates can break detail rendering and discoverability, making it hard for users to audit transactions.

Test Steps:

  1. Generate a mix of transactions (send, swap, bridge, NFT send); open each Activity details panel.
  2. Resize the extension to narrow widths and confirm details content remains readable (no clipping/overflow).
  3. Verify timestamps, fees, method labels, and links to block explorers are correct.
  4. Filter or search (if available) and ensure detail links still open the correct entry.

2. Alerts System (Unconnected Account, Multiple Alerts)

Risk Level: MEDIUM

Why This Matters: Alert presentation and CTA wiring guide users to safe states; regressions can lead to mistaken actions on the wrong account/network.

Test Steps:

  1. Connect Site A with Account 1; switch to Account 2 and return to Site A; verify the Unconnected Account alert appears with correct CTAs (Switch account / Connect).
  2. While on a wrong network for Site A, open Site A; verify Wrong Network and Unconnected Account alerts stack without blocking core actions.
  3. Use the alert CTAs to resolve (switch/connect or switch network) and confirm alerts dismiss correctly.
  4. Trigger a generic inline alert (e.g., low balance) and verify no conflicts with modal alerts.

3. API Error Handling (User-Facing Errors)

Risk Level: MEDIUM

Why This Matters: Error copy and handling prevent user confusion and repeated failed attempts, especially after controller/UI refactors.

Test Steps:

  1. Force a gas estimation failure (e.g., send a failing tx); confirm a clear, user-friendly error is shown and the flow is recoverable.
  2. Go offline during a quote or send step; verify network error messaging and retry guidance, not indefinite spinners.
  3. Submit a transaction that reverts on-chain; confirm the failure status and message appear in Activity details with an explorer link.

4. Encryption Public Key and Decrypt (eth_getEncryptionPublicKey / eth_decrypt)

Risk Level: MEDIUM

Why This Matters: Even small changes here can break privacy-focused dapp features or expose confusing prompts that impact security-sensitive flows.

Test Steps:

  1. From a dapp, request eth_getEncryptionPublicKey; verify a clear prompt and that approving returns a valid key string.
  2. Use that key to send an encrypted payload; request eth_decrypt; ensure the decryption prompt shows expected origin and approving returns plaintext.
  3. Attempt both calls while the wallet is locked and with an unconnected account; verify correct gating and prompts (no silent failures).
  4. Reject each prompt once; confirm the dapp receives a user-rejected error and no stale prompts remain.

Teams Sign-off Status

Signed off: None yet

Awaiting sign-off (7):
Accounts, Assets, Confirmations, Networks, Swaps and Bridge, Transactions, Wallet Integrations


Generated by AI Test Plan Analyzer (gpt-5) at 2026-07-24T17:29:39.713Z

AI generated test plan (JSON): test-plan-13.42.0.json

davidmurdoch and others added 2 commits July 24, 2026 12:46
…2.0 (#44830)

CHANGELOG entry: Fixed deep links so protected routes no longer bypassed the security interstitial based only on their path
@metamask-ci

metamask-ci Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor
Builds ready [d5f6239]
⚡ Performance Benchmarks (Total: 🟢 10 pass · 🟡 8 warn · 🔴 4 fail)

Baseline (latest main): c08a8bb | Date: 7/24/2026 | Pipeline: 30121835668 | Baseline logs

Metricschrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🔴 metricsToWalletReadyScreen(p95) [CI log]🔴 [CI log]
onboardingNewWallet
[Sentry log · main/release]
🔴 srpButtonToPwForm(p95) [CI log]🔴 [CI log]

Regressions (🔴 4 failures)

Interaction Benchmarks · Samples: 5
Benchmarkchrome-webpackfirefox-webpack
loadNewAccount
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
🟡 load_new_account
confirmTx
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
bridgeUserActions
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • confirmTx/longTaskMaxDuration: +11%
  • bridgeUserActions/bridge_load_page: -12%
  • bridgeUserActions/longTaskCount: +11%
  • bridgeUserActions/longTaskTotalDuration: +12%
  • loadNewAccount/load_new_account: +24%
  • loadNewAccount/total: +24%
  • loadNewAccount/inp: -21%
  • loadNewAccount/lcp: +1160%
  • confirmTx/confirm_tx: +11%
  • confirmTx/longTaskCount: -100%
  • confirmTx/longTaskTotalDuration: -100%
  • confirmTx/longTaskMaxDuration: -100%
  • confirmTx/tbt: -100%
  • confirmTx/total: +11%
  • confirmTx/inp: +21%
  • confirmTx/fcp: +14%
  • confirmTx/lcp: +1305%
  • bridgeUserActions/bridge_load_page: +225%
  • bridgeUserActions/bridge_load_asset_picker: +95%
  • bridgeUserActions/bridge_search_token: -12%
  • bridgeUserActions/longTaskCount: -100%
  • bridgeUserActions/longTaskTotalDuration: -100%
  • bridgeUserActions/longTaskMaxDuration: -100%
  • bridgeUserActions/tbt: -100%
  • bridgeUserActions/total: +19%
  • bridgeUserActions/inp: -23%
  • bridgeUserActions/fcp: +12%
  • bridgeUserActions/lcp: +1232%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 loadNewAccount/FCP: p75 1.9s
  • 🟡 confirmTx/FCP: p75 1.9s
  • 🟡 bridgeUserActions/FCP: p75 1.9s
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
startupPowerUserHome
[Sentry log · main/release]
🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/lcp: -36%
  • startupStandardHome/initialActions: +11%
  • startupPowerUserHome/setupStore: +61%
  • startupPowerUserHome/inp: +12%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 startupPowerUserHome/INP: p75 248ms
  • 🟡 startupPowerUserHome/LCP: p75 3.3s
User Journey Benchmarks · Samples: 5 · real API 🔴 4

⚠️ Missing data: chrome/webpack/userJourneyAssets

Benchmarkchrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🔴 [CI log]
🔴 doneButtonToHomeScreen
🔴 total
🔴 [CI log]
🔴 total
onboardingNewWallet
[Sentry log · main/release]
🔴 [CI log]
🔴 total
🔴 [CI log]
🔴 total
importSrpHome
[Sentry log · main/release]
🟡 [CI log]
🟡 homeAfterImportWithNewWallet
🟡 total
🟢 [CI log]
sendTransactions
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
swap
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
assetDetails
[Sentry log · main/release]
🟢 [CI log]
solanaAssetDetails
[Sentry log · main/release]
🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • onboardingImportWallet/metricsToWalletReadyScreen: +36%
  • onboardingImportWallet/doneButtonToHomeScreen: -27%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: -67%
  • onboardingImportWallet/tbt: +18%
  • onboardingImportWallet/total: -32%
  • onboardingNewWallet/srpButtonToPwForm: +11%
  • importSrpHome/homeAfterImportWithNewWallet: +13%
  • importSrpHome/longTaskCount: -13%
  • importSrpHome/total: +11%
  • sendTransactions/openSendPageFromHome: +447%
  • sendTransactions/selectTokenToSendFormLoaded: +14%
  • sendTransactions/reviewTransactionToConfirmationPage: -98%
  • sendTransactions/longTaskCount: -100%
  • sendTransactions/longTaskTotalDuration: -100%
  • sendTransactions/longTaskMaxDuration: -100%
  • sendTransactions/tbt: -100%
  • sendTransactions/total: -93%
  • sendTransactions/lcp: +895%
  • sendTransactions/cls: -17%
  • swap/fetchAndDisplaySwapQuotes: +48%
  • swap/longTaskCount: +100%
  • swap/longTaskTotalDuration: +75%
  • swap/tbt: +19%
  • swap/total: +47%
  • swap/lcp: +12%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 importSrpHome/INP: p75 344ms
  • 🟡 solanaAssetDetails/FCP: p75 1.9s
  • 🟡 sendTransactions/FCP: p75 1.9s
  • 🟡 swap/FCP: p75 1.9s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]

📈 Results compared to the previous 5 runs on main

  • dappPageLoad/pageLoadTime: -20%
  • dappPageLoad/domContentLoaded: -16%
  • dappPageLoad/firstPaint: -13%
  • dappPageLoad/firstContentfulPaint: -13%
Bundle size diffs [🚀 Bundle size reduced!]
  • background: -25.6 KiB (-0.17%)
  • ui: -353 Bytes (0%)
  • common: 0 Bytes (0%)
  • other: 0 Bytes (0%)
  • contentScripts: 404 Bytes (0.02%)
  • zip: -7.19 KiB (-0.03%)

🍒 What's in this RC

Cherry-picks (7 commits)
Commit Description
d5f6239719 release(cp): bump: tar to 7.5.22, ignore react-router advisories cp-13.41.0 (#44862)
78ce2e0cf9 release(cp): fix(deep-links): restore interstitial protection cp-13.42.0 (#44830)
5738947439 release(runway): cherry-pick fix(activity): transaction details width cp-13.42.0 (#44856)
a8682562fc release(runway): cherry-pick feat: keep the balance left aligned for lower viewport cp-13.42.0 (#44854)
189763ce27 release(cp): cherry-pick fix(assets): include tokens with large balances and few decimals in aggregated balance cp-13.41.0
8423f220d3 release: release-changelog/13.42.0 (#44798)
0c93b31dd8 Merge release/13.41.0 into release/13.42.0

Changelog (223 commits from main at RC cut)
Commit Description
446c5a25b5 fix: apply bg-alternative to legacy Popover in pure black theme (#44730)
c2c37a8a68 fix: apply border-muted to global menu drawer in pure black theme (#44729)
7e15155002 chore: remove unused legacy modals from ui/components/app/modals (#44731)
b03252588b fix: add device response timeout to Trezor bridges (#44626)
9ee3d987a7 feat: show skeleton for the whole balance block if the balance is not cached (#44703)
960369d180 fix: require interstitial for CAIP-19 asset deep links (#44639)
ef34172a99 refactor: migrate formatters to client-utils (#44624)
88c41e5489 test: cover Wallet Creation Attempted Segment event (#44673)
7a14cd7f6c feat: Updated the styles for swaps page (#44762)
ad64202e93 test: MMQA - 2035 - Fix antipatterns in sendPage which can lead to flakiness (#44640)
845b4a8f4a feat: updated avatarbase and banner alert to use DS (#44763)
3802fdba7c chore: migrate AvatarFavicon to MMDS (#44764)
a1b13be185 feat: seedless controller v10.1.0 (#44771)
864f5e5294 fix: patch bridge controller to exclude Stellar and Arc cp-13.41.0 (#44749)
ab4fbefa8d fix: non-evm bridge activity (#44751)
62fd747287 chore: removed deprecated checkbox with DS (#44765)
643d4d57cc test: added e2e tests for the new logic showing energy and bandwidth in sign transaction confirmation (#44756)
0fd8198e4b chore: remove border from pages (#44721)
1910a59ff9 feat(ledger): wire ledgerDmk flag to offscreen mode switching (#43488)
56f0a34156 chore: introduce bulk error suppression (#44739)
bd13fb6ec3 chore: updated networks for hardware accounts (#44531)
ab79e887a9 fix: updated search to be sticky and banner to scroll cp-13.41.0 (#44696)
34148d362e test(tron): prepare daily resources for E2E coverage (#44162)
4cd1d95222 chore: bump @metamask/tron-wallet-snap to ^1.33.1 (#44716)
906fee2c9d chore: bump assets controllers and remove patches (#44713)
dad0511577 test: fix flaky QrSync multi-SRP import confirm staleness timeout (#44700)
d50de2fac4 fix(metametrics): silence unmatched route Sentry noise for known paths (#44718)
4103808cae fix(ci): Remove "What's in this RC ...and more changes" section to match Extension RC Slack message to Mobile layout cp-13.41.0 (#44740)
7b2c1b2665 chore: update to ESLint v9 (#44734)
9faf0a6b5d feat: apply bg-alternative and border-muted to legacy Modal in pure black mode (#44726)
969f5c2aaa chore: update swap row labels (#44637)
2aa9b938e0 feat: apply bg-alternative and border-muted to ModalContent dialog in pure black mode (#44720)
9e40a87367 chore: New Crowdin Translations by GitHub Action cp-13.41.0 (#44595)
3ea61fd698 chore: remove unused ESLint directives from shared (#44679)
07651ccf9c chore: remove unused ESLint directives from ui/components (#44683)
0b58311684 chore: remove unused ESLint directives from remaining ui (#44685)
148b0844e4 bump: sharp to 0.35.3 (#44688)
ad1bbf43ce feat: show verified badge on swaps token button (#44623)
d5047c3a86 chore: replace sub tab screen opened metrics (#44093)
bb150a4058 feat: added skeleton for token list after stale open (#44705)
1d3f77fb38 ci: Harden absolute benchmark gate against within-noise breaches (#44609)
f3bd7f870e chore: align dapp connection bar styling with Figma spec (#44539)
42315a4087 feat: navigate users to batch sell through deeplink (#44671)
396263b848 chore: remove unneeded styles (#44693)
2acd3840a2 refactor(activity): use native dialog for transaction details (#44599)
65292d06fb bump: immutable to 5.1.9, fast-uri to 3.1.4, dompurify to 3.4.12, sass-embedded to 1.100.0 cp-13.41.0 (#44678)
57638a9616 chore: remove unused ESLint ignore directives from development (#44676)
7cb3eb6037 chore: split eslint ignore react-compiler directives (#44686)
14c815595a chore: remove unused ESLint directives from ui/pages (#44684)
8eac23857c chore: remove unused ESLint ignore directives from app (#44674)
8d99a5f7d3 test: fix flaky tests Add wallet Import wallet... (#44649)
4a1c57b063 test: fix flaky test Add account added account should persist after wallet lock (#44712)
2b218f3e77 chore(eslint): ignore .yarn and webpack build directory (#44666)
67b21b1e1b chore: update transaction controller (#44656)
77c6773132 chore: adds handler for top-traders (Follow Trading) deeplink redirect (#44660)
bceab0bb1e chore: bump @metamask/tron-wallet-snap to ^1.33.0 (#44698)
fa3885cf81 feat: setup for new defi flag (#44652)
0afcd07800 test: refactor snap-account-abstraction page object to remove references to other page objects (#44690)
3051cf4133 test: refactor account-list page object to remove references to other page objects (#44651)
edb7daa756 fix: clear orphaned advancedGasFee preference (migration 216) (#44205)
59f15bc6b0 fix: remove useAssetActivation test to unblock assets controllers bump up (#44699)
52b4b3d877 feat: removed back transitions unused selector (#44691)
f9f5e1dc48 fix: update slider step to one in batch sell (#44648)
a7847a0538 fix: do not render assets without quotes in review modal (#44650)
efa96b445e refactor: use modern clipboard api (#44622)
80b66e6c4e chore: removed sidepanel viewport max width constraint (#44647)
6d970c423d test: encryption and decryption Segment events (#44607)
1ff9bf422b chore: remove unused ESLint ignore directives from test directory (#44669)
2518a3727c feat(ui): add pure-black dark mode behind build-time flag (#44183)
d07ea1771f test: update swaps unit test mocks (#44627)
c6fc026ec2 chore: refactor ESLint overrides (#44663)
6fb3e32f55 bump: valibot to 1.4.2, body-parser to 1.20.6 and 2.3.0 (#44664)
b8c3584c53 fix(notifications): keep announcement home link in tab (#43419)
6e0219f5d6 chore: skip linting Jest snapshots (#44665)
a84d6539f5 feat: render high rate alert modal in batch sell review page (#44646)
0d81022be0 feat: integrate STX failTransaction fix (bridge stuck-pending) (#44372)
8f66b8fc55 feat: add bottom nav bar source to perps view events (#44611)
6fb1d6ba46 chore: update @metamask/gator-permissions-snap to version 2.4.0 (#44499)
9b12c19790 test: cover Empty Buy Banner Displayed event (#44617)
6c0217c496 feat: add bottom nav transitions (#44641)
8ae5ce634e chore: use same toaster-bottom-offset var for legacy toasts (#44654)
5da5008a3a test: MMQA - 1975 - Enhance feature flag validation/drift PR to omit re-orders without value change (#43814)
261773c0bb test: fix flaky tests Check balance For a non 0 balance account... (#44479)
5207d27d9c feat: add bottom nav experiment display logic and e2e tests (#44403)
1f66fc6cd7 release: Bump main version to 13.42.0 (#44642)
9962ac769f feat: implement close positions with limit orders (#44466)
477be3b0bc feat(e2e): add Tron test fixtures and environment helpers (#44160)
ffd91160c9 fix: various fixes and improvements on batch sell select page (#44603)
e091fe0b04 fix(assets): wire tempMigrateAssetsInfoMetadataAssets3346 into AssetsController init (#44303)
b685e6bf62 test: MMQA - 2034 - Fix antipatterns in qr-sync.spec.ts (#44600)
1548788667 bump: multiple to fix audit cp-13.41.0 (#44634)
6647504ca3 feat: consume backend-suggested slippage in unified swap/bridge (#44537)
e29c451b29 feat: import alias via node subpath imports (#44621)
f7f67d320b feat(ramps): add provider selection page with async quotes (#44553)
e9b745e8e5 chore: remove dead code (#44612)
bb5e12f804 refactor: migrate multichain review permissions toast (#44505)
fc5d600b60 refactor: add useEventListener (#44596)
d8c683d6c9 feat(e2e): add Tron swap token registry and quote fixtures (#44159)
39d6aa6899 refactor: migrate buy button toast (#44510)
4fa405c7e6 fix: dedicated convert mUSD details cp-13.41.0 (#44586)
a6942d1c60 feat(support): replace raw profile params with customer service token (#44482)
d4987093b8 refactor: migrate delete metametrics toast (#44503)
22c64b7f3f refactor: migrate permissions disconnect-all toast (#44504)
227a3644f0 feat(ramps): show per-method quotes on payment selection (#44526)
abc8a8267c feat: update bottom bar navigation to swaps page (#44233)
3784ae3945 feat: added decimal validation for custom token import flow cp-13.41.0 (#44602)
b495bf455d chore: patch @metamask/assets-controller for suggested occurrence floors (#44525)
88bc6591dc feat(ci): add Runway orchestrator starter and store submission CODEOWNERS (#44017)
1894816b17 refactor(analytics): remove MetaMetricsController shims and finish background migration (#44380)
c4af8823c1 feat(hardware-wallets): add signing page orchestrator (#43943)
e8baf89ff4 fix(ci): align Extension RC Slack notes with Mobile Runway changelog (#44597)
7bfc16cfc0 bump: Upgrade @sentry/browser from 8.33.1 to 10.38.0 (#42867)
a25c6a5b07 chore(6932): convert final legacy context consumers to useI18nContext for React 19 (#44493)
9b908f58d4 test: fix Add wallet Import wallet using json file - TimeoutError: Waiting for element to be located By(css selector, [data-testid="choose-wallet-type-import-account"]) (#44464)
6183003c90 refactor: resolve activity list redesign (#44365)
576a79fa6d chore: allow history navigate on activity details (#44467)
593690c0f7 chore: remove browserify (#44433)
1456a2100a fix: keep bridge activity item as pending until dest tx resolves cp-13.40.0 (#44536)
aa09362f39 fix: don't hold the KeyringController lock during hardware wallets reads (#44483)
0f5ef841a3 refactor(activity): handle swaps missing destination token (#44501)
5d12649353 test: fix flakyTest Snap getEntropy can use snap_getEntropy inside a snap (#44458)
ad3fb497ce refactor(confirmations): address send asset picker review follow-ups (#44431)
b6449df15d feat(ramps): update remaining entrypoints to use goToBuy (#44440)
8a1ccdc82c feat: gate scam questionnaire behind LaunchDarkly flag cp-13.40.0 (#44496)
c0e7a119d7 fix: mascot being rendered twice in onboarding unlock page (#44533)
4c7819aff3 fix: prevent duplicate events during tab switch (#44528)
360bc7d616 fix: bump network enablement controller to v5.6.0 (#44371)
e2f4454072 feat(ramps): add payment method selection page (#44437)
d11fa4a85a refactor: migrate gas fee token toast (#44468)
b48258de3b feat(e2e): add Tron local node mock proxy (#44157)
e149e9c519 feat: update bridge status controller to latest release (#44515)
2ba671463a bump: websocket-driver to fix audit (#44513)
8b843741f8 fix(ramps): wait for selected token before leaving token selection (#44497)
449919f484 fix: crash when typing a comma in the MM Pay custom amount input (#44521)
81ed3e6cb7 fix(ramps): keep provider label while quotes load on build quote (#44491)
e294e5fbc3 chore(tokens): remove stale token cache fallbacks (#44522)
b3a729e909 build: remove submodule added by mistake (#44514)
40f4844d3e feat: sentry for QrSync (#44487)
173e9e7a04 feat: added transitions to manage tokens page (#44484)
be631b56fa refactor: switch activity mappers to @metamask/client-utils (#44366)
41ca3b93c3 fix: Bump react-data-query (#44520)
0cd688b4bf refactor(analytics): migrate orphan multichain accounts UI events (#44376)
4400dd58c1 feat: added skeleton fr balance loading state (#44429)
397c4485f0 chore: use skeleton on loading activity screen (#44423)
29b6f2e924 chore: Revert "chore(6926): migrate ReactDOM.render to createRoot (#43872)" (#44517)
743cccdd2a refactor(analytics): migrate orphan account overview tabs events (#44375)
9efc6d62ed chore(6926): migrate ReactDOM.render to createRoot (#43872)
83d763aaa4 perf(6600): fix asset selector cache thrashing for NFTs and token scan results (#44473)
21c3992646 feat: added transitions to Dapp connections pages (#44481)
1d44802063 fix: consume local history data for bridges on activity items (#44488)
bf71e30756 refactor(analytics): migrate orphan UX contacts and chrome events (#44374)
f1c3e4103c feat(e2e): extend Tron mocks with swap tokens, stateful accounts, and parameterized fixtures (#44485)
8c0fa5b830 perf(6601): fix parameterized selector cache thrashing for chain-checking selectors (#44474)
c255a1a983 feat(perps): show ticker next to volume and fix symbol display consistency (#44478)
b169cbc8fc fix: updated analytis for add token (#44486)
d0a5db3726 feat(ramps): add build quote page with quote fetching (#44409)
4eabcbe89b chore(6931): migrate class components from defaultProps to default params (#44299)
56e0cbf45f perf(6929): harden UI effects for React 18 StrictMode double-mount (#44298)
55e0419dce perf(6602): prevent cache thrashing in parameterized network lookups (#44475)
72c5dccaa4 chore(6930): update React Compiler target to v18 (#44476)
9b7cd98c49 feat: updated CODEOWNERS for QrSync (#44465)
f2018259e3 test: QrSync e2e for multi SRP flows (#44438)
dc5bc8dc93 test(e2e): add Bitcoin send flow against local regtest node (#44156)
e34d7e67bb test: Add E2E max balance validation test (#43821)
2ff51fd902 fix: ensure stellar assets show correctly in token details page (#44444)
77cf93f811 chore: tiny header adjustments on new bottom nav pages (#44470)
fe2bc9df7d test: MMQA - 1971 - Fix missnamed test tokens/nft/filter-nfts.spec.ts same as view-nft-details.spec.ts (View NFT details) (#44086)
f5d4634e8b perf(7475): adopt useDeferredValue for search and filter surfaces (#44443)
23a9a0e228 feat(e2e): add Bitcoin regtest node wrapper using @metamask/bitcoin-regtest-up (#44155)
1986666442 feat: updated token management toggle button (#44434)
a74972d532 feat: ux improvemnets for add via chainlist feature (#44424)
bfb0b29226 test: fix flaky test Vault Corruption does not reset metamask state when recovery is not confirmed (#44435)
ccadeeeccd chore: New Crowdin Translations by GitHub Action cp-13.40.0 (#44329)
3f7584b6f0 fix: QR Sync session timeout and cancellation (#44422)
8b02f4a613 chore: reduce Sentry trace sampling cp-13.40.0 (#44451)
7cd63e4d54 perf(6778): add useStateSyncHealth hook for stale sync auto-recovery (#44389)
80a76d63d4 bump: ws to fix audit (#44459)
f602fae822 refactor: migrate perps withdraw transaction toast (#44419)
81bacd28ee fix(sentry): Resolve AggregatedBalanceSelector transaction volume spike by not passing trace into getAggregatedBalanceForAccount cp-13.40.0 (#44449)
ba18ce10ac feat(ramps): intent routing in goToBuy + stub buy pages (#44404)
2e477542ab ci(token-exchange): migrate FIXTURE_UPDATE_TOKEN to token exchange service (#43838)
2ff80c450e test(e2e): run Solana send flow against local validator (#44154)
baab980461 fix: resolve Perps deposit confirmation stuck on loading skeleton on first open (#44247)
a9f826964b ci: remove requirement for "auto-rc-builds" label (#44421)
3e52ec5ffb perf(7467): memoize composite derived state in home container and dapp bar (#44354)
8846ae56e5 feat(ramps): geo-blocking UI for ramps entry points (#44351)
c496204040 feat(e2e): add Solana local validator wrapper using @metamask/solana-… (#44426)
71f9467411 feat: reintroduce saved gas settings (#43317)
25d7175ff4 chore: nav to perps funding screen on perps funded activity details (#44427)
7657dcc0da fix: render in flight perps deposit/withdraw activity details (#44425)
78908aa279 fix(confirmations): address enforced simulations papercuts (#44343)
4b01eb4a84 feat(ramps): add in-extension token selection page (#44349)
eb3b6f521a fix(perps): mask open order size and value in privacy mode (#44432)
c6c99ecced ci(INFRA-3680): rename bot reference from mm-token-exchange-service to metamask-ci (#44387)
594bbd6f6c test: QrSync E2E (main flow) (#44381)
612334352b refactor: migrate musd claim toast (#44414)
d22a7b6118 chore: bump @metamask/tron-wallet-snap to ^1.31.0 cp-13.40.0 (#44385)
a396544397 chore: use candlestick filled icon when perps bottom nav active (#44388)
70a302b923 feat: refresh activity list after confirm (#44333)
ea74194fd2 feat: sync-accounts use image for qr code (#44417)
4631b6103f fix(mv3): move keep-alive polling to service worker startup (#44348)
5dd78ebf23 refactor(analytics): migrate settings thunk MetaMetrics events (#44379)
b400e49380 refactor(analytics): migrate orphan platform metrics UI events (#44378)
1e0188a092 perf(7465): memoize token list derivations and lift per-row Redux subscriptions to parent (#44295)
e9d9c6cd75 fix: fixed race condition on vault creation and get seedphrase (#44276)
5418dedc88 chore(preferences): remove enableMV3TimestampSave debug preference (#44373)
5bfa8fe8fb chore(6925): upgrade react & react-dom to v18 (#42997)
d3fa3dd51b chore: update CODEOWNERS bringing more code under team money-movement (#44408)
485109f500 chore: deprecated import path (#43242)
dec283a8fe refactor(analytics): migrate orphan Web3Auth onboarding events (#44377)
5291e67aa5 refactor: remove headless STX status page approval (#44301)
909c8d60b2 docs: Add Cursor Skill to automatically add new EVM networks to swaps (#44386)
4a4948b41b fix: update trackImportEvent usage to use correct params and string comparison (#44400)
355bc49105 feat: Bump Snaps packages (#44396)
cd8907a7aa perf(7467): memoize hooks/components with multiple selectors (#44297)
7c8966dd69 feat(e2e): wire Tron local node into fixtures (#44152)
82af0c7e26 fix(assets): restore google.svg and relocate to app/images/ cp-13.40.0 (#44383)
b977317023 feat(asset): migrate asset routes to CAIP-19 identifiers (#44114)
0ebadf7dd6 feat: QR sync error UI (#44081)
615c3a8fe1 feat: rename add-device to sync-accounts (#43870)
a329b0473b fix: extra pending row from local state cp-13.40.0 (#44359)
b7c7eef85a feat: wallet metadata and imported account sync via QR (#44047)
b426596c9c perf: add useMemo/useCallback memoization to home balance components (#44294)

AI Test Plan

Risk Score High Risk Medium Risk Files Changed Commits
66/100 10 3 1689 129
Cherry-Pick Scenarios (2)

High Risk Scenarios (1)

1. Security – Deep-link interstitial protection

Risk Level: HIGH

Why This Matters: Cherry-pick 44830 fixes a regression that removed interstitial protection for deep links; without it, malicious links could trigger wallet prompts without user awareness.

Test Steps:

  1. From a web page, click a MetaMask deep link that initiates a sensitive action (e.g., add network or signature request).
  2. Verify an interstitial/warning screen appears before the action, showing origin/context and options to Cancel/Continue.
  3. Choose Cancel and confirm the extension does not proceed to any permission or signing prompt.
  4. Retry and choose Continue; verify the expected MetaMask confirmation screen opens and functions normally.

Medium Risk Scenarios (1)

1. Activity – transaction details width/overflow

Risk Level: MEDIUM

Why This Matters: Cherry-pick 44856 fixes transaction details width issues; without it, users may miss critical info or misclick actions in the Activity panel.

Test Steps:

  1. Open a transaction in Activity with long addresses and method data on a small viewport.
  2. Verify fields wrap correctly with no horizontal scrolling or clipped buttons (e.g., Copy, View on Explorer).
  3. Resize the window and confirm the layout remains readable and interactive.

Release Scenarios (11)

High Risk Scenarios (9)

1. State Migration (217–219) – vault, accounts, permissions

Risk Level: HIGH

Why This Matters: Multiple new migrations (217–219) can corrupt or drop critical state (accounts, permissions, networks) if ordering or shape assumptions changed.

Test Steps:

  1. Start on 13.40.x or 13.41.x profile with: 2 HD accounts, 1 imported private key account, 1 hardware account; at least 2 connected sites (on Mainnet and a custom network).
  2. Upgrade to 13.42.0 and unlock the wallet.
  3. Verify all accounts are present (names, ordering), ensure each previously connected site remains connected to the same accounts.
  4. Open a previously added custom network and confirm RPC/Chain ID are intact and switching succeeds.
  5. Confirm no repeated seed phrase prompts or unexpected logout; extension idle/opening has no crash or blank screen.

2. State Migration (217–219) – tokens, NFTs, activity history

Risk Level: HIGH

Why This Matters: Migrations touching asset state can orphan tokens/NFTs or break activity history, directly impacting user trust and balances visibility.

Test Steps:

  1. Before upgrade, ensure profile has: auto token detection ON, at least 2 imported ERC-20s (e.g., USDC/DAI), and 1–2 NFTs (ERC-721 and ERC-1155).
  2. Upgrade to 13.42.0 and open the Assets and NFTs tabs for multiple accounts.
  3. Verify custom tokens still appear with correct symbols/decimals and balances; fiat conversion shows for detected tokens.
  4. Verify NFTs render images/metadata, collection names, and item counts; activity history still lists past transactions.
  5. Open a past transaction detail and confirm data fields are readable and not truncated.

3. Token Management – Assets Controller v11 upgrade (watchAsset, detection, fiat pricing)

Risk Level: HIGH

Why This Matters: A major Assets Controller change can break watchAsset flows, auto-detection, and pricing—core to portfolio accuracy.

Test Steps:

  1. On Mainnet, toggle Token Detection OFF; import a known ERC-20 by contract address and verify symbol/decimals populate correctly.
  2. Toggle Token Detection ON; confirm popular tokens auto-appear without duplicates.
  3. From a dapp, request wallet_watchAsset for a token; approve and verify the token appears exactly once with fiat price.
  4. Switch fiat currency in settings; check token fiat values update accordingly.
  5. Remove the watched token and confirm balances/fiat recompute without residual entries.

4. Transaction Confirmation – EIP-1559 gas editing and submission

Risk Level: HIGH

Why This Matters: Widespread UI updates can regress confirmation flows and gas editing, risking failed or overpaid transactions.

Test Steps:

  1. Send a small ETH transfer on Mainnet to a fresh address and open the confirmation screen.
  2. Open gas edit (Advanced), change Max Fee/Max Priority, save.
  3. Submit the transaction; monitor Activity until confirmation.
  4. Verify the transaction receipt reflects edited gas values.
  5. Repeat once using the basic gas presets to ensure both editors work.

5. Swaps – quotes, approval, execution

Risk Level: HIGH

Why This Matters: Token metadata and UI refactors can disrupt the Swaps funnel (approvals/quotes), risking failed trades or wrong balance updates.

Test Steps:

  1. Initiate a token-to-token swap (e.g., ETH -> DAI) with a modest amount and request quotes.
  2. Select a quote; if approval is required, complete the allowance approval and proceed.
  3. Submit the swap and wait for completion.
  4. Verify post-swap balances, allowance changes, and Activity entries.
  5. Trigger a low-liquidity/small slippage case to confirm proper validation and errors.

6. Message Signing – personal_sign and eth_signTypedData_v4

Risk Level: HIGH

Why This Matters: UI changes can break or misrepresent signing prompts, exposing users to phishing or incorrect consent.

Test Steps:

  1. From a test dapp, request personal_sign and review the confirmation; verify domain/origin and message text.
  2. Sign the message and verify the dapp validates the signature.
  3. Request eth_signTypedData_v4 with EIP-712 content; review structured data display and domain separator.
  4. Cancel a subsequent request and ensure the dapp receives a proper rejection error.
  5. Confirm no unexpected warnings or blank screens during either flow.

7. Encryption APIs – getEncryptionPublicKey and eth_decrypt

Risk Level: HIGH

Why This Matters: Small controller changes to decrypt-message/encryption key paths can silently break privacy-preserving flows dapps rely on.

Test Steps:

  1. From a test dapp, request eth_getEncryptionPublicKey; confirm and expose the key.
  2. Have the dapp encrypt a message with the returned key and request eth_decrypt.
  3. Approve the decryption and verify the plaintext matches the original.
  4. Repeat once with Cancel to ensure proper rejection handling and no stale prompts.

8. Network Management – add/switch chain via dapp

Risk Level: HIGH

Why This Matters: Network controller and UI changes risk incorrect chain setup/switching, leading to failed dapp interactions.

Test Steps:

  1. From a dapp, trigger wallet_addEthereumChain for a new custom network; review and approve.
  2. Verify the new network appears with correct name/RPC/Chain ID and becomes active.
  3. From the same dapp, trigger wallet_switchEthereumChain to another known chain; approve and ensure active network updates.
  4. Retry both flows with Cancel and confirm the network list remains unchanged.

9. Alert System – unconnected account banner and multi-alert handling

Risk Level: HIGH

Why This Matters: Alert system refactors can hide or misprioritize critical warnings, leading to accidental actions with the wrong account.

Test Steps:

  1. Open a site connected to Account A, then switch the active account in the extension to Account B.
  2. Verify an 'unconnected account' alert appears and provides a clear Connect action.
  3. Trigger an additional alert (e.g., low balance or RPC error) and confirm alerts stack without overlapping critical actions.
  4. Dismiss alerts individually and ensure the correct one closes without UI shift breakage.

Medium Risk Scenarios (2)

1. Activity View – details readability and copy controls

Risk Level: MEDIUM

Why This Matters: Numerous UI updates can degrade transaction detail readability, hurting user ability to audit past actions.

Test Steps:

  1. Open Activity for an account with multiple transactions and select one with long addresses/data.
  2. Inspect the details panel for truncation/overflow; validate all key fields are readable.
  3. Use copy buttons for hash and address; confirm clipboard contents are accurate.
  4. Resize the window to a smaller viewport and re-check layout.

2. API Error Handling – Send and Swap failures

Risk Level: MEDIUM

Why This Matters: The API error handler changed; poor surfacing of RPC/validation errors can lead to user confusion and repeated failures.

Test Steps:

  1. Attempt to Send more ETH than the account balance and observe inline validation and disabled submit.
  2. On Swaps, simulate an invalid quote (e.g., extreme slippage) and confirm descriptive error messages are shown.
  3. Ensure closing/retrying clears errors and the UI recovers without stale states.

Teams Sign-off Status

Signed off: None yet

Awaiting sign-off (9):
Accounts, Assets, Confirmations, Networks, Permissions, Security, Swaps, Transactions, Wallet Integrations


Generated by AI Test Plan Analyzer (gpt-5) at 2026-07-24T20:34:46.264Z

AI generated test plan (JSON): test-plan-13.42.0.json

… native dialog for dark theme cp-13.42.0 (#44873)

- fix(activity): apply text color token to native dialog for dark theme cp-13.42.0 (#44863)

CHANGELOG entry: null
@metamask-ci

metamask-ci Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor
Builds ready [fbd3a5e]
⚡ Performance Benchmarks (Total: 🟢 15 pass · 🟡 5 warn · 🔴 4 fail)

Baseline (latest main): e7a6a5e | Date: 7/24/2026 | Pipeline: 30137726860 | Baseline logs

Metricschrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🔴 confirmSrpToPwForm(p95) [CI log]🔴 [CI log]
onboardingNewWallet
[Sentry log · main/release]
🔴 doneButtonToAssetList(p95) [CI log]🔴 [CI log]

Regressions (🔴 4 failures)

Interaction Benchmarks · Samples: 5
Benchmarkchrome-webpackfirefox-webpack
loadNewAccount
[Sentry log · main/release]
🟡 [CI log]🟢 [CI log]
confirmTx
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
bridgeUserActions
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]

📈 Results compared to the previous 5 runs on main

  • loadNewAccount/inp: +16%
  • bridgeUserActions/bridge_load_page: -19%
  • bridgeUserActions/tbt: -16%
  • bridgeUserActions/inp: +11%
  • loadNewAccount/inp: +30%
  • loadNewAccount/fcp: -52%
  • loadNewAccount/lcp: +1142%
  • confirmTx/confirm_tx: +11%
  • confirmTx/longTaskCount: -100%
  • confirmTx/longTaskTotalDuration: -100%
  • confirmTx/longTaskMaxDuration: -100%
  • confirmTx/tbt: -100%
  • confirmTx/total: +11%
  • confirmTx/inp: -22%
  • confirmTx/lcp: +1125%
  • bridgeUserActions/bridge_load_page: +176%
  • bridgeUserActions/bridge_load_asset_picker: +38%
  • bridgeUserActions/longTaskCount: -100%
  • bridgeUserActions/longTaskTotalDuration: -100%
  • bridgeUserActions/longTaskMaxDuration: -100%
  • bridgeUserActions/tbt: -100%
  • bridgeUserActions/total: +14%
  • bridgeUserActions/inp: -29%
  • bridgeUserActions/fcp: -50%
  • bridgeUserActions/lcp: +1176%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 loadNewAccount/FCP: p75 1.8s
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
startupPowerUserHome
[Sentry log · main/release]
🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/setupStore: +15%
  • startupStandardHome/lcp: -35%
  • startupStandardHome/domInteractive: -33%
  • startupStandardHome/fcp: -28%
  • startupPowerUserHome/uiStartup: +13%
  • startupPowerUserHome/backgroundConnect: +18%
  • startupPowerUserHome/initialActions: +11%
  • startupPowerUserHome/setupStore: +59%
  • startupPowerUserHome/lcp: +12%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 startupPowerUserHome/LCP: p75 3.5s
User Journey Benchmarks · Samples: 5 · real API 🔴 4
Benchmarkchrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🔴 [CI log]
🔴 doneButtonToHomeScreen
🔴 total
🔴 [CI log]
🔴 total
onboardingNewWallet
[Sentry log · main/release]
🔴 [CI log]
🔴 total
🔴 [CI log]
🔴 total
assetDetails
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
solanaAssetDetails
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
importSrpHome
[Sentry log · main/release]
🟡 [CI log]🟢 [CI log]
sendTransactions
[Sentry log · main/release]
🟡 [CI log]🟢 [CI log]
swap
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]

📈 Results compared to the previous 5 runs on main

  • onboardingImportWallet/metricsToWalletReadyScreen: +14%
  • onboardingImportWallet/doneButtonToHomeScreen: +25%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: -92%
  • onboardingImportWallet/longTaskCount: +13%
  • onboardingImportWallet/longTaskMaxDuration: +11%
  • onboardingImportWallet/total: +44%
  • onboardingNewWallet/agreeButtonToOnboardingSuccess: -28%
  • onboardingNewWallet/doneButtonToAssetList: +12%
  • onboardingNewWallet/longTaskCount: +11%
  • onboardingNewWallet/total: +11%
  • solanaAssetDetails/longTaskCount: -100%
  • solanaAssetDetails/longTaskTotalDuration: -100%
  • solanaAssetDetails/longTaskMaxDuration: -100%
  • solanaAssetDetails/tbt: -100%
  • importSrpHome/inp: +21%
  • importSrpHome/cls: -53%
  • sendTransactions/selectTokenToSendFormLoaded: +11%
  • sendTransactions/reviewTransactionToConfirmationPage: +43%
  • sendTransactions/longTaskCount: +25%
  • sendTransactions/longTaskTotalDuration: +30%
  • sendTransactions/longTaskMaxDuration: +30%
  • sendTransactions/tbt: +54%
  • sendTransactions/total: +42%
  • sendTransactions/cls: -17%
  • swap/openSwapPageFromHome: +29%
  • swap/longTaskMaxDuration: +16%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 importSrpHome/INP: p75 392ms
  • 🟡 sendTransactions/INP: p75 208ms
  • 🟡 solanaAssetDetails/FCP: p75 2.0s
  • 🟡 solanaAssetDetails/LCP: p75 2.6s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]
Bundle size diffs [🚀 Bundle size reduced!]
  • background: -25.6 KiB (-0.17%)
  • ui: -340 Bytes (0%)
  • common: 0 Bytes (0%)
  • other: 0 Bytes (0%)
  • contentScripts: 404 Bytes (0.02%)
  • zip: -7.18 KiB (-0.03%)

🍒 What's in this RC

Cherry-picks (8 commits)
Commit Description
fbd3a5e978 release(runway): cherry-pick fix(activity): apply text color token to native dialog for dark theme cp-13.42.0 (#44873)
d5f6239719 release(cp): bump: tar to 7.5.22, ignore react-router advisories cp-13.41.0 (#44862)
78ce2e0cf9 release(cp): fix(deep-links): restore interstitial protection cp-13.42.0 (#44830)
5738947439 release(runway): cherry-pick fix(activity): transaction details width cp-13.42.0 (#44856)
a8682562fc release(runway): cherry-pick feat: keep the balance left aligned for lower viewport cp-13.42.0 (#44854)
189763ce27 release(cp): cherry-pick fix(assets): include tokens with large balances and few decimals in aggregated balance cp-13.41.0
8423f220d3 release: release-changelog/13.42.0 (#44798)
0c93b31dd8 Merge release/13.41.0 into release/13.42.0

Changelog (223 commits from main at RC cut)
Commit Description
446c5a25b5 fix: apply bg-alternative to legacy Popover in pure black theme (#44730)
c2c37a8a68 fix: apply border-muted to global menu drawer in pure black theme (#44729)
7e15155002 chore: remove unused legacy modals from ui/components/app/modals (#44731)
b03252588b fix: add device response timeout to Trezor bridges (#44626)
9ee3d987a7 feat: show skeleton for the whole balance block if the balance is not cached (#44703)
960369d180 fix: require interstitial for CAIP-19 asset deep links (#44639)
ef34172a99 refactor: migrate formatters to client-utils (#44624)
88c41e5489 test: cover Wallet Creation Attempted Segment event (#44673)
7a14cd7f6c feat: Updated the styles for swaps page (#44762)
ad64202e93 test: MMQA - 2035 - Fix antipatterns in sendPage which can lead to flakiness (#44640)
845b4a8f4a feat: updated avatarbase and banner alert to use DS (#44763)
3802fdba7c chore: migrate AvatarFavicon to MMDS (#44764)
a1b13be185 feat: seedless controller v10.1.0 (#44771)
864f5e5294 fix: patch bridge controller to exclude Stellar and Arc cp-13.41.0 (#44749)
ab4fbefa8d fix: non-evm bridge activity (#44751)
62fd747287 chore: removed deprecated checkbox with DS (#44765)
643d4d57cc test: added e2e tests for the new logic showing energy and bandwidth in sign transaction confirmation (#44756)
0fd8198e4b chore: remove border from pages (#44721)
1910a59ff9 feat(ledger): wire ledgerDmk flag to offscreen mode switching (#43488)
56f0a34156 chore: introduce bulk error suppression (#44739)
bd13fb6ec3 chore: updated networks for hardware accounts (#44531)
ab79e887a9 fix: updated search to be sticky and banner to scroll cp-13.41.0 (#44696)
34148d362e test(tron): prepare daily resources for E2E coverage (#44162)
4cd1d95222 chore: bump @metamask/tron-wallet-snap to ^1.33.1 (#44716)
906fee2c9d chore: bump assets controllers and remove patches (#44713)
dad0511577 test: fix flaky QrSync multi-SRP import confirm staleness timeout (#44700)
d50de2fac4 fix(metametrics): silence unmatched route Sentry noise for known paths (#44718)
4103808cae fix(ci): Remove "What's in this RC ...and more changes" section to match Extension RC Slack message to Mobile layout cp-13.41.0 (#44740)
7b2c1b2665 chore: update to ESLint v9 (#44734)
9faf0a6b5d feat: apply bg-alternative and border-muted to legacy Modal in pure black mode (#44726)
969f5c2aaa chore: update swap row labels (#44637)
2aa9b938e0 feat: apply bg-alternative and border-muted to ModalContent dialog in pure black mode (#44720)
9e40a87367 chore: New Crowdin Translations by GitHub Action cp-13.41.0 (#44595)
3ea61fd698 chore: remove unused ESLint directives from shared (#44679)
07651ccf9c chore: remove unused ESLint directives from ui/components (#44683)
0b58311684 chore: remove unused ESLint directives from remaining ui (#44685)
148b0844e4 bump: sharp to 0.35.3 (#44688)
ad1bbf43ce feat: show verified badge on swaps token button (#44623)
d5047c3a86 chore: replace sub tab screen opened metrics (#44093)
bb150a4058 feat: added skeleton for token list after stale open (#44705)
1d3f77fb38 ci: Harden absolute benchmark gate against within-noise breaches (#44609)
f3bd7f870e chore: align dapp connection bar styling with Figma spec (#44539)
42315a4087 feat: navigate users to batch sell through deeplink (#44671)
396263b848 chore: remove unneeded styles (#44693)
2acd3840a2 refactor(activity): use native dialog for transaction details (#44599)
65292d06fb bump: immutable to 5.1.9, fast-uri to 3.1.4, dompurify to 3.4.12, sass-embedded to 1.100.0 cp-13.41.0 (#44678)
57638a9616 chore: remove unused ESLint ignore directives from development (#44676)
7cb3eb6037 chore: split eslint ignore react-compiler directives (#44686)
14c815595a chore: remove unused ESLint directives from ui/pages (#44684)
8eac23857c chore: remove unused ESLint ignore directives from app (#44674)
8d99a5f7d3 test: fix flaky tests Add wallet Import wallet... (#44649)
4a1c57b063 test: fix flaky test Add account added account should persist after wallet lock (#44712)
2b218f3e77 chore(eslint): ignore .yarn and webpack build directory (#44666)
67b21b1e1b chore: update transaction controller (#44656)
77c6773132 chore: adds handler for top-traders (Follow Trading) deeplink redirect (#44660)
bceab0bb1e chore: bump @metamask/tron-wallet-snap to ^1.33.0 (#44698)
fa3885cf81 feat: setup for new defi flag (#44652)
0afcd07800 test: refactor snap-account-abstraction page object to remove references to other page objects (#44690)
3051cf4133 test: refactor account-list page object to remove references to other page objects (#44651)
edb7daa756 fix: clear orphaned advancedGasFee preference (migration 216) (#44205)
59f15bc6b0 fix: remove useAssetActivation test to unblock assets controllers bump up (#44699)
52b4b3d877 feat: removed back transitions unused selector (#44691)
f9f5e1dc48 fix: update slider step to one in batch sell (#44648)
a7847a0538 fix: do not render assets without quotes in review modal (#44650)
efa96b445e refactor: use modern clipboard api (#44622)
80b66e6c4e chore: removed sidepanel viewport max width constraint (#44647)
6d970c423d test: encryption and decryption Segment events (#44607)
1ff9bf422b chore: remove unused ESLint ignore directives from test directory (#44669)
2518a3727c feat(ui): add pure-black dark mode behind build-time flag (#44183)
d07ea1771f test: update swaps unit test mocks (#44627)
c6fc026ec2 chore: refactor ESLint overrides (#44663)
6fb3e32f55 bump: valibot to 1.4.2, body-parser to 1.20.6 and 2.3.0 (#44664)
b8c3584c53 fix(notifications): keep announcement home link in tab (#43419)
6e0219f5d6 chore: skip linting Jest snapshots (#44665)
a84d6539f5 feat: render high rate alert modal in batch sell review page (#44646)
0d81022be0 feat: integrate STX failTransaction fix (bridge stuck-pending) (#44372)
8f66b8fc55 feat: add bottom nav bar source to perps view events (#44611)
6fb1d6ba46 chore: update @metamask/gator-permissions-snap to version 2.4.0 (#44499)
9b12c19790 test: cover Empty Buy Banner Displayed event (#44617)
6c0217c496 feat: add bottom nav transitions (#44641)
8ae5ce634e chore: use same toaster-bottom-offset var for legacy toasts (#44654)
5da5008a3a test: MMQA - 1975 - Enhance feature flag validation/drift PR to omit re-orders without value change (#43814)
261773c0bb test: fix flaky tests Check balance For a non 0 balance account... (#44479)
5207d27d9c feat: add bottom nav experiment display logic and e2e tests (#44403)
1f66fc6cd7 release: Bump main version to 13.42.0 (#44642)
9962ac769f feat: implement close positions with limit orders (#44466)
477be3b0bc feat(e2e): add Tron test fixtures and environment helpers (#44160)
ffd91160c9 fix: various fixes and improvements on batch sell select page (#44603)
e091fe0b04 fix(assets): wire tempMigrateAssetsInfoMetadataAssets3346 into AssetsController init (#44303)
b685e6bf62 test: MMQA - 2034 - Fix antipatterns in qr-sync.spec.ts (#44600)
1548788667 bump: multiple to fix audit cp-13.41.0 (#44634)
6647504ca3 feat: consume backend-suggested slippage in unified swap/bridge (#44537)
e29c451b29 feat: import alias via node subpath imports (#44621)
f7f67d320b feat(ramps): add provider selection page with async quotes (#44553)
e9b745e8e5 chore: remove dead code (#44612)
bb5e12f804 refactor: migrate multichain review permissions toast (#44505)
fc5d600b60 refactor: add useEventListener (#44596)
d8c683d6c9 feat(e2e): add Tron swap token registry and quote fixtures (#44159)
39d6aa6899 refactor: migrate buy button toast (#44510)
4fa405c7e6 fix: dedicated convert mUSD details cp-13.41.0 (#44586)
a6942d1c60 feat(support): replace raw profile params with customer service token (#44482)
d4987093b8 refactor: migrate delete metametrics toast (#44503)
22c64b7f3f refactor: migrate permissions disconnect-all toast (#44504)
227a3644f0 feat(ramps): show per-method quotes on payment selection (#44526)
abc8a8267c feat: update bottom bar navigation to swaps page (#44233)
3784ae3945 feat: added decimal validation for custom token import flow cp-13.41.0 (#44602)
b495bf455d chore: patch @metamask/assets-controller for suggested occurrence floors (#44525)
88bc6591dc feat(ci): add Runway orchestrator starter and store submission CODEOWNERS (#44017)
1894816b17 refactor(analytics): remove MetaMetricsController shims and finish background migration (#44380)
c4af8823c1 feat(hardware-wallets): add signing page orchestrator (#43943)
e8baf89ff4 fix(ci): align Extension RC Slack notes with Mobile Runway changelog (#44597)
7bfc16cfc0 bump: Upgrade @sentry/browser from 8.33.1 to 10.38.0 (#42867)
a25c6a5b07 chore(6932): convert final legacy context consumers to useI18nContext for React 19 (#44493)
9b908f58d4 test: fix Add wallet Import wallet using json file - TimeoutError: Waiting for element to be located By(css selector, [data-testid="choose-wallet-type-import-account"]) (#44464)
6183003c90 refactor: resolve activity list redesign (#44365)
576a79fa6d chore: allow history navigate on activity details (#44467)
593690c0f7 chore: remove browserify (#44433)
1456a2100a fix: keep bridge activity item as pending until dest tx resolves cp-13.40.0 (#44536)
aa09362f39 fix: don't hold the KeyringController lock during hardware wallets reads (#44483)
0f5ef841a3 refactor(activity): handle swaps missing destination token (#44501)
5d12649353 test: fix flakyTest Snap getEntropy can use snap_getEntropy inside a snap (#44458)
ad3fb497ce refactor(confirmations): address send asset picker review follow-ups (#44431)
b6449df15d feat(ramps): update remaining entrypoints to use goToBuy (#44440)
8a1ccdc82c feat: gate scam questionnaire behind LaunchDarkly flag cp-13.40.0 (#44496)
c0e7a119d7 fix: mascot being rendered twice in onboarding unlock page (#44533)
4c7819aff3 fix: prevent duplicate events during tab switch (#44528)
360bc7d616 fix: bump network enablement controller to v5.6.0 (#44371)
e2f4454072 feat(ramps): add payment method selection page (#44437)
d11fa4a85a refactor: migrate gas fee token toast (#44468)
b48258de3b feat(e2e): add Tron local node mock proxy (#44157)
e149e9c519 feat: update bridge status controller to latest release (#44515)
2ba671463a bump: websocket-driver to fix audit (#44513)
8b843741f8 fix(ramps): wait for selected token before leaving token selection (#44497)
449919f484 fix: crash when typing a comma in the MM Pay custom amount input (#44521)
81ed3e6cb7 fix(ramps): keep provider label while quotes load on build quote (#44491)
e294e5fbc3 chore(tokens): remove stale token cache fallbacks (#44522)
b3a729e909 build: remove submodule added by mistake (#44514)
40f4844d3e feat: sentry for QrSync (#44487)
173e9e7a04 feat: added transitions to manage tokens page (#44484)
be631b56fa refactor: switch activity mappers to @metamask/client-utils (#44366)
41ca3b93c3 fix: Bump react-data-query (#44520)
0cd688b4bf refactor(analytics): migrate orphan multichain accounts UI events (#44376)
4400dd58c1 feat: added skeleton fr balance loading state (#44429)
397c4485f0 chore: use skeleton on loading activity screen (#44423)
29b6f2e924 chore: Revert "chore(6926): migrate ReactDOM.render to createRoot (#43872)" (#44517)
743cccdd2a refactor(analytics): migrate orphan account overview tabs events (#44375)
9efc6d62ed chore(6926): migrate ReactDOM.render to createRoot (#43872)
83d763aaa4 perf(6600): fix asset selector cache thrashing for NFTs and token scan results (#44473)
21c3992646 feat: added transitions to Dapp connections pages (#44481)
1d44802063 fix: consume local history data for bridges on activity items (#44488)
bf71e30756 refactor(analytics): migrate orphan UX contacts and chrome events (#44374)
f1c3e4103c feat(e2e): extend Tron mocks with swap tokens, stateful accounts, and parameterized fixtures (#44485)
8c0fa5b830 perf(6601): fix parameterized selector cache thrashing for chain-checking selectors (#44474)
c255a1a983 feat(perps): show ticker next to volume and fix symbol display consistency (#44478)
b169cbc8fc fix: updated analytis for add token (#44486)
d0a5db3726 feat(ramps): add build quote page with quote fetching (#44409)
4eabcbe89b chore(6931): migrate class components from defaultProps to default params (#44299)
56e0cbf45f perf(6929): harden UI effects for React 18 StrictMode double-mount (#44298)
55e0419dce perf(6602): prevent cache thrashing in parameterized network lookups (#44475)
72c5dccaa4 chore(6930): update React Compiler target to v18 (#44476)
9b7cd98c49 feat: updated CODEOWNERS for QrSync (#44465)
f2018259e3 test: QrSync e2e for multi SRP flows (#44438)
dc5bc8dc93 test(e2e): add Bitcoin send flow against local regtest node (#44156)
e34d7e67bb test: Add E2E max balance validation test (#43821)
2ff51fd902 fix: ensure stellar assets show correctly in token details page (#44444)
77cf93f811 chore: tiny header adjustments on new bottom nav pages (#44470)
fe2bc9df7d test: MMQA - 1971 - Fix missnamed test tokens/nft/filter-nfts.spec.ts same as view-nft-details.spec.ts (View NFT details) (#44086)
f5d4634e8b perf(7475): adopt useDeferredValue for search and filter surfaces (#44443)
23a9a0e228 feat(e2e): add Bitcoin regtest node wrapper using @metamask/bitcoin-regtest-up (#44155)
1986666442 feat: updated token management toggle button (#44434)
a74972d532 feat: ux improvemnets for add via chainlist feature (#44424)
bfb0b29226 test: fix flaky test Vault Corruption does not reset metamask state when recovery is not confirmed (#44435)
ccadeeeccd chore: New Crowdin Translations by GitHub Action cp-13.40.0 (#44329)
3f7584b6f0 fix: QR Sync session timeout and cancellation (#44422)
8b02f4a613 chore: reduce Sentry trace sampling cp-13.40.0 (#44451)
7cd63e4d54 perf(6778): add useStateSyncHealth hook for stale sync auto-recovery (#44389)
80a76d63d4 bump: ws to fix audit (#44459)
f602fae822 refactor: migrate perps withdraw transaction toast (#44419)
81bacd28ee fix(sentry): Resolve AggregatedBalanceSelector transaction volume spike by not passing trace into getAggregatedBalanceForAccount cp-13.40.0 (#44449)
ba18ce10ac feat(ramps): intent routing in goToBuy + stub buy pages (#44404)
2e477542ab ci(token-exchange): migrate FIXTURE_UPDATE_TOKEN to token exchange service (#43838)
2ff80c450e test(e2e): run Solana send flow against local validator (#44154)
baab980461 fix: resolve Perps deposit confirmation stuck on loading skeleton on first open (#44247)
a9f826964b ci: remove requirement for "auto-rc-builds" label (#44421)
3e52ec5ffb perf(7467): memoize composite derived state in home container and dapp bar (#44354)
8846ae56e5 feat(ramps): geo-blocking UI for ramps entry points (#44351)
c496204040 feat(e2e): add Solana local validator wrapper using @metamask/solana-… (#44426)
71f9467411 feat: reintroduce saved gas settings (#43317)
25d7175ff4 chore: nav to perps funding screen on perps funded activity details (#44427)
7657dcc0da fix: render in flight perps deposit/withdraw activity details (#44425)
78908aa279 fix(confirmations): address enforced simulations papercuts (#44343)
4b01eb4a84 feat(ramps): add in-extension token selection page (#44349)
eb3b6f521a fix(perps): mask open order size and value in privacy mode (#44432)
c6c99ecced ci(INFRA-3680): rename bot reference from mm-token-exchange-service to metamask-ci (#44387)
594bbd6f6c test: QrSync E2E (main flow) (#44381)
612334352b refactor: migrate musd claim toast (#44414)
d22a7b6118 chore: bump @metamask/tron-wallet-snap to ^1.31.0 cp-13.40.0 (#44385)
a396544397 chore: use candlestick filled icon when perps bottom nav active (#44388)
70a302b923 feat: refresh activity list after confirm (#44333)
ea74194fd2 feat: sync-accounts use image for qr code (#44417)
4631b6103f fix(mv3): move keep-alive polling to service worker startup (#44348)
5dd78ebf23 refactor(analytics): migrate settings thunk MetaMetrics events (#44379)
b400e49380 refactor(analytics): migrate orphan platform metrics UI events (#44378)
1e0188a092 perf(7465): memoize token list derivations and lift per-row Redux subscriptions to parent (#44295)
e9d9c6cd75 fix: fixed race condition on vault creation and get seedphrase (#44276)
5418dedc88 chore(preferences): remove enableMV3TimestampSave debug preference (#44373)
5bfa8fe8fb chore(6925): upgrade react & react-dom to v18 (#42997)
d3fa3dd51b chore: update CODEOWNERS bringing more code under team money-movement (#44408)
485109f500 chore: deprecated import path (#43242)
dec283a8fe refactor(analytics): migrate orphan Web3Auth onboarding events (#44377)
5291e67aa5 refactor: remove headless STX status page approval (#44301)
909c8d60b2 docs: Add Cursor Skill to automatically add new EVM networks to swaps (#44386)
4a4948b41b fix: update trackImportEvent usage to use correct params and string comparison (#44400)
355bc49105 feat: Bump Snaps packages (#44396)
cd8907a7aa perf(7467): memoize hooks/components with multiple selectors (#44297)
7c8966dd69 feat(e2e): wire Tron local node into fixtures (#44152)
82af0c7e26 fix(assets): restore google.svg and relocate to app/images/ cp-13.40.0 (#44383)
b977317023 feat(asset): migrate asset routes to CAIP-19 identifiers (#44114)
0ebadf7dd6 feat: QR sync error UI (#44081)
615c3a8fe1 feat: rename add-device to sync-accounts (#43870)
a329b0473b fix: extra pending row from local state cp-13.40.0 (#44359)
b7c7eef85a feat: wallet metadata and imported account sync via QR (#44047)
b426596c9c perf: add useMemo/useCallback memoization to home balance components (#44294)

AI Test Plan

Risk Score High Risk Medium Risk Files Changed Commits
61/100 8 5 1689 130
Cherry-Pick Scenarios (2)

High Risk Scenarios (2)

1. Deep Links Interstitial Protection

Risk Level: HIGH

Why This Matters: Cherry-pick 44830 fixes restoration of deep link interstitial protections; without it, external links could bypass expected user warnings and increase phishing risk.

Test Steps:

  1. From the OS or a test app, open a metamask:// deep link that would initiate a connect/sign flow; verify an interstitial appears showing the origin and action summary.
  2. Select Do not proceed and confirm that no permissions are granted, no signing modal opens, and no new connected site is added.
  3. Repeat and choose Proceed; verify the app then shows the standard connect/sign confirmation requiring explicit user approval.

2. App Link (https) Deep Links Interstitial

Risk Level: HIGH

Why This Matters: Cherry-pick 44830 fixes interstitial gating for web-based deep links; it ensures users cannot be silently funneled into privileged flows without an explicit checkpoint.

Test Steps:

  1. Open an https metamask.app.link deep link that routes to an Add Network or Connect flow inside the extension.
  2. Verify the interstitial appears first, showing the linking origin and intended action, with clear Cancel/Proceed options.
  3. Cancel and confirm no downstream flow is triggered; then retry and Proceed to ensure the normal Add Network/Connect confirmation still appears.

Release Scenarios (11)

High Risk Scenarios (6)

1. State Migrations (versions 217–219)

Risk Level: HIGH

Why This Matters: State migrations can corrupt or drop user data (accounts, connections, custom networks, token/NFT lists). Verifying upgrade integrity prevents data loss and post-upgrade breakages.

Test Steps:

  1. Install the previous stable extension (e.g., 13.41.x), create a wallet with 2 standard accounts and import 1 account via private key; add a custom network via wallet_addEthereumChain; enable token and NFT autodetection.
  2. Manually add a custom ERC-20 with non-18 decimals, import an NFT by contract/tokenId, and connect two different sites (each to a different account). Execute at least one transaction per account on different networks.
  3. Upgrade to 13.42.0, unlock, and allow the extension to complete migrations.
  4. Verify accounts, connected sites, custom network, tokens (including decimals, logos), NFTs (images/metadata), and settings (autodetection) are preserved and functional.
  5. Perform a quick regression: switch networks, send a small test transaction, and open Activity details to ensure no errors/regressions post-migration.

2. Token Management and Balances (Assets Controller v11)

Risk Level: HIGH

Why This Matters: A major Assets Controller update can alter token discovery, metadata, and balance calculations. Errors here directly impact asset visibility and user trust in balances.

Test Steps:

  1. On Ethereum and a sidechain (e.g., Polygon), enable token autodetection and verify common tokens appear with correct symbols, logos, and balances.
  2. Manually add a custom token with non-18 decimals; confirm balance math and fiat rounding are correct on Home and Activity details.
  3. Hide the token, lock/unlock the wallet, then unhide or re-add it; verify state persistence and no duplicate entries.
  4. Switch to an account with zero balance and confirm balances render as zero without errors or placeholders.

3. NFTs (Detection, Metadata, Transfer)

Risk Level: HIGH

Why This Matters: NFT handling relies on the same asset plumbing; regressions can break detection, metadata display, or transfers, degrading core wallet functionality for NFT users.

Test Steps:

  1. Enable NFT autodetection, then import an NFT by contract address and tokenId; confirm image and metadata load correctly.
  2. Switch to a network where the NFT does not exist and verify it is not shown; return to the original network and ensure it reappears.
  3. Transfer the NFT to another address; verify the transfer flow, Activity entry, and that the NFT leaves the collection after confirmation.

4. Network Management (Add/Switch via dapp and UI)

Risk Level: HIGH

Why This Matters: Changes in network enablement can break EIP-3085/EIP-3326 flows, preventing users from onboarding to new chains or causing permission inconsistencies.

Test Steps:

  1. From a dapp, request wallet_addEthereumChain for a known test chain; accept and confirm the new network appears and is selected.
  2. From the same dapp, request wallet_switchEthereumChain; verify the prompt, successful switch, and that the site retains permissions and correct account context.
  3. Attempt to add a network with an existing chainId but different RPC; verify the UI informs about the existing network and does not duplicate it.

5. Message Encryption/Decryption (eth_getEncryptionPublicKey, eth_decrypt)

Risk Level: HIGH

Why This Matters: Changes in decrypt/encryption key controllers can break dapp workflows or introduce cross-account data exposure, a significant security risk.

Test Steps:

  1. Using a test dapp, request eth_getEncryptionPublicKey for the active account; approve and verify the key is returned.
  2. From the dapp, request eth_decrypt for a payload encrypted to the active account; approve and verify the plaintext is returned.
  3. Switch to another account and attempt to decrypt the same payload; verify the UI blocks or errors appropriately and does not leak plaintext.

6. Transaction Signing and Activity Details

Risk Level: HIGH

Why This Matters: Core transaction flows are sensitive to UI and controller refactors; regressions can lead to incorrect confirmations or broken activity history.

Test Steps:

  1. Send a native token transaction and open its Activity details; verify status, nonce, EIP-1559 fields, explorer link, and fiat value.
  2. Sign Typed Data v4 from a dapp; verify the confirmation details (domain, message fields) are accurate and the signature returns to the dapp correctly.
  3. Speed up or cancel a pending transaction and confirm the Activity view merges/replaces entries correctly without duplicates.

Medium Risk Scenarios (5)

1. Fiat Conversion and Display Consistency

Risk Level: MEDIUM

Why This Matters: Incorrect fiat conversion or inconsistent rendering undermines decision-making and trust in displayed portfolio values.

Test Steps:

  1. Set primary currency to fiat (e.g., USD) and verify token fiat values across Home, Activity list, and transaction detail views.
  2. Switch primary currency to Native and verify all locations update without stale fiat values.
  3. Change conversion currency (e.g., USD to EUR) and confirm values update accurately and consistently throughout the UI.

2. Bridge Flow (Quotes, Approvals, Cancellations)

Risk Level: MEDIUM

Why This Matters: Bridge controller updates can affect quoting, approvals, and cleanup; issues here can strand approvals or mislead users about transfer status.

Test Steps:

  1. Open Bridge, select a source/destination network and token (e.g., ETH → USDC), and fetch quotes; verify providers, estimated time, and fees render.
  2. Proceed to approval, then cancel before final submission; confirm no stuck pending approvals or ghost Activity entries.
  3. Try an unsupported token/network pair and verify clear error messaging without crashes.

3. Connected Sites and Unconnected Account Alert

Risk Level: MEDIUM

Why This Matters: Recent alert and related UI changes can affect safety prompts; missing or incorrect alerts may cause users to transact with unintended accounts.

Test Steps:

  1. Connect a test dapp to Account 1.
  2. Switch the active account to Account 2 and reload the dapp; verify the Unconnected Account alert appears with a Connect action.
  3. Use the Connect action to authorize Account 2; verify the banner disappears and the dapp reflects the new account context.

4. Alert Modals and Stacking Behavior

Risk Level: MEDIUM

Why This Matters: Changes in the alert system utilities can break modality and focus management, causing users to get stuck or miss important warnings.

Test Steps:

  1. Trigger a confirmation modal (e.g., disconnect a connected site) and keep it open.
  2. While the modal is open, cause a general inline alert (e.g., switch to an invalid RPC network to surface an error banner).
  3. Verify the confirmation modal maintains focus and is actionable, the inline alert does not overlap or block actions, and both can be dismissed independently.

5. API Error Handling and Recovery (RPC failures)

Risk Level: MEDIUM

Why This Matters: Resilience to RPC failures ensures the wallet remains usable and clearly communicates connectivity issues without compromising functionality.

Test Steps:

  1. Configure a custom network with an invalid RPC URL and switch to it.
  2. Verify that a clear, non-blocking error message appears instead of a crash or infinite loading.
  3. Switch back to a working network and confirm the error state fully clears.

Teams Sign-off Status

Signed off: None yet

Awaiting sign-off (7):
Accounts, Assets, Confirmations, Networks, Swaps and Bridge, Transactions, Wallet Integrations


Generated by AI Test Plan Analyzer (gpt-5) at 2026-07-25T01:38:05.291Z

AI generated test plan (JSON): test-plan-13.42.0.json

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-benchmark-gate Disables `run-benchmarks/quality-gate` job team-bots Bot team (for MetaMask Bot, Runway Bot, etc.)

Projects

None yet

Development

Successfully merging this pull request may close these issues.