Skip to content

fix: clear analytics queue on callback errors#8934

Merged
gauthierpetetin merged 2 commits into
mainfrom
fix/analytics-queue-clear-callback-errors
Jun 5, 2026
Merged

fix: clear analytics queue on callback errors#8934
gauthierpetetin merged 2 commits into
mainfrom
fix/analytics-queue-clear-callback-errors

Conversation

@gauthierpetetin

@gauthierpetetin gauthierpetetin commented May 29, 2026

Copy link
Copy Markdown
Contributor

Explanation

Clear persisted analytics queue entries once the platform adapter delivery callback fires, even when the callback receives an error. This aligns queue cleanup behavior with the previous Segment-backed MetaMetrics flow and avoids repeatedly replaying malformed or permanently failing events on restart.

References

NA

For example:

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Medium Risk
Changes when persisted analytics events are dropped versus retried; events reported as failed by the adapter will not be re-sent after restart, which is intentional but affects delivery reliability semantics.

Overview
When persisted event-queue delivery runs, AnalyticsController now removes queued entries as soon as the platform adapter’s delivery callback fires, including when the callback passes an error. Failed deliveries are still logged; the queue is no longer left intact for those cases.

That matches prior Segment-backed MetaMetrics behavior and stops replaying events that already failed delivery (for example malformed or permanently rejected payloads) on the next startup. Queued items are still retained if the adapter throws synchronously before the callback runs.

Tests and the package changelog were updated for the new cleanup behavior.

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

Copilot AI left a comment

Copy link
Copy Markdown

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 updates AnalyticsController’s persisted event-queue behavior so queued analytics entries are removed once the platform adapter’s delivery callback fires, even when that callback reports an error. This prevents permanently failing/malformed events from being replayed on restart and aligns cleanup semantics with the prior Segment-backed MetaMetrics behavior.

Changes:

  • Remove the early-return on callback error so queued events are always removed after the delivery callback runs.
  • Update the event-queue persistence tests to assert queue cleanup on callback error and adjust a mutation test to avoid triggering callback-driven removal.
  • Document the behavior change in the analytics-controller package changelog.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
packages/analytics-controller/src/AnalyticsController.ts Always clears a queued event after the adapter callback runs (success or error).
packages/analytics-controller/src/AnalyticsController.test.ts Updates expectations for callback-error behavior and keeps clone-mutation test stable under new semantics.
packages/analytics-controller/CHANGELOG.md Notes the fixed queue-cleanup behavior in Unreleased.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@gauthierpetetin gauthierpetetin added this pull request to the merge queue Jun 5, 2026
Merged via the queue into main with commit 391c74a Jun 5, 2026
371 checks passed
@gauthierpetetin gauthierpetetin deleted the fix/analytics-queue-clear-callback-errors branch June 5, 2026 13:05
@gauthierpetetin gauthierpetetin mentioned this pull request Jun 5, 2026
4 tasks
HowardBraham pushed a commit to consensys-test/metamask-extension-howard that referenced this pull request Jun 5, 2026
## **Description**

This PR integrates AnalyticsController in Extension codebase.

It replaces this state:
- MetaMetricsController's `metaMetricsId`
- MetaMetricsController's `participateInMetaMetrics`
- MetaMetricsController's `segmentApiCalls`

by this state:
- AnalyticsController's `analyticsId`
- AnalyticsController's `optedIn`
- AnalyticsController's `eventQueue`
- MetaMetricsController's `completedMetaMetricsOnboarding`

Since these changes impact many areas of the codebase, we’ve decided to
take a phased approach.

This PR migrates the persisted state and updates the UI compatibility
selectors, as well as the background `getState()` function, to derive
the legacy values (`metaMetricsId`, `participateInMetaMetrics`) from the
new state. This lets existing code continue using the legacy values
while the source of truth moves to `AnalyticsController.analyticsId`,
`AnalyticsController.optedIn`, and
`MetaMetricsController.completedMetaMetricsOnboarding`.

In future phases, we’ll progressively remove all remaining usages of the
legacy values (`metaMetricsId`, `participateInMetaMetrics`) throughout
the codebase.

The files that deserve more attention during PR review are the
following:

- app/scripts/controllers/analytics/platform-adapter.ts
- app/scripts/controllers/metametrics-controller.ts

```mermaid
flowchart TB
  subgraph Before["Before"]
    direction LR
    MMC1["MetaMetricsController"] --> SDK1["Segment SDK"]
    Early1["Early events"] --> SDK1
  end

  subgraph After["After"]
    direction LR
    MMC2["MetaMetricsController"] --> AC["AnalyticsController"]
    AC --> SDK2["Segment SDK"]
    Early2["Early events"] --> SDK2
  end

  Before ~~~ After
```

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: MetaMask/MetaMask-planning#7193

