refactor(analytics): migrate UI and background off legacy metrics state#43406
refactor(analytics): migrate UI and background off legacy metrics state#43406gauthierpetetin wants to merge 4 commits into
Conversation
Replace participateInMetaMetrics and metaMetricsId with analyticsId, optedIn, and completedMetaMetricsOnboarding across selectors, UI, background scripts, Sentry, and tests. Remove getState() legacy projection while preserving tri-state consent behavior. Co-authored-by: Cursor <cursoragent@cursor.com>
✨ Files requiring CODEOWNER review ✨🔑 @MetaMask/accounts-engineers (5 files, +15 -11)
👨🔧 @MetaMask/core-extension-ux (13 files, +111 -60)
🫰 @MetaMask/core-platform (3 files, +35 -28)
👨🔧 @MetaMask/extension-platform (2 files, +4 -2)
🕵️ @MetaMask/extension-privacy-reviewers (1 files, +2 -4)
💎 @MetaMask/metamask-assets (1 files, +11 -6)
🧪 @MetaMask/qa (6 files, +76 -84)
📈 @MetaMask/ramp (1 files, +12 -7)
🔄 @MetaMask/swaps-engineers (2 files, +9 -8)
🔐 @MetaMask/web3auth (11 files, +56 -56)
|
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
Regenerate data-deletion-service action types after analyticsId rename and correct state-logs.json to drop eventQueue and keep profile metaMetricsId for the unchanged UserProfile contract. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Pull request overview
This PR completes Analytics Refactor Phase B by removing the legacy participateInMetaMetrics / metaMetricsId UI-state projection and migrating UI/background consumers to use analyticsId, optedIn, and completedMetaMetricsOnboarding sourced from the AnalyticsController and MetaMetricsController.
Changes:
- Replaced legacy MetaMetrics selectors/consumers with
getAnalyticsId,getOptedIn, andgetCompletedMetaMetricsOnboarding(and corresponding boolean gating). - Updated Sentry gating/helpers and background/service wiring to use the new analytics fields.
- Updated tests/fixtures/snapshots/E2E flows to use
analyticsId+ onboarding/opt-in flags.
Reviewed changes
Copilot reviewed 133 out of 135 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| ui/selectors/selectors.js | Rename selector to getAnalyticsId and read analyticsId from state. |
| ui/selectors/metametrics.test.ts | Update selector tests to cover optedIn, completedMetaMetricsOnboarding, analyticsId. |
| ui/selectors/metametrics.js | Replace legacy tri-state selector with explicit getOptedIn + getCompletedMetaMetricsOnboarding. |
| ui/pages/unlock-page/unlock-page.stories.tsx | Update story state to new analytics consent fields. |
| ui/pages/settings/privacy-tab/metametrics-item.tsx | Use getOptedIn and update tracking props accordingly. |
| ui/pages/settings/privacy-tab/delete-metametrics-data-item.tsx | Gate delete button enablement using completed+optedIn+analyticsId. |
| ui/pages/settings/privacy-tab/delete-metametrics-data-item.test.tsx | Update selector mocks/tests for new consent/id sources. |
| ui/pages/settings/privacy-tab/data-collection-item.tsx | Disable marketing toggle unless completed onboarding and opted in. |
| ui/pages/onboarding-flow/welcome/welcome.tsx | Use getCompletedMetaMetricsOnboarding for routing decisions. |
| ui/pages/onboarding-flow/welcome/welcome.test.tsx | Update mocked state to use analyticsId. |
| ui/pages/onboarding-flow/setup-passkey/setup-passkey.tsx | Use getCompletedMetaMetricsOnboarding for next-route logic. |
| ui/pages/onboarding-flow/onboarding-flow-switch/onboarding-flow-switch.tsx | Use getCompletedMetaMetricsOnboarding for onboarding routing. |
| ui/pages/onboarding-flow/metametrics/metametrics.tsx | Replace legacy selectors with completed+optedIn gating. |
| ui/pages/onboarding-flow/metametrics/metametrics.test.tsx | Update onboarding metametrics test state to new fields. |
| ui/pages/onboarding-flow/download-app/download-app.test.tsx | Update typed overrides/fixtures to new analytics fields. |
| ui/pages/onboarding-flow/creation-successful/creation-successful.tsx | Use getOptedIn when selecting opt-in/out event name. |
| ui/pages/onboarding-flow/create-password/create-password.tsx | Inject iframe based on completed+optedIn+analyticsId; rename base64 var. |
| ui/pages/onboarding-flow/create-password/create-password.test.tsx | Update tests to new consent fields. |
| ui/pages/home/home.container.js | Map state prop to isMetaMetricsEnabled via completed+optedIn. |
| ui/pages/home/home.component.test.tsx | Update prop name to isMetaMetricsEnabled. |
| ui/pages/home/home.component.stories.tsx | Update story prop name to isMetaMetricsEnabled. |
| ui/pages/home/home.component.js | Rename prop and use it for onboarding popover gating. |
| ui/pages/error-page/error-page.component.tsx | Gate Sentry feedback UI behind completed+optedIn. |
| ui/pages/error-page/error-component.test.tsx | Update selector mocks for completed+optedIn. |
| ui/pages/batch-sell/pages/select/components/batch-sell-empty-select-tokens.tsx | Use analyticsId and completed+optedIn gating for portfolio URL params. |
| ui/pages/batch-sell/pages/select/components/batch-sell-empty-select-tokens.test.tsx | Update selector mocks and assertions for new selector order/args. |
| ui/pages/asset/components/asset-page.tsx | Use analyticsId and completed+optedIn gating for portfolio URL params. |
| ui/hooks/useMetametrics.test.tsx | Update hook tests to new consent fields. |
| ui/hooks/subscription/useSubscription.ts | Append support URL param using analyticsId from selector. |
| ui/hooks/ramps/useRamps/useRamps.ts | Use analyticsId and completed+optedIn gating for ramp params. |
| ui/hooks/bridge/useBridging.test.ts | Update test fixtures to set analyticsId. |
| ui/helpers/utils/portfolio.js | Rename helper arg to analyticsId while preserving query param name. |
| ui/ducks/metamask/metamask.js | Replace legacy state fields with analyticsId, optedIn, completedMetaMetricsOnboarding. |
| ui/contexts/metametrics.tsx | Use analyticsId and completed+optedIn gating for buffering vs immediate tracking. |
| ui/components/ui/survey-toast/survey-toast.tsx | Use analyticsId and completed+optedIn gating for survey fetch/tracking. |
| ui/components/multichain/token-list-item/stakeable-link.tsx | Use analyticsId and completed+optedIn gating in portfolio URL. |
| ui/components/multichain/menu-items/discover-menu-item.tsx | Use analyticsId and completed+optedIn gating in portfolio URL. |
| ui/components/multichain/menu-items/discover-menu-item.stories.tsx | Update store mock to analyticsId + consent flags. |
| ui/components/multichain/global-menu-drawer/useGlobalMenuSections.tsx | Use analyticsId and completed+optedIn gating in portfolio URL. |
| ui/components/multichain/funding-method-modal/funding-method-modal.tsx | Use analyticsId and completed+optedIn gating in portfolio URL. |
| ui/components/app/wallet-overview/non-evm-overview.test.tsx | Update mocked state key to analyticsId. |
| ui/components/app/wallet-overview/coin-overview.tsx | Use analyticsId and completed+optedIn gating in portfolio URL. |
| ui/components/app/modals/visit-support-data-consent-modal/visit-support-data.test.tsx | Update selector and expectations to getAnalyticsId. |
| ui/components/app/modals/visit-support-data-consent-modal/visit-support-data-consent-modal.tsx | Rename callback param and selector to analyticsId. |
| ui/components/app/modals/pna25-modal/pna25-modal.stories.tsx | Update story state to analytics consent fields. |
| ui/components/app/modals/identity/turn-on-backup-and-sync-modal/turn-on-backup-and-sync-modal.test.tsx | Update mocked state to new consent fields. |
| ui/components/app/metametrics-toggle/metametrics-toggle.tsx | Switch toggle source to getOptedIn. |
| ui/components/app/identity/backup-and-sync-toggle/backup-and-sync-toggle.test.tsx | Update mocked state to new consent fields. |
| ui/components/app/identity/backup-and-sync-features-toggles/backup-and-sync-features-toggles.test.tsx | Update mocked state to new consent fields. |
| ui/components/app/delete-metametrics-data-button/delete-metametrics-data-button.tsx | Use analyticsId and completed+optedIn gating; update messaging/id checks. |
| ui/components/app/delete-metametrics-data-button/delete-metametrics-data-button.test.tsx | Update selector mocks to new consent/id selectors. |
| ui/components/app/assets/defi-list/cells/defi-empty-state.tsx | Use analyticsId and completed+optedIn gating in portfolio URL. |
| test/e2e/tests/vault-corruption/vault-corruption.spec.ts | Update fixtures to set completed+optedIn. |
| test/e2e/tests/survey/survey.spec.ts | Rename constant and fixture fields to analyticsId + consent flags. |
| test/e2e/tests/settings/state-logs.json | Update expected state shape for analyticsId/optedIn and remove legacy fields. |
| test/e2e/tests/remote-feature-flag/remote-feature-flag.spec.ts | Rename constant and fixture fields to analyticsId + consent flags. |
| test/e2e/tests/profile-metrics/profile-metrics.spec.ts | Update fixtures/table-driven cases to completed+optedIn. |
| test/e2e/tests/ppom/ppom-blockaid-toggle-metrics.spec.ts | Rename constant and expected Segment payload userId to analytics ID. |
| test/e2e/tests/ppom/ppom-blockaid-alert-metrics.spec.js | Rename constant and expected Segment payload userId to analytics ID. |
| test/e2e/tests/portfolio/portfolio-site.spec.ts | Rename constant and expected portfolio URL query metametricsId value. |
| test/e2e/tests/port-stream-chunking/port-stream-chunking.spec.ts | Rename constant and fixture fields to analyticsId + consent flags. |
| test/e2e/tests/onboarding/onboarding.spec.ts | Update fixtures to set completed+optedIn+analyticsId null. |
| test/e2e/tests/metrics/wallet-imported.spec.ts | Update onboarding flow options to completed+optedIn. |
| test/e2e/tests/metrics/wallet-created.spec.ts | Rename constant and update onboarding flow options/fixtures. |
| test/e2e/tests/metrics/unlock-wallet.spec.ts | Rename constant and update fixture fields to analyticsId + consent flags. |
| test/e2e/tests/metrics/transaction-finalized.spec.ts | Rename constant and update fixture fields to analyticsId + consent flags. |
| test/e2e/tests/metrics/traces.spec.ts | Update fixtures to completed+optedIn variants. |
| test/e2e/tests/metrics/token-detection-metrics.spec.ts | Rename constant and update onboarding flow options/fixtures. |
| test/e2e/tests/metrics/swaps.spec.js | Rename constant and update fixture fields to analyticsId + consent flags. |
| test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json | Remove legacy fields from snapshot. |
| test/e2e/tests/metrics/signature-approved.spec.ts | Rename constant and update fixture fields to analyticsId + consent flags. |
| test/e2e/tests/metrics/sessions.spec.ts | Update fixtures to completed+optedIn variants. |
| test/e2e/tests/metrics/segment-user-traits.spec.ts | Rename constant and update onboarding flow options/fixtures. |
| test/e2e/tests/metrics/permissions-approved.spec.ts | Rename constant and update fixture fields to analyticsId + consent flags. |
| test/e2e/tests/metrics/nft-detection-metrics.spec.ts | Rename constant and update onboarding flow options/fixtures. |
| test/e2e/tests/metrics/metrics-opt-in-out.spec.ts | Rename constant and update fixture controller state. |
| test/e2e/tests/metrics/metametrics-persistence.spec.ts | Rename constant and assert persistence via analyticsId. |
| test/e2e/tests/metrics/marketing-cookieid.spec.ts | Rename constant and update fixture fields to analyticsId + consent flags. |
| test/e2e/tests/metrics/errors.spec.ts | Rename constant and update fixture fields to analyticsId + consent flags. |
| test/e2e/tests/metrics/error-page.spec.ts | Rename constant and update fixture fields to analyticsId + consent flags. |
| test/e2e/tests/metrics/developer-options-sentry.spec.ts | Rename constant and update fixture fields to analyticsId + consent flags. |
| test/e2e/tests/metrics/delete-metametrics-data.spec.ts | Rename constant and update expected deletion payload subjectIds. |
| test/e2e/tests/metrics/dapp-viewed.spec.ts | Update fixtures to use analyticsId for sampling. |
| test/e2e/tests/metrics/app-opened.spec.ts | Rename constant and update fixture fields to analyticsId + consent flags. |
| test/e2e/tests/metrics/app-installed.spec.ts | Rename constant and update fixture fields to analyticsId + consent flags. |
| test/e2e/tests/confirmations/transactions/metrics.spec.ts | Rename constant and update fixture fields to analyticsId + consent flags. |
| test/e2e/tests/confirmations/navigation.spec.ts | Rename constant and update fixture fields to analyticsId + consent flags. |
| test/e2e/tests/confirmations/helpers.ts | Rename constant and update shared fixtures to analyticsId + consent flags. |
| test/e2e/tests/bridge/bridge-test-utils.ts | Rename constant and update bridge fixtures to analyticsId + consent flags. |
| test/e2e/tests/account/unlock-wallet.spec.ts | Update onboarding metrics flow options to completed+optedIn. |
| test/e2e/snaps/test-snap-metrics.spec.ts | Rename constant and update fixture fields to analyticsId + consent flags. |
| test/e2e/snaps/test-snap-installed.spec.ts | Update fixture fields to analyticsId + consent flags. |
| test/e2e/page-objects/pages/settings/privacy-settings.ts | Rename page object selector field to optedInToggle. |
| test/e2e/page-objects/flows/vault-corruption.flow.ts | Update flow options type and param naming to optedIn. |
| test/e2e/page-objects/flows/onboarding.flow.ts | Introduce OnboardingMetricsFlowOptions and migrate flows to optedIn/completed fields. |
| test/e2e/flask/snaps/preinstalled-example.spec.ts | Rename constant and update fixture fields to analyticsId + consent flags. |
| test/e2e/fixtures/fixture-builder-v2.ts | Update fixture patching so withMetaMetricsController can patch AnalyticsController analyticsId/optedIn. |
| test/e2e/dist/wallet-fixture-validation.spec.ts | Update onboarding flow options to completed+optedIn. |
| test/e2e/dist/wallet-fixture-export.spec.ts | Update onboarding flow options to completed+optedIn. |
| test/e2e/constants.ts | Rename MOCK_META_METRICS_ID to MOCK_ANALYTICS_ID. |
| test/e2e/benchmarks/flows/user-journey/onboarding-new-wallet.ts | Update onboarding flow options to completed+optedIn. |
| test/e2e/benchmarks/flows/user-journey/onboarding-import-wallet.ts | Update onboarding flow options to completed+optedIn. |
| app/scripts/services/oauth/types.ts | Update OAuth service options to separate completed vs optedIn getters. |
| app/scripts/services/oauth/oauth-service.ts | Gate tracking on completed+optedIn instead of tri-state getter. |
| app/scripts/services/oauth/oauth-service.test.ts | Update OAuth service tests to new getters. |
| app/scripts/services/data-deletion-service.ts | Rename param to analyticsId for deletion subject IDs. |
| app/scripts/services/data-deletion-service.test.ts | Rename test vars and update calls accordingly. |
| app/scripts/services/data-deletion-service-method-action-types.ts | Update JSDoc param name to analyticsId. |
| app/scripts/messenger-client-init/seedless-onboarding/oauth-service-init.ts | Provide separate completed/optedIn getters to OAuth service. |
| app/scripts/messenger-client-init/seedless-onboarding/oauth-service-init.test.ts | Update test mock state for new consent fields. |
| app/scripts/messenger-client-init/remote-feature-flag-controller-init.ts | Get MetaMetrics ID via AnalyticsController state. |
| app/scripts/messenger-client-init/profile-metrics-controller-init.ts | Resolve MetaMetrics ID from AnalyticsController state. |
| app/scripts/messenger-client-init/network-controller-init.ts | Provide analyticsId to network RPC metrics helpers via AnalyticsController state. |
| app/scripts/messenger-client-init/messengers/remote-feature-flag-controller-messenger.ts | Delegate AnalyticsController:getState instead of legacy MetaMetrics action. |
| app/scripts/messenger-client-init/messengers/network-controller-messenger.ts | Delegate AnalyticsController:getState instead of legacy MetaMetrics action. |
| app/scripts/messenger-client-init/messengers/identity/authentication-controller-messenger.ts | Delegate AnalyticsController:getState instead of legacy MetaMetrics action. |
| app/scripts/messenger-client-init/identity/authentication-controller-init.ts | Implement getMetaMetricsId by reading AnalyticsController state. |
| app/scripts/lib/util.ts | Rename sampling helper param/docs to analyticsId. |
| app/scripts/lib/setupSentry.js | Switch Sentry gating/state resolution to analytics fields. |
| app/scripts/lib/sentry-metametrics.ts | Update Sentry integration to use analytics state and attach user.id from analyticsId. |
| app/scripts/lib/sentry-metametrics.test.ts | Update tests for new Sentry integration inputs/behavior. |
| app/scripts/lib/sentry-make-transport.ts | Gate transport network calls on completed+optedIn. |
| app/scripts/lib/sentry-get-state.ts | Replace legacy participation shape with explicit analytics state fields. |
| app/scripts/lib/sentry-get-state.test.ts | Update tests to new analytics state resolution behavior. |
| app/scripts/lib/network-controller/utils.ts | Sample RPC service metrics using analyticsId. |
| app/scripts/lib/network-controller/utils.test.ts | Update tests to use analyticsId. |
| app/scripts/lib/network-controller/messenger-action-handlers.ts | Rename params to analyticsId and pass through sampling logic. |
| app/scripts/lib/network-controller/messenger-action-handlers.test.ts | Update tests for renamed param and sampling calls. |
| app/scripts/fixtures/with-preferences.js | Update preferences fixture to completed+optedIn fields. |
| app/scripts/controllers/metametrics-data-deletion/metametrics-data-deletion.test.ts | Update tests to read analyticsId from AnalyticsController. |
| app/scripts/controllers/metametrics-controller.ts | Remove legacy derived UI fields, add analytics fields to MetaMaskState, update traits/uninstall URL handling. |
| app/scripts/controllers/metametrics-controller.test.ts | Update tests to provide analyticsId + consent fields in state. |
| app/scripts/background.js | Update metrics gating and dapp-view sampling to use analyticsId + consent fields. |
| .storybook/test-data.js | Update Storybook state fixture to new analytics consent fields. |
Comments suppressed due to low confidence (1)
ui/components/app/delete-metametrics-data-button/delete-metametrics-data-button.tsx:124
- The description switches to
deleteMetaMetricsDataRequestedDescriptionwhenever the button is disabled and an analytics ID exists. This will also be true when the user is simply opted out (or hasn’t opted in yet) but still has an analytics ID, which can show a misleading “requested” message (often with a 1970 date when the timestamp is 0). The “requested” copy should be tied to an actual deletion status/timestamp condition, not justdisabled && analyticsId.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Fix optedIn indentation in storybook test data and update RPC sampling docs to refer to Analytics instead of MetaMetrics. Co-authored-by: Cursor <cursoragent@cursor.com>
Builds ready [f15632d]
⚡ Performance Benchmarks (Total: 🟢 17 pass · 🟡 7 warn · 🔴 0 fail)
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
Builds ready [7d51dab]
⚡ Performance Benchmarks (Total: 🟢 17 pass · 🟡 8 warn · 🔴 0 fail)
Bundle size diffs
|
MetaMask#43430) ## **Description** Part 1 of the Analytics Phase B split (supersedes monolithic MetaMask#43406). **Reason:** Phase B migrates off legacy `participateInMetaMetrics` / `metaMetricsId` toward canonical `analyticsId`, `optedIn`, and `completedMetaMetricsOnboarding`. **Solution:** This PR lands the shared foundation: Redux initial state, selectors, metrics context, background/Sentry/controller wiring, and messenger/service inits. It also adds temporary backward-compat shims so domain PRs can merge in parallel. **Shim contract (removed in MetaMask#43442):** | Legacy | Replacement | Shim behavior | |--------|-------------|---------------| | `getParticipateInMetaMetrics` | `completed && optedIn` | deprecated alias | | `getIsParticipateInMetaMetricsSet` | `getCompletedMetaMetricsOnboarding` | alias | | `getMetaMetricsId` | `getAnalyticsId` | alias | | `state.metamask.metaMetricsId` | `state.metamask.analyticsId` | projected in `getState()` | | `state.metamask.participateInMetaMetrics` | derived from canonical fields | projected in `getState()` | **Merge order:** Must merge before consumer PRs (MetaMask#43431–MetaMask#43441). ## **Changelog** CHANGELOG entry: null ## **Related issues** Part of MetaMask/MetaMask-planning#7331 ## **Manual testing steps** 1. Run `yarn start` and load the extension 2. Complete onboarding metrics opt-in and opt-out flows 3. Toggle metrics in Settings → Privacy 4. Confirm the extension loads without background selector errors <!-- ## **Screenshots/Recordings** ### **Before** ### **After** --> ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes how analytics consent and user ID are read everywhere events, Sentry, OAuth buffering, and sampling run; behavior should match the old model but the split onboarding/opt-in gates add regression surface across privacy flows. > > **Overview** > **Phase B foundation** for analytics: the extension stops treating `participateInMetaMetrics` and `metaMetricsId` as the source of truth and wires **`analyticsId`**, **`optedIn`**, and **`completedMetaMetricsOnboarding`** through Redux, background, controllers, and Sentry. > > The UI Redux slice and selectors now expose the canonical fields (`getOptedIn`, `getCompletedMetaMetricsOnboarding`, `getAnalyticsId`), with **deprecated aliases** for `getParticipateInMetaMetrics`, `getIsParticipateInMetaMetricsSet`, and `getMetaMetricsId`. `MetaMetricsProvider` gates buffering and immediate tracking on **onboarding complete + opt-in + analytics ID** instead of the old combined flag. > > Background and services apply the same split: `AppOpened` / `AppInstalled` / dapp-viewed sampling, cookie handler setup, OAuth event buffering, uninstall URL encoding, data-deletion Segment calls, and RPC degraded/unavailable sampling all read **`analyticsId`** and require **`completedMetaMetricsOnboarding && optedIn`** where metrics used to check `participateInMetaMetrics`. Messenger inits fetch the ID via **`AnalyticsController:getState`** rather than `MetaMetricsController:getMetaMetricsId`. > > Sentry helpers are renamed and reshaped (`getAnalyticsState`, `AnalyticsParticipation`) so transport, breadcrumbs, and the MetaMetrics integration drop or send events based on the two consent booleans and attach `user.id` from `analyticsId`. `getState()` in the main controller still **projects** legacy `participateInMetaMetrics` / `metaMetricsId` for parallel consumer PRs. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 7311dbb. 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>
…Mask#43467) ## **Description** Part 2 of the Analytics Phase B split (supersedes monolithic MetaMask#43406). After foundation ([MetaMask#43430](MetaMask#43430)) merged, child analytics PRs failed `yarn lint:tsc` because migrated E2E tests used canonical fields (`analyticsId`, `optedIn`, `MOCK_ANALYTICS_ID`) while unmigrated tests still used legacy fields (`metaMetricsId`, `participateInMetaMetrics`, `MOCK_META_METRICS_ID`). This PR adds transitional dual-support in E2E fixtures and flow helpers so domain PRs ([MetaMask#43431](https://github.com/MetaMask/metamask-extension/pull/43431)–[#43441](https://github.com/MetaMask/metamask-extension/pull/43441)) can merge in parallel. Cleanup ([MetaMask#43442](MetaMask#43442)) removes this shim last. **Changes:** - `test/e2e/constants.ts` — `MOCK_ANALYTICS_ID` plus deprecated `MOCK_META_METRICS_ID` alias - `test/e2e/fixtures/fixture-builder-v2.ts` — `withMetaMetricsController` accepts legacy and canonical patch fields - `test/e2e/page-objects/flows/onboarding.flow.ts` — `OnboardingMetricsFlowOptions` with `resolveOptedIn()` - `test/e2e/page-objects/flows/vault-corruption.flow.ts` — accepts canonical onboarding metrics options ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: MetaMask/MetaMask-planning#7331 (partial) ## **Manual testing steps** 1. None, E2E tests shall pass as before <!-- ## **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** > Test-only helpers and constants; no production wallet or analytics runtime behavior changes. > > **Overview** > Adds a **transitional dual-support layer** in E2E so analytics migration PRs can land in parallel without `yarn lint:tsc` failures from mixed legacy and canonical naming. > > **Constants:** Introduces `MOCK_ANALYTICS_ID` and keeps `MOCK_META_METRICS_ID` as a deprecated alias to the same value. > > **Fixtures:** `withMetaMetricsController` now accepts both legacy (`metaMetricsId`, `participateInMetaMetrics`) and canonical (`analyticsId`, `optedIn`) patches, resolves them with canonical taking precedence for IDs, and writes `AnalyticsController` state (`analyticsId`, `optedIn`) while still merging real `MetaMetricsController` fields. > > **Onboarding flows:** New `OnboardingMetricsFlowOptions` and `resolveOptedIn()` unify opt-in behavior; flows accept `optedIn` alongside deprecated `participateInMetaMetrics`. Post-metrics wait accepts either `analyticsId` or `metaMetricsId` in app state. > > **Vault corruption:** `onboardThenExecuteScript` / `onboardThenTriggerCorruptionFlow` use the shared metrics options type and forward `optedIn`. > > Intended to be removed by a follow-up cleanup PR once all E2E tests use canonical fields. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 1f05308. 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** Part 9 of the Analytics Phase B split (supersedes monolithic MetaMask#43406). **Owner:** @MetaMask/core-platform **Reason:** Snaps E2E specs still use legacy metrics fixture fields. **Solution:** Update snaps E2E specs for canonical analytics fixture fields. **Depends on:** MetaMask#43430 ## **Changelog** CHANGELOG entry: null ## **Related issues** Part of MetaMask/MetaMask-planning#7331 ## **Manual testing steps** 1. Run `yarn build:test` 2. Run snaps E2E specs affected by this change <!-- ## **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.
## **Description** Part 4 of the Analytics Phase B split (supersedes monolithic MetaMask#43406). **Owner:** @MetaMask/core-extension-ux **Reason:** Core UX surfaces still depend on legacy metrics selectors. **Solution:** Migrate home, privacy settings, multichain discover, delete-metametrics, metametrics-toggle, and visit-support modal to canonical analytics selectors. **Tri-state rule:** Where old code used `getParticipateInMetaMetrics` for "metrics enabled", use `getCompletedMetaMetricsOnboarding(state) && getOptedIn(state)`. **Depends on:** MetaMask#43430 ## **Changelog** CHANGELOG entry: null ## **Related issues** Part of MetaMask/MetaMask-planning#7331 ## **Manual testing steps** 1. Run `yarn start` and toggle metrics in Settings → Privacy 2. Verify home and discover links respect metrics state 3. Test delete MetaMetrics data flow from privacy settings <!-- ## **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. Co-authored-by: Cursor <cursoragent@cursor.com>
…aMask#43433) ## **Description** Part 5 of the Analytics Phase B split (supersedes monolithic MetaMask#43406). **Owner:** @MetaMask/accounts-engineers **Reason:** Accounts identity init and backup-and-sync tests still reference legacy metrics fields. **Solution:** Migrate authentication controller init/messenger and backup-and-sync tests to canonical analytics selectors. **Depends on:** MetaMask#43430 ## **Changelog** CHANGELOG entry: null ## **Related issues** Part of MetaMask/MetaMask-planning#7331 ## **Manual testing steps** 1. Run unit tests for backup-and-sync components 2. Verify backup and sync toggle flows still work after building with `yarn start` <!-- ## **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. --------- Co-authored-by: Cursor <cursoragent@cursor.com>
…etaMask#43431) ## **Description** Part 3 of the Analytics Phase B split (supersedes monolithic MetaMask#43406). **Owner:** @MetaMask/web3auth **Reason:** Onboarding and subscription flows still read legacy metrics selectors. **Solution:** Migrate onboarding-flow pages/tests, `useSubscription.ts`, and onboarding E2E to `getOptedIn`, `getCompletedMetaMetricsOnboarding`, and `getAnalyticsId`. **Depends on:** MetaMask#43430 ## **Changelog** CHANGELOG entry: null ## **Related issues** Part of MetaMask/MetaMask-planning#7331 ## **Manual testing steps** 1. Run `yarn start` and complete create-wallet and import-wallet onboarding flows 2. Verify metrics opt-in and opt-out during onboarding 3. Run `yarn build:test` then `yarn test:e2e:single test/e2e/tests/onboarding/onboarding.spec.ts --browser=chrome` <!-- ## **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.
## **Description** Part 7 of the Analytics Phase B split (supersedes monolithic MetaMask#43406). **Owner:** @MetaMask/ramp **Reason:** Ramp portfolio URL builder still reads legacy metrics selectors. **Solution:** Update `useRamps.ts` to use canonical analytics selectors. **Depends on:** MetaMask#43430 ## **Changelog** CHANGELOG entry: null ## **Related issues** Part of MetaMask/MetaMask-planning#7331 ## **Manual testing steps** 1. Run `yarn start` and verify ramp/buy flows build portfolio URLs with correct metrics params <!-- ## **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.
…k#43437) ## **Description** Part 8 of the Analytics Phase B split (supersedes monolithic MetaMask#43406). **Owner:** @MetaMask/metamask-assets **Reason:** Defi empty state still uses legacy metrics selectors. **Solution:** Update `defi-empty-state.tsx` to use canonical analytics selectors. **Depends on:** MetaMask#43430 ## **Changelog** CHANGELOG entry: null ## **Related issues** Part of MetaMask/MetaMask-planning#7331 ## **Manual testing steps** 1. Run `yarn start` and verify defi empty state renders and links work with metrics enabled and disabled <!-- ## **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.
## **Description** Part 7 of the Analytics Phase B split (supersedes monolithic #43406). **Owner:** @MetaMask/ramp **Reason:** Ramp portfolio URL builder still reads legacy metrics selectors. **Solution:** Update `useRamps.ts` to use canonical analytics selectors. **Depends on:** #43430 ## **Changelog** CHANGELOG entry: null ## **Related issues** Part of MetaMask/MetaMask-planning#7331 ## **Manual testing steps** 1. Run `yarn start` and verify ramp/buy flows build portfolio URLs with correct metrics params <!-- ## **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.
## **Description** Part 8 of the Analytics Phase B split (supersedes monolithic #43406). **Owner:** @MetaMask/metamask-assets **Reason:** Defi empty state still uses legacy metrics selectors. **Solution:** Update `defi-empty-state.tsx` to use canonical analytics selectors. **Depends on:** #43430 ## **Changelog** CHANGELOG entry: null ## **Related issues** Part of MetaMask/MetaMask-planning#7331 ## **Manual testing steps** 1. Run `yarn start` and verify defi empty state renders and links work with metrics enabled and disabled <!-- ## **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.
Description
14-part Analytics Phase B split umbrella (this monolithic PR #43406 must not be merged as-is).
This PR is superseded by a split series. Do not merge as-is. It remains open as an umbrella tracker only.
This change completes Analytics Refactor Phase B by removing the legacy
participateInMetaMetrics/metaMetricsIdprojection from UI state and migrating consumers toanalyticsId,optedIn, andcompletedMetaMetricsOnboardingfromAnalyticsControllerandMetaMetricsController. Selectors, background services, Sentry helpers, Redux initial state, E2E fixtures, and snapshots were updated so tri-state metrics consent behavior stays the same while the codebase reads analytics fields from their canonical sources.Split strategy: Parallel domain PRs with backward-compat shims in production code (foundation) and E2E fixtures (transitional shim). A final cleanup PR removes shims after all consumers land on
main.Changelog
CHANGELOG entry: null
Related issues
Fixes: https://github.com/MetaMask/MetaMask-planning/issues/7331 (when PR 13 merges)
Manual testing steps
yarn start --sentryand load it in Chrome.metametricsId,metricsEnabled).completedMetaMetricsOnboarding && optedIn(watch Networks tab in the UI inspector).Screenshots/Recordings
N/A - No user-visible UI changes. Internal state and selector migration only.
Pre-merge author checklist
Pre-merge reviewer checklist
Child PR checklist
refactor/analytics-phase-b-foundationmainrefactor/analytics-phase-b-e2e-fixture-shimmainrefactor/analytics-phase-b-web3authmainrefactor/analytics-phase-b-core-uxmainrefactor/analytics-phase-b-accountsmainrefactor/analytics-phase-b-swaps-bridgemainrefactor/analytics-phase-b-rampmainrefactor/analytics-phase-b-assetsmainrefactor/analytics-phase-b-snapsmainrefactor/analytics-phase-b-qa-inframainrefactor/analytics-phase-b-metrics-e2erefactor/analytics-phase-b-qa-infrarefactor/analytics-phase-b-confirmationsmainrefactor/analytics-phase-b-platform-miscmainrefactor/analytics-phase-b-cleanupmainProgress
Merge order
Part 1✅ Merged (#43430)Part 2✅ Merged (#43467)main)refactor/analytics-phase-b-qa-infra, retarget tomainafter PR 9 merges)mainShim contracts (temporary)
Production shim (from #43430, removed in #43442):
getParticipateInMetaMetricscompleted && optedIngetIsParticipateInMetaMetricsSetgetCompletedMetaMetricsOnboardinggetMetaMetricsIdgetAnalyticsIdstate.metamask.metaMetricsIdstate.metamask.analyticsIdgetState()state.metamask.participateInMetaMetricsgetState()E2E fixture shim (from #43467, removed in #43442):
MOCK_META_METRICS_IDMOCK_ANALYTICS_IDparticipateInMetaMetrics/metaMetricsIdin fixturesoptedIn/analyticsIdwithMetaMetricsControllerparticipateInMetaMetricsin onboarding flowsoptedInOnboardingMetricsFlowOptionsCI note
Domain PRs that touch E2E tests failed
Test lintuntil fixture types accepted both legacy and canonical field names. #43467 adds transitional dual-support so child PRs can merge independently. UI-only PRs (#43432, #43433, #43436, #43437) already pass CI without the E2E shim.Deferred to Phase C
participateInMetaMetricspropertyUserProfile.metaMetricsIdmetametricsIdNote
Medium Risk
Wide refactor of analytics consent gating (Sentry, install/open events, OAuth buffering, RPC sampling); behavior should match prior tri-state logic but any missed consumer could mis-track or drop events.
Overview
This PR removes the legacy UI projection
participateInMetaMetrics/metaMetricsIdand moves background, Sentry, OAuth, and network/RPC metrics code toanalyticsId,optedIn, andcompletedMetaMetricsOnboardingfromAnalyticsController/MetaMetricsController.MetamaskController.getState()no longer synthesizes the old fields; consent checks now require onboarding completed and opted in (e.g.AppOpened,AppInstalledbuffering, cookie handler, Sentry transport/integration).getMetaMetricsStateis renamed togetAnalyticsStateand returns the three canonical fields instead of a combinedparticipateInMetaMetricstri-state.Messenger init for network, remote feature flags, auth, and profile metrics now reads
AnalyticsController:getStateinstead ofMetaMetricsController:getMetaMetricsId. OAuth replacesgetParticipateInMetaMetricswith separate onboarding/opt-in getters. E2E fixtures and flows useoptedIn/analyticsId(andMOCK_ANALYTICS_ID) when seeding metrics-enabled state.Reviewed by Cursor Bugbot for commit 7d51dab. Bugbot is set up for automated code reviews on this repo. Configure here.