Repository navigation
release: 13.40.0 - #44326
release: 13.40.0#44326
Conversation
<!-- 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** The update-fixture script was broken due to the new cache build logic. This issue was fixed here: #43194 However, this has unmasked an issue with permissions in the repo (cannot fully test in the fork, that's why it was not catched there): 1. In prepare, the Cache dist artifact step failed because of this error `##[warning]Failed to save: Unable to reserve cache with key dist-f2a11c162c. cache write denied: token has no writable scopes` https://github.com/MetaMask/metamask-extension/actions/runs/28595056443/job/84790275152 <img width="1074" height="138" alt="image" src="https://github.com/user-attachments/assets/fc4a041d-ad76-4f58-9c3c-9f617be5d719" /> 2. In update-fixtures, Restore dist artifact has fail-on-cache-miss: true, so it hard-failed, the cache was never written. <img width="875" height="244" alt="image" src="https://github.com/user-attachments/assets/930526d4-788f-4cd1-80af-6728cb65bee6" /> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: ## **Related issues** Fixes: ## **Manual testing steps** 1. Not easy manual steps. Best effort: look into the failure and see fix ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask 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 - [ ] 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** > CI-only workflow permission tweak with no application or runtime behavior changes. > > **Overview** > Fixes the **Update E2E fixtures** workflow by giving the `prepare` and `update-fixtures` jobs explicit token scopes. > > Each job now declares `permissions: contents: read` and `actions: write` so steps that **download** build artifacts from another run (`gh run download`), **save/restore** cache entries, and **upload** test artifacts can run under the default `GITHUB_TOKEN` instead of failing on missing `actions` access. Commit/push behavior is unchanged and still relies on `FIXTURE_UPDATE_TOKEN` in later jobs. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 654d27a. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Sub-PR of umbrella tracker [#43885](#43885). Migrates MetaMetrics `trackEvent` call sites in this CODEOWNERS domain to `createEventBuilder` + `trackEvent` via `useAnalytics()` (UI) or `app/scripts/controllers/analytics` (background). **Dependency note:** Can merge in parallel with other domain PRs. **Files in this PR:** 26 ## **Changelog** CHANGELOG entry: null ## **Related issues** Part of analytics migration umbrella: #43885 ## **Manual testing steps** 1. Check out this branch and run `yarn start`. 2. Exercise flows in the touched domain (see diff file list). 3. Confirm no console errors and representative events still fire. <!-- ## **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-only refactor with no change to conversion, claim, or DeFi product logic; risk is mainly telemetry shape/pipeline regressions, covered by updated unit and integration tests. > > **Overview** > This PR moves **earn / mUSD** and related **DeFi** analytics off legacy `MetaMetricsContext` / `MetaMetricsController:trackEvent` onto the shared **`createEventBuilder` + `trackEvent`** path (`useAnalytics` in UI, `app/scripts/controllers/analytics` in background). > > **UI:** mUSD CTAs, claim badge, convert links, education screen, and transaction-status hooks now build events with the builder (`name`, category in `properties`, optional `sensitiveProperties`) instead of flat `{ event, category, properties }` payloads. > > **Background:** `DeFiPositionsController` gets a local `trackEvent` adapter that maps legacy controller payloads into built analytics events; the init messenger no longer delegates **`MetaMetricsController:trackEvent`**. > > **Tests:** mocks switch from `metametrics` context to `useAnalytics`; integration DeFi tests assert **`trackAnalyticsEvent`** and the new event/options shape. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit d716d33. 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** Sub-PR of umbrella tracker [#43885](#43885). Migrates MetaMetrics `trackEvent` call sites in this CODEOWNERS domain to `createEventBuilder` + `trackEvent` via `useAnalytics()` (UI) or `app/scripts/controllers/analytics` (background). **Dependency note:** Can merge in parallel with other domain PRs after PR1. **Files in this PR:** 29 ## **Changelog** CHANGELOG entry: null ## **Related issues** Part of analytics migration umbrella: #43885 ## **Manual testing steps** 1. Check out this branch and run `yarn start`. 2. Exercise flows in the touched domain (see diff file list). 3. Confirm no console errors and representative events still fire. <!-- ## **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] > **Medium Risk** > Wide refactor across privacy, security, and passkey flows could subtly change analytics payloads or context (e.g. page title, excludeMetaMetricsId), though product behavior is unchanged. > > **Overview** > This PR continues the umbrella analytics migration by replacing **`MetaMetricsContext`** `trackEvent` usage across **settings** (about, assets, preferences, privacy, security, developer tools, shared toggles) with **`useAnalytics()`** and the **`createEventBuilder` → `build()`** event shape. > > Call sites now build events with **`addCategory` / `addProperties`** instead of legacy `{ category, event, properties }` objects. Notable behavioral tweaks: **About** contact-us tracking pulls **page title** from **`useSegmentContext`** instead of `contextPropsIntoEventProperties`; **delete MetaMetrics data** success/error events pass **`excludeMetaMetricsId`** via **`build({ excludeMetaMetricsId: true })`** instead of a second `trackEvent` options argument. > > Tests drop **`MetaMetricsContext.Provider`** wrappers and **mock `useAnalytics`** (often with the real **`createEventBuilder`**), asserting the new payload shape (`name`, `properties.category`, `sensitiveProperties`). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f70ace8. 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** Sub-PR of umbrella tracker [#43885](#43885). Migrates MetaMetrics `trackEvent` call sites in this CODEOWNERS domain to `createEventBuilder` + `trackEvent` via `useAnalytics()` (UI) or `app/scripts/controllers/analytics` (background). **Dependency note:** Can merge in parallel with other domain PRs after PR1. **Files in this PR:** 19 ## **Changelog** CHANGELOG entry: null ## **Related issues** Part of analytics migration umbrella: #43885 ## **Manual testing steps** 1. Check out this branch and run `yarn start`. 2. Exercise flows in the touched domain (see diff file list). 3. Confirm no console errors and representative events still fire. <!-- ## **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 plumbing and test updates only; event names and properties are intended to stay equivalent aside from the builder payload shape. > > **Overview** > Confirmation and send flows stop using **`MetaMetricsContext`** for **`trackEvent`** and instead build events with **`createEventBuilder`** from **`useAnalytics()`**, matching the umbrella analytics migration. > > Send metrics hooks (**amount**, **asset**, **recipient** selection) and related confirmation hooks (**`useTrackERC20WithoutDecimalInformation`**, snap transaction loading screen, permit value display tests) follow the same pattern; **`excludeMetaMetricsId: false`** is preserved where it was passed before via **`.build({ excludeMetaMetricsId: false })`**. > > **`useSimulationMetrics`** also refactors incomplete-asset tracking: **`SimulationIncompleteAssetDisplayed`** fires inside a **`useEffect`** (with **`useMemo`** for display-name lookup) instead of during render, while still deduplicating with **`processedAssets`**. Tests mock **`useAnalytics`** instead of wrapping components in **`MetaMetricsContext.Provider`**. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 305e278. 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** Fixes a crash in the transaction confirmation footer: `BigNumber Error: times() number type has more than 15 significant digits`. **Cause:** BigNumber rejects raw JS numbers with more than 15 significant digits, since floats lose precision past that point. It only trusts strings for values that precise. The price API can return prices like `0.07086574003221964`, and a couple of hooks were passing that value into `.times()` as a number instead of a string. **Fix:** convert the value to a string before it hits BigNumber, in: - `useEthFiatAmount.js` - `useGasFeeToken.ts` - `Numeric.ts` (`numberToBigNumber`) — the shared helper other number conversions rely on, so this doesn't keep resurfacing elsewhere. <!-- 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: bignumber incident 1752 ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/ASSETS-3528 ## **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/ff2711fe-b071-48e0-a65d-bbda4d5ecae4 <!-- [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** > Narrow string-coercion change at BigNumber boundaries for fiat display; no auth, signing, or transaction submission logic is modified. > > **Overview** > Fixes a **transaction confirmation crash** (`BigNumber Error: times() number type has more than 15 significant digits`) when fiat conversion rates from the price API exceed JavaScript’s safe float precision (e.g. `0.07086574003221964`). > > **`numberToBigNumber`** in `Numeric.ts` now builds decimal `BigNumber`s from `String(value)` instead of the raw number, so shared `Numeric` construction and **`applyConversionRate`** no longer throw on long rates. **`useEthFiatAmount`** and **`useGasFeeToken`** likewise pass **`String(conversionRate)`** into `.times()` so hook-level fiat math matches that behavior. > > Tests cover high-precision construction, conversion rates, and gas-fee-token fiat display. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 22a656b. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## Version Bump After Release This PR bumps the main branch version from 13.39.0 to 13.40.0 after cutting the release branch. ### Why this is needed: - **Nightly builds**: Each nightly build needs to be one minor version ahead of the current release candidate - **Version conflicts**: Prevents conflicts between nightlies and release candidates - **Platform alignment**: Maintains version alignment between MetaMask mobile and extension - **Update systems**: Ensures nightlies are accepted by app stores and browser update systems ### What changed: - Version bumped from `13.39.0` to `13.40.0` - Platform: `extension` - Files updated by `set-semvar-version.sh` script ### Next steps: This PR should be **manually reviewed and merged by the release manager** to maintain proper version flow. ### Related: - Release version: 13.39.0 - Release branch: release/13.39.0 - Platform: extension - Test mode: false --- *This PR was automatically created by the `create-platform-release-pr.sh` script.* Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
## **Description** Upgrades design system packages to align with the [v50.0.0 release](https://github.com/MetaMask/metamask-design-system/releases/tag/v50.0.0) ([release PR](MetaMask/metamask-design-system#1303)). **Packages upgraded:** - `@metamask/design-system-react`: `^0.29.0` → `^0.30.0` - `@metamask/design-system-shared`: `^0.25.0` → `^0.26.0` **Unchanged (already at latest for this release line):** - `@metamask/design-system-tailwind-preset`: `^0.10.0` - `@metamask/design-tokens`: `^8.6.0` **Breaking changes addressed:** None. Release 50.0.0 is additive only. **New additions available for future use:** - `IconName.HardDrive` — hard-drive icon across shared, React web, and React Native packages ([#1302](MetaMask/metamask-design-system#1302)) **Legacy component deprecations:** - No new `@deprecated` JSDoc notices were added in this release. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** Feature: Design system upgrade to v50.0.0 Scenario: Core app functionality is unaffected Given I am on the main app screen When I navigate through the primary user flows (home, send, settings) Then the UI renders correctly with no visual regressions Scenario: Banner and tag surfaces render correctly Given I view screens that use design-system banners or tags (e.g. alerts, network notices) When the page loads Then banners and tags display with expected spacing and colors ## **Screenshots/Recordings** ### **Before** N/A – dependency-only update ### **After** N/A – dependency-only update ## **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. Made with [Cursor](https://cursor.com) Co-authored-by: Cursor <cursoragent@cursor.com>
…ile's workflow, aligns Extension RC notifications with Mobile (#42960) ## **Description** Adds Extension RC release notification improvements, aligned with the Mobile RC notification experience: - Adds an `RC Slack notify` workflow that runs after successful `Main` workflow runs on semver `release/**` branches. - Gates automated Slack posting on an open release PR targeting `stable` with the `auto-rc-builds` label. - Adds a manual `workflow_dispatch` path for testing Slack notifications with explicit `head_sha`, `semver`, `github_run_id`, and `test_channel` inputs. - Posts RC Slack messages with Extension build artifact links, changelog entries, a build pipeline link, and a “What’s in this RC” details link. - Adds a “What’s in this RC” section to prerelease PR comments, including cherry-picks since `origin/main` and changelog commits since the previous release tag. Aligns Extension RC notifications with Mobile by adding: - Cherry-picks and changelog sections to RC PR comments (collapsible tables with anchors) - "What's in this RC" link in Slack notifications pointing to PR #whats-in-this-rc anchor - "View Build Pipeline" link in Slack footer ## **Testing performed** - Verified the Slack notification workflow in `consensys-test/metamask-extension-howard`. - End-to-end run from this release branch consensys-test#72 - Slack message was posted, and the links worked ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MCRM-76?actionerId=62972968b407cc0069ffc438&sourceType=assign&atlOrigin=eyJpIjoiNGI2NmFjNGFiNjUzNGIyMmEyMDBlNjZmMGE3Mzk5M2QiLCJwIjoiaiJ9 Fixes: MetaMask/MetaMask-planning#7458 <!--## **Manual testing steps**--> ## **Screenshots/Recordings** ### **Before** <img width="543" height="392" alt="Screenshot 2026-05-27 at 1 54 28 AM" src="https://github.com/user-attachments/assets/2c3a0c82-3f60-477b-9542-fb5c26d0577b" /> ### **After** After - What's in this RC section added (this is Mobile RC PR screenshot, section should look the same for the Extension RC PR comment): <img width="546" height="809" alt="Screenshot 2026-05-27 at 1 53 50 AM" src="https://github.com/user-attachments/assets/6a0002e0-1d84-4b99-95c4-914b08bf1afa" /> <!--## **Pre-merge author checklist** ## **Pre-merge reviewer checklist**--> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches release CI (Slack, PR comments, git history) where mistakes could mis-link builds or omit RC details, but failures are treated as non-critical and secrets stay scoped to existing announce flows. > > **Overview** > **RC Slack notifications** now gate on an open `release/*` → `stable` PR with `auto-rc-builds`, pass **`BUILD_RUN_ID`** and **`PR_NUMBER`**, and post Block Kit messages with Webpack/Browserify zips, changelog snippets, **View Build Pipeline** / **View full release notes** footers, and a **What’s in this RC** link to a run-scoped PR anchor (`#user-content-whats-in-this-rc-{runId}`). The notify job checks out **default-branch** notification scripts while loading **`package.json` / `CHANGELOG.md` from the release commit**. > > **Prerelease PR comments** on `release/*` gain a **What’s in this RC** block: cherry-picks since `merge-base` with `origin/main` and changelog commits since the prior semver tag, rendered as collapsible tables (or a failure message). **`publish-prerelease`** fetches fuller git history for that section, finds the release PR via paginated open PRs matched by branch/repo, and uses **`BUILD_ANNOUNCE_TOKEN`** instead of `PR_COMMENT_TOKEN`. > > **`getBuildLinks`** moves to **`build-links.ts`** (re-exported from `artifacts.ts`) for Slack, nightly posts, and announce tooling; **`slack-rc-notification.mts`** runs via **`node`** with typed imports. Unit tests cover build links and cherry-pick extraction/markdown. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 75330e7. 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: Howard Braham <howrad@gmail.com>
## **Description** Adds React Refresh support to development webpack watch builds while keeping webpack-dev-server's built-in HMR client out of non-UI extension runtimes. The current implementation: - Disables webpack-dev-server's automatic `hot`, `liveReload`, and client injection, then registers MetaMask-specific dev-server clients from `setupMiddlewares` once the resolved WebSocket port is known. - Prepends the React Refresh runtime and `ui-client` only to the UI runtime, so React UI pages can receive Webpack HMR updates without injecting HMR code into service workers, content scripts, or other privileged entries. - Uses a dev-server protocol with two update messages: - `mm:background-update-fingerprint` for background/privileged-code changes that require `browser.runtime.reload()`. - `mm:ui-update-hash` for UI-only rebuilds that should trigger a React Refresh/Webpack hot update in open UI pages. - Fingerprints manifest scripts, background/service-worker code, and privileged HTML page entries after successful builds. If that fingerprint changes, the background client reloads the extension; if it does not, UI clients receive the UI build hash and ask their own Webpack runtime to check for hot updates. - Handles MV3 by bundling the background client into the service worker entry, and MV2 by injecting a standalone `background-client` entry into the background page. - Patches `@pmmmwh/react-refresh-webpack-plugin` with a `runtimeEntry` option so its automatic runtime injection can be disabled; MetaMask injects the runtime explicitly through `reactRefreshLoader` instead. - Adds the `webpack/hot/emitter` project type declaration and extends webpack unit coverage for the dev-server client wiring, update announcements, WebSocket message validation/reconnect behavior, React Refresh loader wiring, and SWC React refresh options. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: MetaMask/MetaMask-planning#7277 ## **Manual testing steps** 1. Run `yarn start`. 2. Reload the unpacked extension in Chrome. 3. Open a React UI page, for example the onboarding welcome page. 4. Edit a visible React component, for example remove a button in `ui/pages/onboarding-flow/welcome/welcome-login.tsx`. 5. Save the file. 6. Verify the visible UI updates without manually reloading the extension page or reloading the whole extension. 7. Verify the service worker console does not receive webpack-dev-server HMR update handling for that UI-only change. 8. Edit a background or privileged-code file. 9. Save the file and verify the extension reloads instead of attempting a UI hot update. ## **Screenshots/Recordings** Not applicable: this is build tooling/dev-server behavior with no persistent 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] > **Medium Risk** > Changes are confined to development watch tooling but touch extension reload/HMR wiring, privileged entry injection, and a patched third-party webpack plugin—incorrect behavior could cause missed updates or unwanted reloads in local dev only. > > **Overview** > **Development watch builds** now enable **React Refresh** and **Webpack HMR** for UI code only, without injecting webpack-dev-server’s default HMR client into service workers, content scripts, or other privileged entries. > > For **dev development + `--watch`**, the config adds `HotModuleReplacementPlugin`, `@pmmmwh/react-refresh-webpack-plugin` (with `runtimeEntry: false`), and SWC rules scoped to `UI_DIR_RE` with `refresh: true`. A patched plugin adds **`runtimeEntry`** so automatic React Refresh entry injection is off; **`reactRefreshLoader`** prepends the React Refresh runtime and **`ui-client`** to the UI load entry via a `pre` rule from **`setupUiClient`**. > > **Dev-server wiring** moves from a static `DEV_SERVER_OPTIONS` to **`getDevServerOptions({ uiClientRule })`** on the webpack config; **`build.ts`** starts WDS with `options.devServer`. Custom clients replace full-page UI reload: **`ui-client`** listens for **`mm:ui-update-hash`** and emits `webpackHotUpdate`; **`background-client`** handles **`mm:background-update-fingerprint`** and triggers `browser.runtime.reload()` when privileged code changes. **`setupBackgroundClient`** still chooses extension reload vs UI update from build fingerprints. MV2 HTML injection drops the old UI reload entry; **`injectEntryScripts`** skips `.hot-update.` chunks. > > Also adds **`react-refresh`** dependency, LavaMoat policy entries for the plugin, **`webpack/hot/emitter`** types, and expanded unit tests (dev-server, loader, webpack config, WebSocket reconnect/`isDone` behavior). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f089dc1. 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: Howard Braham <howrad@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** <!-- 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? --> Replacement for #42914 as CI made it impossible to merge that PR. ## **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: change the native asset icon (RBTC) for Rootstock ## **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** > Static image swap only; no logic, auth, or network behavior changes. > > **Overview** > Replaces **`app/images/rootstock-native.svg`** with a new artwork used wherever **`ROOTSTOCK_NATIVE_TOKEN_IMAGE_URL`** points (Rootstock mainnet and testnet native RBTC in the wallet UI). > > The old asset was a large, multi-path illustration (green/orange palette, oversized viewBox). The new one is a **560×560** hex badge with orange **`#ff9100`** fill and a white Bitcoin mark, with simplified CSS classes. No TypeScript or wiring changes—only the SVG file. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 24b7caa. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…cp-13.39.0 (#44006) <!-- 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 integrates the `QuoteStatusManager` from `@metamask/bridge-status-controller` v74 into MetaMask Mobile, aligning mobile with the extension's bridge quote status tracking. **Reason for change:** Bridge swaps need server-side quote status tracking (submit/update/poll) so the backend can correlate user transactions with bridge quotes. `@metamask/bridge-status-controller` v74 exposes this via `QuoteStatusManager`, gated behind a remote feature flag. **Solution:** - Bumps `@metamask/bridge-status-controller` to `^74.0.0` and `@metamask/transaction-pay-controller` to `^23.17.2` - Wires `BridgeStatusController` init with: - `clientProduct: 'metamask-mobile'` - `isQuoteStatusManagerEnabled` — reads the `bridgeQuoteStatusManager` remote feature flag (respects local overrides) - `onQuoteStatusManagerError` — reports `QuoteStatusUpdateError` to Sentry; `QuoteStatusGetError` is not reported (expected polling failures) - Registers `bridgeQuoteStatusManager` in the E2E feature flag registry (enabled by default for version `8.2.0`) - Adds `quoteUpdateStatusStore` to test fixtures and bridge API mocks for `GET /getQuoteStatus` and `POST /quote/updateStatus` <!-- 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-4452 ## **Manual testing steps** ```gherkin Feature: Bridge Quote Status Manager Scenario: Quote status manager is disabled by default Given the app is installed with default remote feature flags When a bridge/swap transaction is initiated Then no requests are made to /getQuoteStatus or /quote/updateStatus Scenario: Quote status manager tracks swap quote lifecycle when enabled Given the bridgeQuoteStatusManager remote feature flag is enabled (via local override or LaunchDarkly) And the user has a funded wallet on a supported source chain When the user completes a bridge or swap transaction Then the app sends a POST to /quote/updateStatus with SUBMITTED status after tx submission And the app polls GET /getQuoteStatus for quote status updates And bridge transaction history continues to display correctly in Activity Scenario: Quote status update errors are reported to Sentry Given bridgeQuoteStatusManager is enabled And the /quote/updateStatus endpoint returns an error When a swap transaction is submitted Then a QuoteStatusUpdateError is captured in Sentry And QuoteStatusGetError polling failures are NOT captured in Sentry ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask 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 bridge swap submission/polling and transaction-batch wiring behind a feature flag; mis-flag or error-handling behavior could affect bridge activity without blocking swaps when disabled. > > **Overview** > Integrates **bridge quote status tracking** from `@metamask/bridge-status-controller` **v74** by bumping that package (and `@metamask/transaction-pay-controller`) and extending `BridgeStatusController` initialization with **`clientProduct` / `clientVersion`**, a remote-flag gate **`isQuoteStatusManagerEnabled`** (`bridgeQuoteStatusManager`), and **`onQuoteStatusManagerError`** that sends **`QuoteStatusUpdateError`** to Sentry while ignoring **`QuoteStatusGetError`**. > > Exposes new persisted/UI state **`quoteUpdateStatusStore`** (fixtures, background types, metrics snapshots) and excludes it from Sentry state reporting. **LavaMoat** policies grant `fetch` / interval timers to the updated controller package. > > Also adds **Stellar pubnet** (`XlmScope.Pubnet`) to featured multichain network chain IDs and refreshes lockfile transitive MetaMask deps. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 27b7626. 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: MetaMask Bot <metamaskbot@users.noreply.github.com>
…nAccountService:createNextMultichainAccountGroup` (#44103) ## **Description** This binds the `createNextMultichainAccountGroup` `getApi()` method directly to the `MultichainAccountService:createNextMultichainAccountGroup` messenger action, removing the redundant `MetamaskController` wrapper. The UI thunk is updated to pass `{ entropySource }` so the argument shape matches the action's signature. ## **Changelog** CHANGELOG entry:null ## **Related issues** Progresses: https://consensyssoftware.atlassian.net/browse/WPC-1090 ## **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** > Small wiring refactor with an explicit argument-shape fix; behavior should be unchanged if the service already expected `{ entropySource }`. > > **Overview** > Removes the **`MetamaskController`** wrapper for **`createNextMultichainAccountGroup`** and exposes **`getApi()`** as a direct **`controllerMessenger.call`** to **`MultichainAccountService:createNextMultichainAccountGroup`**. > > The UI thunk and its test now pass **`{ entropySource }`** (stripped wallet id) instead of a bare string, so the background RPC matches the messenger action’s expected argument shape. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 99e2b31. 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** <!-- 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? --> Remove left-over code following up #43461 The "Turn on notifications" modal usage has been removed. This PR removes remaining files and translations ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: ## **Related issues** Fixes: ## **Manual testing steps** 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** > Dead-code and i18n cleanup only; no remaining references to the removed modal or strings in the repo. > > **Overview** > Removes leftover **Turn on MetaMask notifications** UI after the modal was already disconnected from product flows in a prior change. > > The `TurnOnMetamaskNotifications` component, its test, barrel export, and `TURN_ON_METAMASK_NOTIFICATIONS` entry in the central modal registry are deleted. Locale strings used only by that modal (`turnOnMetamaskNotifications*`, except `turnOnMetamaskNotificationsError`) are dropped across all `app/_locales` files. Jest console baseline no longer tracks the removed test file. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 21f4da2. 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**
Move `AddressBookController` initialization to `@metamask/wallet@6.0.0`.
The controller is now wired inside the wallet library with no
extension-specific instance options required.
Deletes the local init file, messenger file, and their tests. Resolves
the instance via `this.wallet.getInstance('AddressBookController')` in
`MetaMaskController`. No functional changes.
## **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. Build the extension and open it.
2. Add, edit, and delete a contact in the address book.
3. Confirm contacts persist across page reloads.
## **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]
> **Medium Risk**
> Touches persisted contact data and controller startup order via a
major @metamask/wallet bump; behavior should match if wallet init is
equivalent, but regressions in add/edit/persist need manual
verification.
>
> **Overview**
> **Address book** is no longer bootstrapped in the extension; it comes
from **`@metamask/wallet@6.0.0`**, which now owns
**`AddressBookController`** initialization (including
**`@metamask/address-book-controller`**).
>
> The extension drops the local **`AddressBookControllerInit`**,
restricted messenger factory, and their tests, and removes
**`AddressBookController`** from **`messengerClientInitFunctions`** and
**`MESSENGER_FACTORIES`**. **`MetaMaskController`** resolves the
controller with **`this.wallet.getInstance('AddressBookController')`**,
same as **`AccountsController`** and **`KeyringController`**.
>
> **LavaMoat** policies are updated so **`@metamask/wallet`** may use
**`@metamask/address-book-controller`**. **`package.json`** /
**`yarn.lock`** bump **`@metamask/wallet`** from **5.0.0** to **6.0.0**.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
22148c9. 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: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: MetaMask Bot <metamaskbot@users.noreply.github.com>
## **Description** Sub-PR of umbrella tracker [#43885](#43885). Migrates MetaMetrics `trackEvent` call sites in this CODEOWNERS domain to `createEventBuilder` + `trackEvent` via `useAnalytics()` (UI) or `app/scripts/controllers/analytics` (background). **Dependency note:** Can merge in parallel with other domain PRs after PR1. **Files in this PR:** 28 ## **Changelog** CHANGELOG entry: null ## **Related issues** Part of analytics migration umbrella: #43885 ## **Manual testing steps** 1. Check out this branch and run `yarn start`. 2. Exercise flows in the touched domain (see diff file list). 3. Confirm no console errors and representative events still fire. <!-- ## **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] > **Medium Risk** > Touches many onboarding funnel telemetry paths; wrong event shape could skew metrics, but behavior is largely a refactor with updated test coverage. > > **Overview** > Onboarding UI analytics moves off **`MetaMetricsContext.trackEvent`** onto **`useAnalytics()`** with **`createEventBuilder(...).addCategory(...).addProperties(...).build()`** across password creation, SRP import/review/confirm, MetaMetrics opt-in, privacy settings, wallet-ready completion, and related screens. **`MetaMetricsContext`** is still used where needed for tracing (e.g. buffered traces on create-password and recovery flows). > > **`onboarding-flow`** wires social-import unlock through a **`trackLegacyEventForAction`** adapter so **`restoreSocialBackupAndGetSeedPhrase`** keeps receiving the old payload shape while events are built with the new API. > > **Tests and tooling:** unit tests mock **`useAnalytics`** (create-password asserts on **`name`** instead of **`event`**); integration onboarding tests expect background **`trackAnalyticsEvent`** with **`name`** / **`properties`** (category nested in properties). Storybook aliases **`useAnalytics`** to a no-op mock; Import SRP stories drop the MetaMetrics provider wrapper. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 942625f. 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** Sub-PR of umbrella tracker [#43885](#43885). Migrates MetaMetrics `trackEvent` call sites in this CODEOWNERS domain to `createEventBuilder` + `trackEvent` via `useAnalytics()` (UI) or `app/scripts/controllers/analytics` (background). **Dependency note:** Can merge in parallel with other domain PRs after PR1. **Files in this PR:** 15 ## **Changelog** CHANGELOG entry: null ## **Related issues** Part of analytics migration umbrella: #43885 ## **Manual testing steps** 1. Check out this branch and run `yarn start`. 2. Exercise flows in the touched domain (see diff file list). 3. Confirm no console errors and representative events still fire. <!-- ## **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] > **Medium Risk** > Analytics event shape and property placement change across onboarding and OAuth callbacks, which could alter Segment payloads if builders differ from legacy context merging; user-facing onboarding behavior is unchanged. > > **Overview** > Onboarding **welcome and account-status flows** now emit MetaMetrics through **`useAnalytics()`** and **`createEventBuilder().addCategory().addProperties().build()`** instead of legacy `MetaMetricsContext.trackEvent({ category, event, properties })`. > > **`useAccountStatusContext`** sources `trackEvent` / `createEventBuilder` from analytics while keeping buffered traces on `MetaMetricsContext`. **Welcome** adds **`trackLegacyEventForAction`** so **`startOAuthLogin`** still receives a legacy-shaped callback that is converted to builder events. **Login error modal** drops context-based tracking; support-link events use **`useSegmentContext`** for `location` (e.g. page title **Welcome**) instead of `MetaMetricsContextProp.PageTitle`. > > Tests mock **`useAnalytics`** (and segment context where needed) and assert the new payload shape (`name` + `properties` including `category`). **`txDataSelector`** uses optional chaining on `confirmTransaction` as a small unrelated hardening. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit c671f60. 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** Sub-PR of umbrella tracker [#43885](#43885). Migrates MetaMetrics `trackEvent` call sites in this CODEOWNERS domain to `createEventBuilder` + `trackEvent` via `useAnalytics()` (UI) or `app/scripts/controllers/analytics` (background). **Dependency note:** Can merge in parallel with other domain PRs after PR1. **Files in this PR:** 21 ## **Changelog** CHANGELOG entry: null ## **Related issues** Part of analytics migration umbrella: #43885 ## **Manual testing steps** 1. Check out this branch and run `yarn start`. 2. Exercise flows in the touched domain (see diff file list). 3. Confirm no console errors and representative events still fire. <!-- ## **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] > **Medium Risk** > Touches analytics emission across OAuth onboarding failures and Shield subscription flows; behavior should be equivalent but any regression could skew product metrics or drop pre-consent buffered events. > > **Overview** > Migrates **Shield, subscription, OAuth, and related UI** from legacy `MetaMetricsController:trackEvent` / `MetaMetricsContext` to **`createEventBuilder` + `trackEvent`** (`app/scripts/controllers/analytics` in background, `useAnalytics()` in UI). > > **Background:** `SubscriptionService` drops the `MetaMetricsController:trackEvent` messenger delegate and emits Shield metrics (cohort assignment, subscription requests, payment method changes, rewards opt-in) via the analytics module. `OAuthService` no longer accepts an injected `trackEvent`; social login failure events use the builder API while **pre–opt-in buffering** still maps built events back to `addEventBeforeMetricsOptIn` when onboarding/opt-in are incomplete. > > **UI:** Modals (`AddFundsModal`, support data consent) and `useSubscriptionMetrics` switch to `useAnalytics`, with a shared `trackShieldEvent` helper to reduce duplication. Support link clicks now put **page title** on the event properties (via `useSegmentContext`) instead of the old `contextPropsIntoEventProperties` option. > > Tests are updated to mock `useAnalytics` / `controllers/analytics` and to split OAuth init mocks between `MetaMetricsController` and `AnalyticsController` for opt-in state. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit e77a542. 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** Extracted mockAuthenticatedUserStorageNotificationPreferences into test/e2e/helpers/authenticated-user-storage/mocks.ts and removed it from identity mocks. Global E2E setup now imports it directly from the dedicated file. <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: ## **Related issues** Fixes: ## **Manual testing steps** 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** - [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 refactor of mock registration and URL matching; no production code paths. > > **Overview** > **Authenticated User Storage** notification-preferences E2E mocking is moved out of `test/e2e/tests/identity/mocks.ts` into `test/e2e/helpers/authenticated-user-storage/mocks.ts`, so it is no longer bundled with identity/auth `mockIdentityServices`. > > Global setup in `mock-e2e.js` now registers that mock directly next to identity APIs. Behavior is unchanged (in-memory GET 404 until PUT, then GET returns prefs), but the mock URL matcher now covers **dev-api**, **uat-api**, and **api** user-storage hosts via regex instead of a single production URL. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit bb0ab5e. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Sub-PR of umbrella tracker [#43885](#43885). Migrates MetaMetrics `trackEvent` call sites in this CODEOWNERS domain to `createEventBuilder` + `trackEvent` via `useAnalytics()` (UI) or `app/scripts/controllers/analytics` (background). **Dependency note:** Can merge in parallel with other domain PRs after PR1. **Files in this PR:** 9 ## **Changelog** CHANGELOG entry: null ## **Related issues** Part of analytics migration umbrella: #43885 ## **Manual testing steps** 1. Check out this branch and run `yarn start`. 2. Exercise flows in the touched domain (see diff file list). 3. Confirm no console errors and representative events still fire. <!-- ## **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; event names and property semantics are preserved with updated payload structure. Low risk to backup/sync behavior aside from verifying metrics still fire in manual testing. > > **Overview** > This PR moves **Backup and Sync** MetaMetrics tracking onto the shared **`createEventBuilder` + `trackEvent`** pattern used elsewhere in the analytics migration. > > **UI** components (`BackupAndSyncToggle`, feature toggles, turn-on modal) drop **`MetaMetricsContext`** in favor of **`useAnalytics()`**, building events with **`name`** / **`properties.category`** (plus **`sensitiveProperties`**) instead of top-level **`event`** / **`category`**. **Tests** mock **`useAnalytics`** and assert the new payload shape. > > **Background** contact-sync callbacks in **`UserStorageControllerInit`** call **`trackEvent(createEventBuilder(...).build())`** from **`app/scripts/controllers/analytics`** instead of **`initMessenger.call('MetaMetricsController:trackEvent', ...)`**. The user-storage **init messenger** no longer delegates **`MetaMetricsController:trackEvent`** ( **`AllowedInitializationActions`** is **`never`** ). > > **`privacy-settings.test.tsx`** adds a **`useAnalytics`** mock so onboarding privacy tests still run with child components that use the new hook. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit e20763d. 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>
#44128) <!-- 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** We still have permissions issues with the update-fixture script, after adding read/write permissions: <img width="2148" height="276" alt="image" src="https://github.com/user-attachments/assets/32ef0098-a51f-4599-b7cd-87f58f05aae5" /> The reason is because of a github policy change in 26-06-2026, [Read-only Actions cache for untrusted triggers](https://github.blog/changelog/2026-06-26-read-only-actions-cache-for-untrusted-triggers/) So we can no longer save caches. This PR replaces the cache-based job-to-job handoffs in update-e2e-fixtures.yml with artifacts, and revert the permissions change (no effect) ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: ## **Related issues** Fixes: ## **Manual testing steps** 1. It's utterly complex to test the same conditions on a fork. After PR is merged we can create a test PR. There's very low risk, as if broken, the only thing that won't work is the update-fixtures job (which is currently already broken) and only triggered by the bot comment (we have the manual alternative as workaround) ## **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** > CI-only change to a bot-triggered fixture update workflow; no application or runtime behavior changes. > > **Overview** > Restores the **@metamaskbot update-e2e-fixture** flow after GitHub’s read-only Actions cache policy for untrusted triggers (e.g. `issue_comment` on PRs), which blocked `cache/save` between jobs. > > **prepare** now uploads the downloaded `build-dist-webpack` bundle as `dist-<commit-sha>`; **update-fixtures** downloads that artifact instead of restoring a cache, then uploads regenerated `onboarding-fixture.json` and `default-fixture.json` as `fixtures-<commit-sha>`. **commit-updated-fixtures** downloads those fixtures into `test/e2e/fixtures` before diffing and committing. > > Job-level `contents: read` / `actions: write` permissions added for cache writes are removed. Upload steps use `if-no-files-found: error` and `overwrite: true` so re-runs can replace prior artifacts. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 61a4abe. 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** Switching accounts (and many other quick operations) **always** briefly flashed the full-screen loading overlay. For operations that resolve in a few milliseconds, the spinner makes the app feel slower This PR adds a `useSpinDelay` hook that withholds the spinner until loading has run for at least a certain duration, and once shown pins it for a minimum duration to prevent flicker on the way out. Summary: - fast operations no longer flash a spinner - genuinely slow operations still show one ## **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: chore: defer global spinners ## **Related issues** Fixes: ## **Manual testing steps** 1.Unlock the wallet and open the account list 2. Switch between accounts several times 3. Verify no loading spinner flashes during the switch 4. Open Settings and toggle a few preferences ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** https://github.com/user-attachments/assets/35785229-a9c5-4e82-978a-ad2fac88bd8d https://github.com/user-attachments/assets/aac6568c-51f4-44df-854c-bc1fdcd51a87 <!-- [screenshots/recordings] --> ### **After** https://github.com/user-attachments/assets/ce2a590d-2d56-4a53-a4f6-a8ecacf94c16 https://github.com/user-attachments/assets/ce3025aa-cdac-4098-adc6-389a679b56ac <!-- [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** > UI-only timing change on the global loading overlay with no auth, data, or API impact; behavior is covered by unit tests. > > **Overview** > Adds **`useSpinDelay`** so the full-screen loading overlay no longer appears on very short `appState.isLoading` bursts (e.g. account switching). > > The hook waits **300ms** before showing a spinner and, once visible, keeps it up for at least **400ms** to avoid flicker. **`Routes`** now gates the overlay with `showLoadingOverlay = useSpinDelay(isLoading)` instead of tying visibility directly to `isLoading`; existing guards (onboarding, confirmations, redesigned flows, deep link) are unchanged. > > Unit tests cover delay, min duration, early resolution, defaults, and unmount cleanup. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit b2a8591. 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 sets the codeowners of `app/scripts/metamask-controller.js` to `core-platform` and `extension-platform` ## **Changelog** 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** > Process-only change to review requirements; no runtime or build behavior is modified. > > **Overview** > Updates **`.github/CODEOWNERS`** so changes to **`app/scripts/metamask-controller.js`** require review from **@MetaMask/extension-platform** and **@MetaMask/core-platform**, with a new co-ownership comment for that path. > > The **metamask-template-renderer** entry comment is updated from Snaps to **Core Platform** (owners unchanged). A prior **Confirmations and Snaps** comment block is removed in favor of these sections. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 9219389. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…e and removes one (#44094) <!-- 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** Test is failing in CI: Ledger Account 2 was partially scrolled out of view, so clicking its options button didn't open the dropdown menu. Added `scrollToElement()` before clicking the options button in `openMultichainAccountMenu`, ensuring the account is fully visible before the click. CI [logs](https://github.com/MetaMask/metamask-extension/actions/runs/28572596324/job/84715535505) ## **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** <img width="780" height="493" alt="test-failure-screenshot-1" src="https://github.com/user-attachments/assets/2dcba58a-c1ad-4bb8-8ba0-ee0db027cc2d" /> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask 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** > E2E page-object locator change only; no production wallet or extension runtime behavior is affected. > > **Overview** > **`openMultichainAccountMenu`** no longer uses a CSS `aria-label` selector plus `findElements` and an array index. It now clicks through a new **indexed XPath** helper that matches `multichain-account-cell-end-accessory` by quoted `"{accountLabel} options"` and picks the **(srpIndex + 1)** match when duplicate labels exist across SRPs. > > `srpIndex` defaults to **0** via destructuring, and the click goes through **`driver.clickElement({ xpath })`** instead of manually indexing WebElements. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 7004750. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
`getUnconnectedAccounts` was an unmemoized function that called `.filter()` on every invocation, returning a new array reference even when the underlying accounts and permissions hadn't changed — triggering unnecessary re-renders in the connections UI. CHANGELOG entry: null Fixes: https://github.com/MetaMask/MetaMask-planning/issues/6411 ## Changes - **`ui/selectors/selectors.js`** — Converts `getUnconnectedAccounts` from a plain function to a `createSelector`-memoized selector using `getMetaMaskAccountsOrdered` and `getOrderedConnectedAccountsForConnectedDapp` as input selectors. Since `createSelector` forwards all arguments to input selectors, `activeTab` continues to be passed correctly to `getOrderedConnectedAccountsForConnectedDapp`. ```js // Before export function getUnconnectedAccounts(state, activeTab) { const accounts = getMetaMaskAccountsOrdered(state); const connectedAccounts = getOrderedConnectedAccountsForConnectedDapp(state, activeTab); return accounts.filter((account) => !connectedAccounts.some((c) => c.address === account.address), ); } // After export const getUnconnectedAccounts = createSelector( getMetaMaskAccountsOrdered, getOrderedConnectedAccountsForConnectedDapp, (accounts, connectedAccounts) => accounts.filter((account) => !connectedAccounts.some((c) => c.address === account.address), ), ); ``` - **`ui/selectors/selectors.test.js`** — Adds a `describe('getUnconnectedAccounts')` block covering: filtering connected accounts out of results, returning all accounts when none are connected, and returning an empty array when all accounts are connected. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Selector refactor with equivalent behavior and new unit tests; no auth, security, or data-path changes. > > **Overview** > **Memoizes** `getUnconnectedAccounts` with `createSelector`, using `getMetaMaskAccountsOrdered` and `getOrderedConnectedAccountsForConnectedDapp` as inputs so the filtered list keeps a stable reference when accounts and dapp permissions are unchanged—reducing extra re-renders in the connections UI. > > The filter logic is unchanged; the second argument (`activeTab` / origin) still flows through to the connected-accounts input selector. > > **Tests:** adds `getUnconnectedAccounts` coverage (partial connect, none connected, all connected) and toggles Reselect `inputStabilityCheck` off in the test file so dev-mode checks do not fail on this suite. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit c7e5977. 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>
…uest` (#44132) ## **Description** `handleSnapRequest` was a pure single-action passthrough to `SnapController:handleRequest`. Rather than routing it through `LegacyBackgroundApiService`, this binds the `getApi` entry directly to `SnapController:handleRequest` via the controller messenger, and repoints the three construction-time `handleRequest` hooks (used by `forwardRequestToSnap` in the permissions-kernel snap setup) to the same direct bind. The now-unused `handleSnapRequest` controller method is removed. Behavior is unchanged: the action handler takes the same `args` object the old method passed through. ## **Related issues** Progresses: https://consensyssoftware.atlassian.net/browse/WPC-1094 ## **Manual testing steps** 1. Open a dapp that triggers a snap RPC request (e.g. a snap name resolution or snap home page). 2. Confirm the snap request resolves as before. ## **Screenshots/Recordings** ### **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** > Pure refactor with equivalent messenger routing; no change to RPC args or snap execution behavior. > > **Overview** > Removes the **`handleSnapRequest`** wrapper on `MetaMaskController` and wires snap RPC handling straight to **`SnapController:handleRequest`** through `controllerMessenger.call.bind(...)`. > > The same bound handler is used for the legacy **`getApi`** `handleSnapRequest` entry and for the three **`forwardRequestToSnap`** hooks in the permissions-kernel snap setup (execution permission processing). Call sites still pass the same `args` object; only the indirection through the controller method is gone. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit b815f87. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…updateNetworksList` (#44133) ## **Description** Part of the WPC-418 effort to slim down `MetamaskController.getApi()`. The `updateNetworksList` getApi entry was a thin pass-through over `networkOrderController.updateNetworksList`, wrapped only in a `try/catch` that logged and rethrew. Since the `NetworkOrderController:updateNetworksList` messenger action already exists (the method is in `MESSENGER_EXPOSED_METHODS`), the getApi entry is now bound directly to that action via the controller messenger and the redundant `MetamaskController` wrapper method is removed. No behavior change for the client: the UI thunk still calls `submitRequestToBackground('updateNetworksList', [chainIds])` with the same argument shape. Progresses: https://consensyssoftware.atlassian.net/browse/WPC-1096 ## **Changelog** CHANGELOG entry: null ## **Related issues** Progresses: https://consensyssoftware.atlassian.net/browse/WPC-1096 ## **Manual testing steps** 1. Open the network list in the UI and reorder networks via drag and drop. 2. Confirm the new order persists (state `orderedNetworkList` is updated) after reload. ## **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] > **Low Risk** > Thin routing refactor with no intended change to network ordering logic; only error logging around the old wrapper is dropped. > > **Overview** > Part of slimming **`MetamaskController.getApi()`**, **`updateNetworksList`** is no longer implemented as a **`MetamaskController`** method that forwarded to **`networkOrderController.updateNetworksList`** inside a log-and-rethrow **`try/catch`**. > > The background API entry is now **`this.controllerMessenger.call.bind(..., 'NetworkOrderController:updateNetworksList')`**, matching other controller actions already exposed on the messenger. Callers such as **`submitRequestToBackground('updateNetworksList', [chainIds])`** should still hit the same controller logic and argument shape; failures will surface from the messenger path without the extra **`log.error`** wrapper. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 1f5e890. 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** On gas-sponsorship networks, Monad, hardware-wallet transactions fail instantly with no device prompt: `eth_sendRawTransaction: Invalid parameters: transaction could not be decoded: not enough input to decode` The `TransactionController` sets `isExternalSign = true` whenever a transaction is gas-sponsored, regardless of account type. That flag skips the signing step, so the device is never prompted and `rawTx` is never produced. EOA accounts are unaffected because the EIP-7702 relay submits on their behalf; hardware wallets cannot hold a 7702 delegation, so no relay catches the publish and an empty payload is sent. <!-- 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: disable gas sponsorship for hw wallets ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MUL-1947?atlOrigin=eyJpIjoiOTYzMGIyOWRjNTE2NDJhZWEwM2NmYTUzNGUwOGZjOGUiLCJwIjoiaiJ9 ## **Manual testing steps** 1. Select a **hardware-wallet account** (not an EOA). 2. Initiate a send of a **small, sponsorship-eligible** amount of native token (stay under Monad's gas sponsorship cap; keep gas modest). *This matters — if the transaction is ineligible for sponsorship, the bug does not reproduce and the fix cannot be verified.* 3. On the confirmation screen, confirm the transaction. 4. **Verify:** the hardware device prompts for signature (Ledger displays the transaction / Trezor shows the review screen). This is the key fix — previously the transaction failed instantly with no device prompt. 5. Approve the transaction on the device. 6. **Verify:** the transaction submits successfully and lands on chain (no `transaction could not be decoded` error; a transaction hash is returned). 7. **Non-regression (EOA):** switch to an EOA (HD/imported) account on the same network and send a transaction. Verify it is still gas-sponsored (the "Paid by MetaMask" indicator appears / no native gas is deducted). ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask 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 transaction confirm approval and gasless/external-sign routing; wrong conditions could break EIP-7702 gas sponsorship for EOAs or leave HW txs broken. > > **Overview** > Fixes **instant failures on gas-sponsored networks** (e.g. Monad) when confirming with a **hardware wallet**: the device never prompted and `eth_sendRawTransaction` failed with an undecodable transaction. > > On confirm, `useTransactionConfirm` now clears **`isExternalSign`** (and sponsorship flags already follow **`isGaslessSupported`**) whenever gasless is **not** supported for the account/chain—not only when the user opts out of sponsorship. Gas estimation can set `isExternalSign` for any sponsored tx; leaving it on skips signing and sends an empty raw tx when no EIP-7702 relay applies (typical for HW). > > Tests cover clearing `isExternalSign` when gasless is unsupported vs keeping it when gasless is supported; confirmation test fixtures accept **`isExternalSign`**. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit cef323c. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
release: sync stable to main for version 13.38.0
## **Description** This PR prevents Sentry event processing from recursively reporting storage read failures. Sentry uses persisted state to determine MetaMetrics participation when no in-memory snapshot is available; if that persisted-state read failed, `PersistenceManager.get` reported the failure to Sentry, which re-entered the same persisted-state read path. The fix adds an optional `reportErrors` flag to persisted-state reads. Normal reads still report storage failures by default, while Sentry's analytics-state lookup disables reporting and falls back to backup/null without causing another Sentry capture. ## **Changelog** CHANGELOG entry: null <!-- ## **Related issues** Fixes: --> ## **Manual testing steps** 1. Run the extension from this branch. 2. Complete onboarding or unlock an existing test wallet. 3. Trigger an error report while the background is still initializing or while persisted state is unavailable. 4. Verify the extension does not repeatedly capture the same storage read failure. <!-- ## **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. ## Validation - `yarn test:unit app/scripts/lib/sentry-get-state.test.ts app/scripts/lib/setup-initial-state-hooks.test.ts shared/lib/stores/persistence-manager.test.ts` - `yarn lint:changed:fix` - `git diff --check` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches persistence error reporting and Sentry’s analytics consent path; behavior change is narrowly scoped with defaults preserved, but mis-wiring `reportErrors` could hide real storage read failures from Sentry. > > **Overview** > Adds an optional **`reportErrors`** flag on persisted-state reads so storage **`get`** failures can still be logged without always sending **`captureException`** to Sentry. > > **`PersistenceManager.get`** now accepts **`reportErrors`** (default **`true`**); when **`false`**, read errors are logged but not reported. **`getPersistedState`** forwards the same option, and **`getAnalyticsState`** calls **`getPersistedState({ reportErrors: false })`** so MetaMetrics lookups during Sentry event processing do not re-trigger persisted reads that report back into Sentry. > > Default behavior for normal wallet reads is unchanged (**`reportErrors: true`**). Types and unit tests cover the hook wiring and the no-capture path. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit e1140f3. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
Builds ready [143f29b]
⚡ Performance Benchmarks (Total: 🟢 14 pass · 🟡 7 warn · 🔴 3 fail)
Bundle sizes
🍒 What's in this RCCherry-picks (171 commits)
Changelog (8 commits from main at RC cut)
AI Test Plan
Cherry-Pick Scenarios (4)High Risk Scenarios (1)1. Activity List – Duplicate Pending RowsRisk Level: HIGH Why This Matters: Cherry-pick 44370 fixes duplicate pending rows from local state; duplicates mislead users about transaction status and can cause erroneous retries. Test Steps:
Medium Risk Scenarios (3)1. Featured Networks – Robinhood ChainRisk Level: MEDIUM Why This Matters: Cherry-pick 44346 adds Robinhood Chain as a featured network; misconfiguration (chainId/RPC/explorer) can break switching and confuse users. Test Steps:
2. Token Management – Non-EVM Search Imports (Unified Assets)Risk Level: MEDIUM Why This Matters: Cherry-pick 44361 seeds unified assets for non-EVM search imports; without this, users may fail to find or add popular non-EVM assets. Test Steps:
3. Balances – AggregatedBalanceSelector StabilityRisk Level: MEDIUM Why This Matters: Cherry-pick 44460 reduces tracing in AggregatedBalanceSelector to stop a transaction volume spike; it must not destabilize or misreport balances. Test Steps:
Release Scenarios (10)High Risk Scenarios (4)1. State Migrations (Migration 216)Risk Level: HIGH Why This Matters: State migrations can corrupt or drop user data; verifying upgrade paths ensures accounts, networks, and assets remain intact after migration 216. Test Steps:
2. Seedless Onboarding (Migration/Resume behavior)Risk Level: HIGH Why This Matters: Changes to seedless onboarding migrations can strand users mid-flow or create unusable accounts; resuming and completing must be reliable. Test Steps:
3. Transaction Flow (Send/Speed Up/Cancel)Risk Level: HIGH Why This Matters: Core controller and UI changes can subtly break confirmation flows, status transitions, or gas handling; ensuring send/speed up/cancel work prevents loss or confusion. Test Steps:
4. MetaMetrics Consent and Privacy ControlsRisk Level: HIGH Why This Matters: Significant analytics controller changes can regress privacy guarantees; user consent must be honored and preferences must persist. Test Steps:
Medium Risk Scenarios (6)1. Assets List Sorting and Control BarRisk Level: MEDIUM Why This Matters: Refactors to assets list and control bar can break ordering, persistence, or filtering, degrading discoverability and trust in balances. Test Steps:
2. Asset Inactive Badge and WarningsRisk Level: MEDIUM Why This Matters: New UI indicators for inactive assets must inform without blocking legitimate actions; incorrect badges erode user confidence. Test Steps:
3. DeFi List Empty State and Protocol CellsRisk Level: MEDIUM Why This Matters: UI changes to DeFi cells and empty states can cause broken rendering or confusing states, impacting portfolio usability. Test Steps:
4. Onboarding Variants (SRP, Create New, Hardware)Risk Level: MEDIUM Why This Matters: Onboarding method action type changes can break specific paths; ensuring each path completes avoids onboarding lockouts. Test Steps:
5. Portfolio/Total Balance AggregationRisk Level: MEDIUM Why This Matters: Controller changes around balance selection can cause incorrect totals or UI instability, leading to user mistrust of displayed balances. Test Steps:
6. Localization Sanity (Amharic/Arabic)Risk Level: MEDIUM Why This Matters: Recent locale string changes can surface missing or broken translations on key screens, degrading usability for non-English users. Test Steps:
Teams Sign-off StatusSigned off: None yet Awaiting sign-off (5): Generated by AI Test Plan Analyzer (gpt-5) at 2026-07-15T02:31:45.662Z AI generated test plan (JSON): test-plan-13.40.0.json |
…b Action cp-13.40.0 (#44469) - chore: New Crowdin Translations by GitHub Action cp-13.40.0 (#44329) Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com> [ccadeee](ccadeee) Co-authored-by: MetaMask Bot <37885440+metamaskbot@users.noreply.github.com> Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
Builds ready [1ae883a]
⚡ Performance Benchmarks (Total: 🟢 10 pass · 🟡 11 warn · 🔴 3 fail)
Bundle sizes
🍒 What's in this RCCherry-picks (172 commits)
Changelog (8 commits from main at RC cut)
AI Test Plan
Cherry-Pick Scenarios (4)High Risk Scenarios (2)1. Token Management – Non‑EVM Token Search/Import (Snaps)Risk Level: HIGH Why This Matters: Cherry-pick #44361 fixes seeding unified assets for non‑EVM search imports; without it, users can’t discover/import tokens on Snap-based networks, breaking basic asset management. Test Steps:
2. Activity – Duplicate Pending Transaction RowsRisk Level: HIGH Why This Matters: Cherry-pick #44370 fixes extra pending rows from local state; duplicates confuse users, obscure the real status, and can cause mistaken actions. Test Steps:
Medium Risk Scenarios (2)1. Networks – Add and Use Featured Robinhood ChainRisk Level: MEDIUM Why This Matters: Cherry-pick #44346 adds a new featured network; incorrect metadata or switching issues can lead to failed transactions or mispriced balances. Test Steps:
2. Portfolio – Aggregated Balance Stability (Tracer change)Risk Level: MEDIUM Why This Matters: Cherry-pick #44460 removes a trace parameter in balance aggregation; while aimed at telemetry, it touches hot paths that could alter performance or accuracy. Test Steps:
Release Scenarios (10)High Risk Scenarios (4)1. State Migration (Migration 216) – Upgrade SafetyRisk Level: HIGH Why This Matters: New migration (216) can corrupt or drop user data if it mishandles persisted state; validating upgrade integrity prevents data loss and broken sessions. Test Steps:
2. Seedless Onboarding – Migration and ResumeRisk Level: HIGH Why This Matters: Seedless onboarding migrations changed; mid-flow users are susceptible to dead-ends or corrupted onboarding state after upgrade. Test Steps:
3. Token Management – Asset List Control Bar and SortingRisk Level: HIGH Why This Matters: Large refactor to asset list/control bar/sort components risks broken sorting, persistence, and search behavior that directly affects discoverability of assets. Test Steps:
4. Portfolio – Aggregated Balance Accuracy and PerformanceRisk Level: HIGH Why This Matters: Changes around balance aggregation can cause misreported totals or performance regressions that erode trust in displayed balances. Test Steps:
Medium Risk Scenarios (6)1. Token Management – Inactive Asset BadgeRisk Level: MEDIUM Why This Matters: New badge introduces compliance/safety cues; incorrect labeling or missing action-guards can lead users to interact with deprecated or unsafe assets. Test Steps:
2. DeFi – Empty State and Protocol Cell DisplayRisk Level: MEDIUM Why This Matters: UI updates in DeFi cells/empty state can break discoverability and clarity of DeFi holdings, leading to confusion about portfolio composition. Test Steps:
3. Assets/Activity Views – List Virtualization and CountsRisk Level: MEDIUM Why This Matters: List component changes can introduce virtualization and state bugs (missing items, duplicates) that degrade trust and usability. Test Steps:
4. Analytics/MetaMetrics – Consent and SettingsRisk Level: MEDIUM Why This Matters: Large analytics controller changes risk breaking privacy toggles or introducing UX regressions in consent handling. Test Steps:
5. Network Switching – Asset List and Balance RefreshRisk Level: MEDIUM Why This Matters: Asset list and sorting changes must remain correct across network boundaries to avoid misattribution of balances and tokens. Test Steps:
6. Onboarding – Create vs Import Flow ReliabilityRisk Level: MEDIUM Why This Matters: Changes around onboarding action types and analytics must not interfere with the critical create/import paths. Test Steps:
Teams Sign-off StatusSigned off: None yet Awaiting sign-off (6): Generated by AI Test Plan Analyzer (gpt-5) at 2026-07-15T16:49:57.082Z AI generated test plan (JSON): test-plan-13.40.0.json |
Builds ready [22224a2]
⚡ Performance Benchmarks (Total: 🟢 19 pass · 🟡 2 warn · 🔴 3 fail)
Bundle sizes
🍒 What's in this RCCherry-picks (173 commits)
Changelog (8 commits from main at RC cut)
AI Test Plan
Cherry-Pick Scenarios (4)High Risk Scenarios (2)1. Token Management — Unified assets seeding for non-EVM search/importRisk Level: HIGH Why This Matters: Cherry-pick 44361 fixes non-EVM asset seeding in search/import; mistakes here create cross-network asset confusion or duplicate entries. Test Steps:
2. Activity Feed — Remove extra pending row from local stateRisk Level: HIGH Why This Matters: Cherry-pick 44370 fixes duplicate pending entries; duplicates degrade trust and make it hard to track real transaction states. Test Steps:
Medium Risk Scenarios (2)1. Network Management — Add Robinhood Chain as featured networkRisk Level: MEDIUM Why This Matters: Cherry-pick 44346 adds a new featured network; incorrect chain metadata or switching can strand users on a broken network. Test Steps:
2. Portfolio Balance Selector — Remove tracing from balance aggregationRisk Level: MEDIUM Why This Matters: Cherry-pick 44460 alters the balance aggregation call path; unintended side-effects can impact accuracy or performance of portfolio totals. Test Steps:
Release Scenarios (9)High Risk Scenarios (3)1. State Migrations (Migration 216 + seedless onboarding migrations)Risk Level: HIGH Why This Matters: New migrations can reshape stored data; regressions may cause data loss, broken unlocks, or inconsistent activity/history after upgrade. Test Steps:
2. Analytics/MetaMetrics opt-in/out and event gatingRisk Level: HIGH Why This Matters: Large refactors in analytics controllers/adapters can accidentally block flows, spam prompts, or ignore user consent. Test Steps:
3. Assets list sorting and filter control barRisk Level: HIGH Why This Matters: Significant UI updates to asset list and sort controls risk incorrect ordering, broken filtering, or lost user preferences. Test Steps:
Medium Risk Scenarios (6)1. Asset Inactive Badge and token detailsRisk Level: MEDIUM Why This Matters: New UI component introduces risk of mislabeling tokens or blocking legitimate actions, impacting user trust and safety. Test Steps:
2. DeFi list empty state and protocol cellsRisk Level: MEDIUM Why This Matters: UI copy/structure changes in DeFi lists can cause rendering or formatting regressions that confuse users or hide opportunities. Test Steps:
3. Portfolio total vs per-asset balances consistencyRisk Level: MEDIUM Why This Matters: Selector and controller changes around balances can produce incorrect or unstable totals, undermining portfolio accuracy. Test Steps:
4. Seedless onboarding state continuityRisk Level: MEDIUM Why This Matters: Changes in seedless onboarding migrations can break access or invalidate stored session/authorization data. Test Steps:
5. Activity feed during pending→confirmed transitionsRisk Level: MEDIUM Why This Matters: List and rendering updates can cause subtle duplication or stale rows during state transitions, confusing users reviewing history. Test Steps:
6. Network management sanity (switching and visibility)Risk Level: MEDIUM Why This Matters: Broad UI changes can unintentionally regress core network switching and visibility behaviors. Test Steps:
Teams Sign-off StatusSigned off: None yet Awaiting sign-off (3): Generated by AI Test Plan Analyzer (gpt-5) at 2026-07-16T06:35:35.154Z AI generated test plan (JSON): test-plan-13.40.0.json |
|
@metamaskbot update-attributions |
|
Attributions update failed. You can review the logs or retry the attributions update here |
|
@SocketSecurity ignore all |
|
@metamaskbot update-attributions |
|
Attributions update failed. You can review the logs or retry the attributions update here |
1 similar comment
|
Attributions update failed. You can review the logs or retry the attributions update here |
Builds ready [6d442d4]
⚡ Performance Benchmarks (Total: 🟢 17 pass · 🟡 5 warn · 🔴 2 fail)
Bundle sizes
🍒 What's in this RCCherry-picks (175 commits)
Changelog (8 commits from main at RC cut)
AI Test Plan
Cherry-Pick Scenarios (4)High Risk Scenarios (1)1. Token Management — Non-EVM token search/import (unified assets)Risk Level: HIGH Why This Matters: Cherry-pick 44361 fixes unified asset seeding for non-EVM search imports; a regression would break token discovery or show wrong metadata for non-EVM ecosystems. Test Steps:
Medium Risk Scenarios (3)1. Networks — Add Robinhood Chain as a featured networkRisk Level: MEDIUM Why This Matters: Cherry-pick 44346 adds a new featured network; misconfiguration (RPC, chain ID, currency) can prevent connections or cause users to transact on the wrong chain. Test Steps:
2. Activity — Duplicate pending transaction rowsRisk Level: MEDIUM Why This Matters: Cherry-pick 44370 fixes an extra pending row from local state; duplicates confuse users and can lead to incorrect follow-up actions. Test Steps:
3. Security/UX — Scam questionnaire gated by LaunchDarkly flagRisk Level: MEDIUM Why This Matters: Cherry-pick 44582 gates the scam questionnaire behind a flag; incorrect gating could hide necessary education or inappropriately block critical flows. Test Steps:
Release Scenarios (7)High Risk Scenarios (3)1. State Migrations (Migration 216 + seedless onboarding data)Risk Level: HIGH Why This Matters: Migrations can corrupt user state (accounts, networks, tokens) or cause load failures; verifying upgrade integrity prevents data loss and broken post-upgrade flows. Test Steps:
2. Onboarding (Seedless/Passkey) flow and resumeRisk Level: HIGH Why This Matters: New or migrated seedless onboarding state can get stuck or reset, blocking new users from completing setup or producing unusable accounts. Test Steps:
3. Analytics/MetaMetrics consent and event collection (controller refactor)Risk Level: HIGH Why This Matters: A refactor to analytics controllers/adapters risks silent failures, duplicate events, or privacy regressions that affect user trust and app stability. Test Steps:
Medium Risk Scenarios (4)1. Token Management — Asset list sorting and searchRisk Level: MEDIUM Why This Matters: Large UI changes to the asset list, control bar, and sort control can break discoverability, ordering, or persistence of user preferences. Test Steps:
2. Token Management — Inactive token badge and actionsRisk Level: MEDIUM Why This Matters: A new inactive-asset badge surfaces risk to users; regressions could hide warnings or incorrectly block legitimate actions. Test Steps:
3. DeFi portfolio list — empty state and protocol cellsRisk Level: MEDIUM Why This Matters: UI changes to DeFi list cells and empty states can break navigation or misrepresent balances, confusing users about their positions. Test Steps:
4. Network switching consistency with asset listRisk Level: MEDIUM Why This Matters: Wide UI and controller churn can cause cross-network state leakage or stale lists, leading to wrong balances or actions on the wrong chain. Test Steps:
Teams Sign-off StatusSigned off: None yet Awaiting sign-off (5): Generated by AI Test Plan Analyzer (gpt-5) at 2026-07-16T20:30:40.898Z AI generated test plan (JSON): test-plan-13.40.0.json |
🚀 v13.40.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
Conduct regression and exploratory testing for your functional areas, including automated and manual tests for critical workflows.
Focus on exploratory testing across the wallet, prioritize high-impact areas, and triage any Sentry errors found during testing.
Validate new functionalities and provide feedback to support release monitoring.
GitHub Signoff
Issue Resolution
Cherry-Picking Criteria
🗓️ Timeline and Milestones
✅ Signoff Checklist
Each team is responsible for signing off via GitHub. Use the checkbox below to track signoff completion:
Team sign-off checklist
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