Skip to content

refactor(analytics): add foundation selectors and background migration#43430

Merged
gauthierpetetin merged 10 commits into
mainfrom
refactor/analytics-phase-b-foundation
Jun 11, 2026
Merged

refactor(analytics): add foundation selectors and background migration#43430
gauthierpetetin merged 10 commits into
mainfrom
refactor/analytics-phase-b-foundation

Conversation

@gauthierpetetin

@gauthierpetetin gauthierpetetin commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Description

Part 1 of the Analytics Phase B split (supersedes monolithic #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 #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 (#43431#43441).

Changelog

CHANGELOG entry: null

Related issues

Part of https://github.com/MetaMask/MetaMask-planning/issues/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

Pre-merge author checklist

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.

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.

Reviewed by Cursor Bugbot for commit 7311dbb. Bugbot is set up for automated code reviews on this repo. Configure here.

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>
@github-actions

Copy link
Copy Markdown
Contributor

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.

@mm-token-exchange-service mm-token-exchange-service Bot added the team-extension-platform Extension Platform team label Jun 11, 2026
@mm-token-exchange-service mm-token-exchange-service Bot added the INVALID-PR-TEMPLATE PR's body doesn't match template label Jun 11, 2026
@mm-token-exchange-service mm-token-exchange-service Bot removed the INVALID-PR-TEMPLATE PR's body doesn't match template label Jun 11, 2026
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>
gauthierpetetin and others added 2 commits June 11, 2026 08:00
…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>
itsyoboieltr
itsyoboieltr previously approved these changes Jun 11, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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, and completedMetaMetricsOnboarding, 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 attaches analyticsId as user.id when 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.

Comment thread app/scripts/lib/network-controller/messenger-action-handlers.ts Outdated
Comment thread app/scripts/lib/network-controller/messenger-action-handlers.ts Outdated
Comment thread app/scripts/lib/network-controller/messenger-action-handlers.ts Outdated
Comment thread app/scripts/lib/network-controller/utils.test.ts Outdated
Comment thread app/scripts/lib/network-controller/utils.test.ts Outdated
Comment thread app/scripts/lib/network-controller/utils.test.ts Outdated
Comment thread app/scripts/lib/network-controller/utils.test.ts Outdated
…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>
@metamaskbotv2

metamaskbotv2 Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor
Builds ready [7311dbb]
Deprecated Browserify fallback builds
⚡ Performance Benchmarks (Total: 🟢 17 pass · 🟡 7 warn · 🔴 1 fail)

Baseline (latest main): 697494a | Date: 6/11/2026 | Pipeline: 27350950242 | Baseline logs

Metricschrome-webpackfirefox-webpack
onboardingNewWallet
[Sentry log · main/release]
🟢 [CI log]🔴 [CI log]

Regressions (🔴 1 failure)

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

📈 Results compared to the previous 5 runs on main

  • loadNewAccount/load_new_account: +18%
  • loadNewAccount/total: +18%
  • loadNewAccount/inp: -25%
  • confirmTx/longTaskCount: +25%
  • confirmTx/longTaskTotalDuration: +17%
  • confirmTx/tbt: +11%
  • confirmTx/inp: +36%
  • bridgeUserActions/longTaskCount: -29%
  • bridgeUserActions/longTaskTotalDuration: -23%
  • bridgeUserActions/tbt: -20%
  • bridgeUserActions/inp: +37%
  • loadNewAccount/load_new_account: +43%
  • loadNewAccount/total: +43%
  • loadNewAccount/inp: -33%
  • loadNewAccount/fcp: -50%
  • loadNewAccount/lcp: +1147%
  • confirmTx/longTaskCount: -100%
  • confirmTx/longTaskTotalDuration: -100%
  • confirmTx/longTaskMaxDuration: -100%
  • confirmTx/tbt: -100%
  • confirmTx/inp: -18%
  • confirmTx/fcp: -50%
  • confirmTx/lcp: +1129%
  • bridgeUserActions/bridge_load_page: +228%
  • bridgeUserActions/bridge_load_asset_picker: +42%
  • bridgeUserActions/longTaskCount: -100%
  • bridgeUserActions/longTaskTotalDuration: -100%
  • bridgeUserActions/longTaskMaxDuration: -100%
  • bridgeUserActions/tbt: -100%
  • bridgeUserActions/total: +33%
  • bridgeUserActions/inp: -27%
  • bridgeUserActions/lcp: +1097%
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
startupPowerUserHome
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/domInteractive: +26%
  • startupStandardHome/inp: -17%
  • startupStandardHome/fcp: +24%
  • startupPowerUserHome/domInteractive: -19%
  • startupPowerUserHome/backgroundConnect: -28%
  • startupPowerUserHome/fcp: -22%

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

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

📈 Results compared to the previous 5 runs on main

  • onboardingImportWallet/doneButtonToHomeScreen: -87%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: -98%
  • onboardingImportWallet/longTaskCount: -41%
  • onboardingImportWallet/longTaskTotalDuration: -84%
  • onboardingImportWallet/longTaskMaxDuration: -87%
  • onboardingImportWallet/tbt: -98%
  • onboardingImportWallet/total: -87%
  • onboardingNewWallet/createPwToRecoveryScreen: +12%
  • onboardingNewWallet/skipBackupToMetricsScreen: +16%
  • onboardingNewWallet/agreeButtonToOnboardingSuccess: +14%
  • onboardingNewWallet/longTaskTotalDuration: -60%
  • onboardingNewWallet/longTaskMaxDuration: -31%
  • onboardingNewWallet/tbt: -80%
  • assetDetails/assetClickToPriceChart: -16%
  • assetDetails/longTaskCount: +67%
  • assetDetails/longTaskTotalDuration: +42%
  • assetDetails/longTaskMaxDuration: +115%
  • assetDetails/tbt: -100%
  • assetDetails/total: -16%
  • assetDetails/inp: -31%
  • assetDetails/cls: -89%
  • solanaAssetDetails/assetClickToPriceChart: -69%
  • solanaAssetDetails/longTaskCount: -100%
  • solanaAssetDetails/longTaskTotalDuration: -100%
  • solanaAssetDetails/longTaskMaxDuration: -100%
  • solanaAssetDetails/tbt: -100%
  • solanaAssetDetails/total: -69%
  • solanaAssetDetails/cls: -92%
  • importSrpHome/loginToHomeScreen: -17%
  • importSrpHome/homeAfterImportWithNewWallet: -46%
  • importSrpHome/longTaskCount: -20%
  • importSrpHome/longTaskTotalDuration: -27%
  • importSrpHome/longTaskMaxDuration: -20%
  • importSrpHome/tbt: -33%
  • importSrpHome/total: -39%
  • importSrpHome/inp: -26%
  • importSrpHome/lcp: -59%
  • sendTransactions/openSendPageFromHome: -52%
  • sendTransactions/tbt: -14%
  • sendTransactions/inp: -43%
  • sendTransactions/fcp: -10%
  • sendTransactions/lcp: -20%
  • sendTransactions/cls: -84%

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

  • 🟡 solanaAssetDetails/FCP: p75 1.8s
  • 🟡 assetDetails/FCP: p75 1.9s
  • 🟡 solanaAssetDetails/FCP: p75 1.8s
  • 🟡 importSrpHome/FCP: p75 1.9s
  • 🟡 sendTransactions/FCP: p75 1.9s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 24.14 KiB (0.36%)
  • ui: 17.42 KiB (0.15%)
  • common: 175 Bytes (0%)

@gauthierpetetin gauthierpetetin added this pull request to the merge queue Jun 11, 2026
@github-project-automation github-project-automation Bot moved this from Needs dev review to Review finalised - Ready to be merged in PR review queue Jun 11, 2026
Merged via the queue into main with commit 86afca4 Jun 11, 2026
204 checks passed
@github-project-automation github-project-automation Bot moved this from Review finalised - Ready to be merged to Merged, Closed or Archived in PR review queue Jun 11, 2026
@gauthierpetetin gauthierpetetin deleted the refactor/analytics-phase-b-foundation branch June 11, 2026 14:49
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 11, 2026
@metamaskbot metamaskbot added the release-13.36.0 Issue or pull request that will be included in release 13.36.0 label Jun 11, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-13.36.0 Issue or pull request that will be included in release 13.36.0 risk:medium size-L team-extension-platform Extension Platform team

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

5 participants