refactor(analytics): add foundation selectors and background migration#43430
Conversation
Introduce getOptedIn, getCompletedMetaMetricsOnboarding, and getAnalyticsId while keeping deprecated legacy selector aliases and getState() projection for unmigrated consumers. Migrate background services, Sentry, and shared metrics context to canonical analytics fields. Co-authored-by: Cursor <cursoragent@cursor.com>
|
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. |
Realign metamask-controller.js with main to undo accidental seedless drift from the monolithic checkout while keeping the analytics cookie handler migration. Fix oxfmt formatting in metametrics selectors. Co-authored-by: Cursor <cursoragent@cursor.com>
…branch Restore metametrics-controller multichain tests and realign foundation slice with refactor/analytics-phase-b after merging latest main. Co-authored-by: Cursor <cursoragent@cursor.com>
Re-add deprecated selector aliases and getState projection required for parallel consumer PRs while keeping main-synced controller updates. Co-authored-by: Cursor <cursoragent@cursor.com>
Add explicit unit test for the canonical onboarding completion selector alongside existing legacy shim coverage. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Pull request overview
This PR lays the “Phase B foundation” for the analytics refactor by migrating UI/background/Sentry/services to the canonical analytics consent model (analyticsId, optedIn, completedMetaMetricsOnboarding) while keeping temporary backward-compat selector + getState() projections for legacy callers.
Changes:
- Introduces canonical UI selectors/state for
analyticsId,optedIn, andcompletedMetaMetricsOnboarding, and keeps deprecated aliases for legacy selectors (getMetaMetricsId,getParticipateInMetaMetrics, etc.). - Updates background/services/controller wiring (OAuth, network RPC metrics sampling, data deletion, cookie handler) to use the split consent model and
analyticsId. - Refactors Sentry gating/state resolution to require
completedMetaMetricsOnboarding && optedIn, and attachesanalyticsIdasuser.idwhen available.
Reviewed changes
Copilot reviewed 37 out of 37 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| ui/selectors/selectors.js | Adds getAnalyticsId and keeps getMetaMetricsId as deprecated alias. |
| ui/selectors/metametrics.test.ts | Adds coverage for new canonical selectors and validates ID source. |
| ui/selectors/metametrics.js | Adds getOptedIn / getCompletedMetaMetricsOnboarding; deprecates legacy consent selectors. |
| ui/hooks/useMetametrics.test.tsx | Updates hook tests’ mocked state to canonical consent fields. |
| ui/ducks/metamask/metamask.js | Updates Redux initial/reset state to canonical analytics consent fields. |
| ui/contexts/metametrics.tsx | Gates tracking/buffering using canonical consent fields + analyticsId. |
| app/scripts/services/oauth/types.ts | Splits getParticipateInMetaMetrics into onboarding + opt-in getters. |
| app/scripts/services/oauth/oauth-service.ts | Updates OAuth event gating to completedMetaMetricsOnboarding && optedIn. |
| app/scripts/services/oauth/oauth-service.test.ts | Updates OAuth tests for new consent getter contract. |
| app/scripts/services/data-deletion-service.ts | Renames deletion API param to analyticsId. |
| app/scripts/services/data-deletion-service.test.ts | Updates tests to use mockAnalyticsId. |
| app/scripts/services/data-deletion-service-method-action-types.ts | Updates JSDoc param naming to analyticsId. |
| app/scripts/metamask-controller.js | Uses canonical consent fields for cookie handler and continues legacy getState() projection. |
| app/scripts/messenger-client-init/seedless-onboarding/oauth-service-init.ts | Wires OAuth service with canonical onboarding/opt-in getters. |
| app/scripts/messenger-client-init/seedless-onboarding/oauth-service-init.test.ts | Updates OAuth init test mock state shape. |
| app/scripts/messenger-client-init/remote-feature-flag-controller-init.ts | Sources ID via AnalyticsController:getState().analyticsId. |
| app/scripts/messenger-client-init/profile-metrics-controller-init.ts | Sources ID from analyticsController.state.analyticsId. |
| app/scripts/messenger-client-init/network-controller-init.ts | Renames RPC metrics sampling input to analyticsId via AnalyticsController:getState(). |
| app/scripts/messenger-client-init/messengers/remote-feature-flag-controller-messenger.ts | Delegates AnalyticsController:getState for init. |
| app/scripts/messenger-client-init/messengers/network-controller-messenger.ts | Delegates AnalyticsController:getState for init. |
| app/scripts/lib/util.ts | Renames dapp-view sampling helper to take analyticsId. |
| app/scripts/lib/setupSentry.js | Switches to analytics state helpers and split consent gating for breadcrumbs/integration. |
| app/scripts/lib/sentry-metametrics.ts | Updates Sentry integration to use canonical consent + analyticsId user binding. |
| app/scripts/lib/sentry-metametrics.test.ts | Updates integration tests for canonical state shape. |
| app/scripts/lib/sentry-make-transport.ts | Updates transport gating to canonical consent fields. |
| app/scripts/lib/sentry-get-state.ts | Renames and reshapes participation resolution to getAnalyticsState returning canonical fields. |
| app/scripts/lib/sentry-get-state.test.ts | Updates tests for new analytics participation shape and gating. |
| app/scripts/lib/network-controller/utils.ts | Renames RPC sampling inputs to analyticsId and updates terminology. |
| app/scripts/lib/network-controller/utils.test.ts | Updates tests to use MOCK_ANALYTICS_ID and analyticsId parameter. |
| app/scripts/lib/network-controller/messenger-action-handlers.ts | Renames RPC event gating input to analyticsId. |
| app/scripts/lib/network-controller/messenger-action-handlers.test.ts | Updates handler tests to pass analyticsId. |
| app/scripts/fixtures/with-preferences.js | Updates fixture consent fields to canonical split model. |
| app/scripts/controllers/metametrics-data-deletion/metametrics-data-deletion.test.ts | Updates deletion controller tests to use analyticsId wiring. |
| app/scripts/controllers/metametrics-controller.ts | Updates MetaMaskState typing and trait gating to canonical consent fields. |
| app/scripts/controllers/metametrics-controller.test.ts | Updates controller tests for canonical consent fields and analyticsId. |
| app/scripts/background.js | Updates install/open/dapp-view metrics gating to canonical consent fields + analyticsId. |
| .storybook/test-data.js | Updates storybook state fixtures to canonical consent fields and analyticsId. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…p-e2e Update JSDoc and test descriptions to use analytics ID instead of MetaMetrics ID after the analyticsId rename. Co-authored-by: Cursor <cursoragent@cursor.com>
Builds ready [7311dbb]
⚡ Performance Benchmarks (Total: 🟢 17 pass · 🟡 7 warn · 🔴 1 fail)
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
Description
Part 1 of the Analytics Phase B split (supersedes monolithic #43406).
Reason: Phase B migrates off legacy
participateInMetaMetrics/metaMetricsIdtoward canonicalanalyticsId,optedIn, andcompletedMetaMetricsOnboarding.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 #43442):
getParticipateInMetaMetricscompleted && optedIngetIsParticipateInMetaMetricsSetgetCompletedMetaMetricsOnboardinggetMetaMetricsIdgetAnalyticsIdstate.metamask.metaMetricsIdstate.metamask.analyticsIdgetState()state.metamask.participateInMetaMetricsgetState()Merge order: Must merge before consumer PRs (#43431–#43441).
Changelog
CHANGELOG entry: null
Related issues
Part of https://github.com/MetaMask/MetaMask-planning/issues/7331
Manual testing steps
yarn startand load the extensionPre-merge author checklist
Pre-merge reviewer checklist
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
participateInMetaMetricsandmetaMetricsIdas the source of truth and wiresanalyticsId,optedIn, andcompletedMetaMetricsOnboardingthrough Redux, background, controllers, and Sentry.The UI Redux slice and selectors now expose the canonical fields (
getOptedIn,getCompletedMetaMetricsOnboarding,getAnalyticsId), with deprecated aliases forgetParticipateInMetaMetrics,getIsParticipateInMetaMetricsSet, andgetMetaMetricsId.MetaMetricsProvidergates 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 readanalyticsIdand requirecompletedMetaMetricsOnboarding && optedInwhere metrics used to checkparticipateInMetaMetrics. Messenger inits fetch the ID viaAnalyticsController:getStaterather thanMetaMetricsController: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 attachuser.idfromanalyticsId.getState()in the main controller still projects legacyparticipateInMetaMetrics/metaMetricsIdfor parallel consumer PRs.Reviewed by Cursor Bugbot for commit 7311dbb. Bugbot is set up for automated code reviews on this repo. Configure here.