## **Manual testing steps**

Main test case
1. Build two different Extensions, one on this branch and one on main,
the goal will be to compare events emitted by both and confirm they're
equivalent
2. Go through onboarding with both extension and find your
metaMetricsId/analyticsId by doing right click on extension UI, then
inspect > Application > Storage > IndexedDB > metamask-backup >
MetaMetricsController/AnalyticsController
3. Open Segment, choose the right source (usually `MetaMask Extension
[Dev]`, except if you configured SEGMENT_WRITE_KEY env variable with
your own Segment project), and filter events with your
metaMetricsId/analyticsId
4. Confirm the three types of events emitted by both extension are
equivalent:
  a. track
  b. identify
  c. page

Edge cases
- Anonymous events (see list
[here](MetaMask/MetaMask-planning#7230))
  - Fully anonymous ones
- These events are fully anonymous in the sense that the entire event,
including all properties are considered as sensitive and get anonymized
- Fully anonymous events are emitted by passing "excludeMetaMetricsId:
true" as option (Example
[here](https://github.com/MetaMask/metamask-extension/blob/main/app/scripts/background.js#L502))
- An easy one to reproduce is "Phishing Page Displayed": visit one of
the pages listed
[here](https://phishing-detection.api.cx.metamask.io/v1/stalelist) and
the event will be emitted
  - Partially anonymous ones
- These events are partially anonymous in the sense that some properties
are considered as sensitive and some are not. As a consequence, 2 events
are sent: an anonymous one with all properties, and a non-anonymous one
with only properties considered as non-sensitive
- Partially anonymous events are emitted by passing
"sensitiveProperties" (Example
[here](https://github.com/MetaMask/metamask-extension/blob/main/ui/pages/contacts/components/add-contact-form.tsx#L236-L239))
- An easy one to reproduce is "Contact Added": go to Contacts, click
"Add contact", and add Vitalik's address as contact
(0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045)
- Before this PR, both events used to have similar messageId (example:
"1780055175321.6592", and "1780055175321.6592-0x000"), while with this
PR, messageId have a new uuidv4 format and both events don't have
similar messageId (example: "5cc0d85e-3f0e-4374-8811-d36924d06689" and
"433ff4c1-948d-4a4e-9470-81e878c7df44")
  - Anonymous ones with event renaming
- Some anonymous events get renamed when being emitted (list of events
available
[here](https://github.com/MetaMask/metamask-extension/blob/main/app/scripts/controllers/metametrics-controller.ts#L113-L130)):
for example “Signature Requested” gets renamed “Signature Requested
Anon”
- An easy one to reproduce is “Signature Requested” (see Fragments
sections below for more detail)
- Fragments
- Fragments are events used to tie a multi-step flow together, such as
“Signature Requested” followed later by “Signature Approved” or
“Signature Rejected”
- They can be tested by visiting
[test-dapp](https://metamask.github.io/test-dapp/), then connect
extension, then click "Sign Typed Data V4", then accept or reject
signature
- The purpose of fragments is for both each event of the multi-step flow
to share the same properties
- Before this PR, events from a same fragment used to have similar
`messageId` (example: "signature-3947127447", and
"signature-3947127447-success" or "signature-3947127447-failure"), while
with this PR, `messageId` have a new uuidv4 format and events from a
same fragment don't have similar `messageId` (example:
"9e3a83d0-ce13-47d2-a2f4-08a6d9adc29d" and
"d2368a25-01c5-4b3c-af55-7d5f54eb58a6")
- Persisted queue
  - Go to home page
- Check that persisted queue is an empty object: right click on
extension UI, then inspect > Application > Storage > IndexedDB >
metamask-backup > MetaMetricsController/AnalyticsController >
segmentApiCalls/eventQueue
  - Turn internet off
  - Click on "Swap"
  - Confirm no event is sent to Segment
- Confirm events are added to persisted queue, including "Unified
SwapBridge Button Clicked" (click on refresh button in the inspector to
see them)
  - Wait for 5 minutes
  - Turn internet on
  - Restart extension
- Confirm events are sent to Segment, including "Unified SwapBridge
Button Clicked", and there's a 5 minute difference between `timestamp`
and `sentAt`
- These repro steps are not working on main branch, because persisted
queue used to get cleared, regardless of whether the callback represents
success or failure, whereas in this PR, it only gets cleared upon
success. That change of behavior introduces the risk that if an event is
malformed, it can end up being retried after every extension restart.
But at the same time it allows us to collect more events, in cases of
transient failures (e.g. offline, timeout). This core repo PR got opened
to align behavior with what's currently on main:
MetaMask/core#8934
- Early events
- Right click on extension UI, then inspect > Application > Storage >
Extension storage > Local > KeyringController > Right click to delete
KeyringController
  - Restart Extension straight away
- You should see "Vault Corruption Restore Wallet Screen Viewed" event
in Segment
- Opt out event
- Start from a fresh onboarding state, go through create/import wallet,
on the MetaMetrics onboarding page, uncheck “Participate in
MetaMetrics”, continue and finish onboarding.
    - On Chrome, you should see "Metrics Opt Out" event in Segment
    - On Firefox, you should not see "Metrics Opt Out" event in Segment
- Delete metametrics
- Right click on extension UI, then inspect > Network, and paste
"regulations" in the search bar
- Go to Settings > Privacy > Delete MetaMetrics data and click the
button
- You should see an API call in the Networks tab, with "subjectIds"
array as parameter, and your metaMetricsId/analyticsId included in that
array

## **Screenshots/Recordings**

NA

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.




<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **High Risk**
> Central refactor of consent, IDs, queuing, and anonymous event
handling across background, Segment, and data-deletion paths; messageId
and offline-queue behavior differ from main and can affect metrics
parity or stuck retries.
> 
> **Overview**
> This PR routes MetaMetrics **track / identify / page** through
**`AnalyticsController`** and a new **Segment `platform-adapter`**,
instead of **`MetaMetricsController`** calling Segment directly.
> 
> **State & consent:** Persisted **`metaMetricsId`**,
**`participateInMetaMetrics`**, and **`segmentApiCalls`** are removed
from **`MetaMetricsController`** in favor of **`AnalyticsController`**
(`analyticsId`, `optedIn`, `eventQueue`) plus
**`completedMetaMetricsOnboarding`**. Opt-in/out now calls
**`AnalyticsController:optIn` / `optOut`**; IDs come from
**`getMetaMetricsId()`** → analytics state. **Sentry** snapshots add
**`AnalyticsController`** and drop the old MMC consent fields.
> 
> **Behavior changes:** Anonymous / sensitive events use a
**`properties.anonymous`** marker; the adapter swaps to the shared
anonymous ID and renames select signature/transaction events. Direct
Segment logic (payload building, **`segmentApiCalls`** MV3 replay,
deterministic **`messageId`**, **`generateMetaMetricsId`**) is removed
from MMC. **Early** and **opt-out** paths use
**`custom-segment-tracking`** reading **`AnalyticsController`** from
backup state. **RPC middleware**, **data deletion**, and **background**
helpers read consent/ID via **`controller.getState()`** /
**`analyticsController.state`**.
> 
> **Tests:** Large **`metametrics-controller`** test updates; new
**`platform-adapter`** unit tests.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
5d73b11. 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 Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Norbert Elter <72046715+itsyoboieltr@users.noreply.github.com>
pull Bot pushed a commit to dmrazzy/core that referenced this pull request Jun 8, 2026
## Explanation

This is the release candidate for version `1023.0.0`. It releases
`@metamask/analytics-controller@1.1.1`, which clears persisted analytics
event queue entries after the delivery callback runs, including when the
callback reports an error
([MetaMask#8934](MetaMask#8934)).

## References

<!--
Are there any issues that this pull request is tied to?
Are there other links that reviewers should consult to understand these
changes better?
Are there client or consumer pull requests to adopt any breaking
changes?
-->

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [ ] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Version and changelog-only release with no code changes in this PR;
shipped fix is a patch-level analytics queue persistence behavior.
> 
> **Overview**
> **Monorepo release `1023.0.0`** bumps the root `package.json` version
from `1022.0.0` to `1023.0.0`.
> 
> It publishes **`@metamask/analytics-controller@1.1.1`** (from `1.1.0`)
with changelog entries for the fix in
[MetaMask#8934](MetaMask#8934): persisted analytics
event queue entries are cleared after the delivery callback runs,
including when the callback reports an error.
> 
> This PR contains **version and changelog updates only**; the
behavioral fix is not in this diff.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
b711b05. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
sgextcsi pushed a commit to sgextcsi/metamask-extension-ne-regression that referenced this pull request Jun 8, 2026
## **Description**

This PR integrates AnalyticsController in Extension codebase.

It replaces this state:
- MetaMetricsController's `metaMetricsId`
- MetaMetricsController's `participateInMetaMetrics`
- MetaMetricsController's `segmentApiCalls`

by this state:
- AnalyticsController's `analyticsId`
- AnalyticsController's `optedIn`
- AnalyticsController's `eventQueue`
- MetaMetricsController's `completedMetaMetricsOnboarding`

Since these changes impact many areas of the codebase, we’ve decided to
take a phased approach.

This PR migrates the persisted state and updates the UI compatibility
selectors, as well as the background `getState()` function, to derive
the legacy values (`metaMetricsId`, `participateInMetaMetrics`) from the
new state. This lets existing code continue using the legacy values
while the source of truth moves to `AnalyticsController.analyticsId`,
`AnalyticsController.optedIn`, and
`MetaMetricsController.completedMetaMetricsOnboarding`.

In future phases, we’ll progressively remove all remaining usages of the
legacy values (`metaMetricsId`, `participateInMetaMetrics`) throughout
the codebase.

The files that deserve more attention during PR review are the
following:

- app/scripts/controllers/analytics/platform-adapter.ts
- app/scripts/controllers/metametrics-controller.ts

```mermaid
flowchart TB
  subgraph Before["Before"]
    direction LR
    MMC1["MetaMetricsController"] --> SDK1["Segment SDK"]
    Early1["Early events"] --> SDK1
  end

  subgraph After["After"]
    direction LR
    MMC2["MetaMetricsController"] --> AC["AnalyticsController"]
    AC --> SDK2["Segment SDK"]
    Early2["Early events"] --> SDK2
  end

  Before ~~~ After
```

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: MetaMask/MetaMask-planning#7193

## **Manual testing steps**

Main test case
1. Build two different Extensions, one on this branch and one on main,
the goal will be to compare events emitted by both and confirm they're
equivalent
2. Go through onboarding with both extension and find your
metaMetricsId/analyticsId by doing right click on extension UI, then
inspect > Application > Storage > IndexedDB > metamask-backup >
MetaMetricsController/AnalyticsController
3. Open Segment, choose the right source (usually `MetaMask Extension
[Dev]`, except if you configured SEGMENT_WRITE_KEY env variable with
your own Segment project), and filter events with your
metaMetricsId/analyticsId
4. Confirm the three types of events emitted by both extension are
equivalent:
  a. track
  b. identify
  c. page

Edge cases
- Anonymous events (see list
[here](MetaMask/MetaMask-planning#7230))
  - Fully anonymous ones
- These events are fully anonymous in the sense that the entire event,
including all properties are considered as sensitive and get anonymized
- Fully anonymous events are emitted by passing "excludeMetaMetricsId:
true" as option (Example
[here](https://github.com/MetaMask/metamask-extension/blob/main/app/scripts/background.js#L502))
- An easy one to reproduce is "Phishing Page Displayed": visit one of
the pages listed
[here](https://phishing-detection.api.cx.metamask.io/v1/stalelist) and
the event will be emitted
  - Partially anonymous ones
- These events are partially anonymous in the sense that some properties
are considered as sensitive and some are not. As a consequence, 2 events
are sent: an anonymous one with all properties, and a non-anonymous one
with only properties considered as non-sensitive
- Partially anonymous events are emitted by passing
"sensitiveProperties" (Example
[here](https://github.com/MetaMask/metamask-extension/blob/main/ui/pages/contacts/components/add-contact-form.tsx#L236-L239))
- An easy one to reproduce is "Contact Added": go to Contacts, click
"Add contact", and add Vitalik's address as contact
(0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045)
- Before this PR, both events used to have similar messageId (example:
"1780055175321.6592", and "1780055175321.6592-0x000"), while with this
PR, messageId have a new uuidv4 format and both events don't have
similar messageId (example: "5cc0d85e-3f0e-4374-8811-d36924d06689" and
"433ff4c1-948d-4a4e-9470-81e878c7df44")
  - Anonymous ones with event renaming
- Some anonymous events get renamed when being emitted (list of events
available
[here](https://github.com/MetaMask/metamask-extension/blob/main/app/scripts/controllers/metametrics-controller.ts#L113-L130)):
for example “Signature Requested” gets renamed “Signature Requested
Anon”
- An easy one to reproduce is “Signature Requested” (see Fragments
sections below for more detail)
- Fragments
- Fragments are events used to tie a multi-step flow together, such as
“Signature Requested” followed later by “Signature Approved” or
“Signature Rejected”
- They can be tested by visiting
[test-dapp](https://metamask.github.io/test-dapp/), then connect
extension, then click "Sign Typed Data V4", then accept or reject
signature
- The purpose of fragments is for both each event of the multi-step flow
to share the same properties
- Before this PR, events from a same fragment used to have similar
`messageId` (example: "signature-3947127447", and
"signature-3947127447-success" or "signature-3947127447-failure"), while
with this PR, `messageId` have a new uuidv4 format and events from a
same fragment don't have similar `messageId` (example:
"9e3a83d0-ce13-47d2-a2f4-08a6d9adc29d" and
"d2368a25-01c5-4b3c-af55-7d5f54eb58a6")
- Persisted queue
  - Go to home page
- Check that persisted queue is an empty object: right click on
extension UI, then inspect > Application > Storage > IndexedDB >
metamask-backup > MetaMetricsController/AnalyticsController >
segmentApiCalls/eventQueue
  - Turn internet off
  - Click on "Swap"
  - Confirm no event is sent to Segment
- Confirm events are added to persisted queue, including "Unified
SwapBridge Button Clicked" (click on refresh button in the inspector to
see them)
  - Wait for 5 minutes
  - Turn internet on
  - Restart extension
- Confirm events are sent to Segment, including "Unified SwapBridge
Button Clicked", and there's a 5 minute difference between `timestamp`
and `sentAt`
- These repro steps are not working on main branch, because persisted
queue used to get cleared, regardless of whether the callback represents
success or failure, whereas in this PR, it only gets cleared upon
success. That change of behavior introduces the risk that if an event is
malformed, it can end up being retried after every extension restart.
But at the same time it allows us to collect more events, in cases of
transient failures (e.g. offline, timeout). This core repo PR got opened
to align behavior with what's currently on main:
MetaMask/core#8934
- Early events
- Right click on extension UI, then inspect > Application > Storage >
Extension storage > Local > KeyringController > Right click to delete
KeyringController
  - Restart Extension straight away
- You should see "Vault Corruption Restore Wallet Screen Viewed" event
in Segment
- Opt out event
- Start from a fresh onboarding state, go through create/import wallet,
on the MetaMetrics onboarding page, uncheck “Participate in
MetaMetrics”, continue and finish onboarding.
    - On Chrome, you should see "Metrics Opt Out" event in Segment
    - On Firefox, you should not see "Metrics Opt Out" event in Segment
- Delete metametrics
- Right click on extension UI, then inspect > Network, and paste
"regulations" in the search bar
- Go to Settings > Privacy > Delete MetaMetrics data and click the
button
- You should see an API call in the Networks tab, with "subjectIds"
array as parameter, and your metaMetricsId/analyticsId included in that
array

## **Screenshots/Recordings**

NA

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.




<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **High Risk**
> Central refactor of consent, IDs, queuing, and anonymous event
handling across background, Segment, and data-deletion paths; messageId
and offline-queue behavior differ from main and can affect metrics
parity or stuck retries.
> 
> **Overview**
> This PR routes MetaMetrics **track / identify / page** through
**`AnalyticsController`** and a new **Segment `platform-adapter`**,
instead of **`MetaMetricsController`** calling Segment directly.
> 
> **State & consent:** Persisted **`metaMetricsId`**,
**`participateInMetaMetrics`**, and **`segmentApiCalls`** are removed
from **`MetaMetricsController`** in favor of **`AnalyticsController`**
(`analyticsId`, `optedIn`, `eventQueue`) plus
**`completedMetaMetricsOnboarding`**. Opt-in/out now calls
**`AnalyticsController:optIn` / `optOut`**; IDs come from
**`getMetaMetricsId()`** → analytics state. **Sentry** snapshots add
**`AnalyticsController`** and drop the old MMC consent fields.
> 
> **Behavior changes:** Anonymous / sensitive events use a
**`properties.anonymous`** marker; the adapter swaps to the shared
anonymous ID and renames select signature/transaction events. Direct
Segment logic (payload building, **`segmentApiCalls`** MV3 replay,
deterministic **`messageId`**, **`generateMetaMetricsId`**) is removed
from MMC. **Early** and **opt-out** paths use
**`custom-segment-tracking`** reading **`AnalyticsController`** from
backup state. **RPC middleware**, **data deletion**, and **background**
helpers read consent/ID via **`controller.getState()`** /
**`analyticsController.state`**.
> 
> **Tests:** Large **`metametrics-controller`** test updates; new
**`platform-adapter`** unit tests.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
5d73b11. 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 Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Norbert Elter <72046715+itsyoboieltr@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants