Skip to content

Conversation

@NicolasMassart
Copy link
Contributor

@NicolasMassart NicolasMassart commented Nov 6, 2025

Important

This is an unreleased package which will continue to be improved until ready for release.

analytics-controller update

  • Added onSetupCompleted lifecycle hook for post-initialization setup
  • Added UUIDv4 validation for analyticsId
  • Added getter methods: getAnalyticsId(), isEnabled(), isOptedIn(), isSocialOptedIn()
  • Added social opt-in/opt-out methods: socialOptIn(), socialOptOut()
  • Added AnalyticsPlatformAdapterSetupError for setup failures
  • Refactored state structure: enabled → computed via computeEnabledState(), optedInuser_optedIn, analyticsIduser_analyticsId, added user_socialOptedIn
  • Added analyticsStateComputer module with computeEnabledState() function to compute enabled state from user opt-in status
  • Removed enable() and disable() methods (replaced by computed enabled state)
  • Added AnalyticsTrackingEvent type with properties, sensitiveProperties, isAnonymous, hasProperties for anonymous/non-anonymous tracking
  • Updated trackEvent to accept AnalyticsTrackingEvent instead of separate eventName and properties parameters
  • Made identify and view required in AnalyticsPlatformAdapter
  • Renamed controller method: trackPagetrackView for platform agnostic usage
  • Renamed adapter type method: trackEventtrack to better match Segment SDKs
  • Refactored identify: removed userId parameter, uses analyticsId from state, added AnalyticsUserTraits type
  • Updated action types for new methods and renames
  • Updated tests for new API and lifecycle hook
  • Updated README with lifecycle hook documentation

References

fixes #7079

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, highlighting breaking changes as necessary
  • I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes

Note

Refactors controller/adapter APIs (track/view, new event type), adds onSetupCompleted and UUID validation, splits opt-in state with computed enabled, and introduces selectors with updated actions, tests, and docs.

  • API changes:
    • Rename trackEventtrack and trackPagetrackView; update messenger actions to trackView and new opt-in actions for regular/social accounts.
    • identify now uses current analyticsId and accepts traits only.
    • trackEvent now accepts AnalyticsTrackingEvent (supports properties/sensitiveProperties, hasProperties).
  • State & computation:
    • Replace enabled/optedIn with optedInForRegularAccount and optedInForSocialAccount; enabled is derived via computeEnabledState.
    • Add selectors in selectors.ts (selectAnalyticsId, selectOptedIn, selectSocialOptedIn, selectEnabled).
  • Platform adapter:
    • Require track, identify, view; add onSetupCompleted(analyticsId) lifecycle hook and AnalyticsPlatformAdapterSetupError.
  • Validation & behavior:
    • Validate analyticsId as UUIDv4 (analyticsStateValidator).
    • Track sensitive data as a separate event with isSensitive flag.
  • Tests & docs:
    • Add tests for state computer, validator, selectors, lifecycle hook, and updated methods.
    • Update README to reflect new API and lifecycle hook.

Written by Cursor Bugbot for commit 21a5dda. This will update automatically on new commits. Configure here.

- Add onSetupCompleted lifecycle hook to AnalyticsPlatformAdapter interface
- Remove add method from interface (breaking change)
- Change AnalyticsPlatformAdapter from type alias to interface
- Add UUIDv4 validation for analyticsId with error handling
- Add AnalyticsUserTraits type for better semantic separation
- Rename trackEvent to track and trackPage to view in adapter interface
- Update controller to call onSetupCompleted after initialization
- Add comprehensive tests for lifecycle hook and validation
- Update documentation with lifecycle hook usage examples
@NicolasMassart NicolasMassart self-assigned this Nov 6, 2025
@NicolasMassart NicolasMassart changed the title feat(analytics-controller): update controller and adapter interface for mobile integration feat(analytics-controller): update controller and adapter interface for mobile integration [Phase 1.4] Nov 7, 2025
NicolasMassart and others added 7 commits November 7, 2025 11:49
…y method

- Add isOptedIn method and corresponding action type
- Refactor identify method to use analyticsId from state instead of userId parameter
- Update tests to use realistic traits (ENABLE_OPENSEA_API, NFT_AUTODETECTION) instead of email
- Update UUID test example from v1 to v5
- Remove obsolete tests
- Fix formatting issues
…TrackingEvent object

- Add AnalyticsJsonValue and AnalyticsJsonMap types similar to legacy types for easier migration
- Add AnalyticsTrackingEvent type matching legacy ITrackingEvent structure
- Update trackEvent method to accept AnalyticsTrackingEvent instead of separate eventName and properties
- Implement same logic as legacy trackEvent (handles hasProperties, isAnonymous, sensitiveProperties)
- Remove redundant saveDataRecording parameter (now part of event object)
- Convert interfaces to type aliases for consistency
- Update tests
…m:MetaMask/core into refactor/7079_update_analytics_controller
@NicolasMassart

This comment was marked as outdated.

@github-actions

This comment was marked as outdated.

@NicolasMassart NicolasMassart marked this pull request as ready for review November 17, 2025 18:00
@NicolasMassart NicolasMassart requested review from a team as code owners November 17, 2025 18:00
Copy link
Contributor

@mcmire mcmire left a comment

Choose a reason for hiding this comment

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

Hi @NicolasMassart! Thanks for the ping. I had some comments and suggestions below.

* Represents values that can be passed as properties to the event tracking function.
* Similar to JsonValue from Segment SDK but decoupled for platform agnosticism.
*/
type AnalyticsJsonValue =
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible to simplify this type and use Json? I see that there are slight differences between this type and Json, namely that objects are allowed to have number keys. However if this data really gets serialized to JSON, wouldn't the keys get converted to strings anyway?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here are the resons why I used this explicit type:

Using Record<string, Json> (current):

✅ Explicit: must be an object whith named props of Json type value
✅ Type-safe: rejects arrays, primitives, null
✅ Consistent with BaseController.StateConstraint and ApprovalController

Using Json directly:

✅ Simpler
✅ Matches runtime JSON serialization behavior
❌ Less type-safe: allows arrays, primitives, null
❌ Less explicit intent as naming the AnalyticsEventProperties and AnalyticsUserTraits types allows to clearly identify the usage in controller.

My recommendation:

Keep Record<string, Json> for type safety and consistency. If you really prefers Json, we can switch, but it weakens compile-time guarantees.

NicolasMassart and others added 8 commits November 18, 2025 15:57
…and extract validation

- Remove isAnonymous field, derive sensitivity from sensitiveProperties presence
- Extract state validation to analyticsStateValidator module (called before super)
- Add selectors module for state access
- Add comprehensive unit tests for validator and selectors
- Update documentation for clarity
…m:MetaMask/core into refactor/7079_update_analytics_controller

# Conflicts:
#	packages/analytics-controller/src/selectors.test.ts
@NicolasMassart
Copy link
Contributor Author

@metamaskbot publish-preview

@github-actions
Copy link
Contributor

Preview builds have been published. See these instructions for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-tree-controller": "3.0.0-preview-21a5ddac",
  "@metamask-previews/accounts-controller": "34.0.0-preview-21a5ddac",
  "@metamask-previews/address-book-controller": "7.0.0-preview-21a5ddac",
  "@metamask-previews/analytics-controller": "0.0.0-preview-21a5ddac",
  "@metamask-previews/announcement-controller": "8.0.0-preview-21a5ddac",
  "@metamask-previews/app-metadata-controller": "2.0.0-preview-21a5ddac",
  "@metamask-previews/approval-controller": "8.0.0-preview-21a5ddac",
  "@metamask-previews/assets-controllers": "89.0.1-preview-21a5ddac",
  "@metamask-previews/base-controller": "9.0.0-preview-21a5ddac",
  "@metamask-previews/bridge-controller": "61.0.0-preview-21a5ddac",
  "@metamask-previews/bridge-status-controller": "61.0.0-preview-21a5ddac",
  "@metamask-previews/build-utils": "3.0.4-preview-21a5ddac",
  "@metamask-previews/chain-agnostic-permission": "1.2.2-preview-21a5ddac",
  "@metamask-previews/claims-controller": "0.2.0-preview-21a5ddac",
  "@metamask-previews/composable-controller": "12.0.0-preview-21a5ddac",
  "@metamask-previews/controller-utils": "11.15.0-preview-21a5ddac",
  "@metamask-previews/core-backend": "4.1.0-preview-21a5ddac",
  "@metamask-previews/delegation-controller": "1.0.0-preview-21a5ddac",
  "@metamask-previews/earn-controller": "10.0.0-preview-21a5ddac",
  "@metamask-previews/eip-5792-middleware": "2.0.0-preview-21a5ddac",
  "@metamask-previews/eip-7702-internal-rpc-middleware": "0.1.0-preview-21a5ddac",
  "@metamask-previews/eip1193-permission-middleware": "1.0.2-preview-21a5ddac",
  "@metamask-previews/ens-controller": "18.0.0-preview-21a5ddac",
  "@metamask-previews/error-reporting-service": "3.0.0-preview-21a5ddac",
  "@metamask-previews/eth-block-tracker": "14.0.0-preview-21a5ddac",
  "@metamask-previews/eth-json-rpc-middleware": "21.0.0-preview-21a5ddac",
  "@metamask-previews/eth-json-rpc-provider": "5.0.1-preview-21a5ddac",
  "@metamask-previews/foundryup": "1.0.1-preview-21a5ddac",
  "@metamask-previews/gas-fee-controller": "25.0.0-preview-21a5ddac",
  "@metamask-previews/gator-permissions-controller": "0.5.0-preview-21a5ddac",
  "@metamask-previews/json-rpc-engine": "10.1.1-preview-21a5ddac",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.8-preview-21a5ddac",
  "@metamask-previews/keyring-controller": "24.0.0-preview-21a5ddac",
  "@metamask-previews/logging-controller": "7.0.0-preview-21a5ddac",
  "@metamask-previews/message-manager": "14.0.0-preview-21a5ddac",
  "@metamask-previews/messenger": "0.3.0-preview-21a5ddac",
  "@metamask-previews/multichain-account-service": "3.0.0-preview-21a5ddac",
  "@metamask-previews/multichain-api-middleware": "1.2.4-preview-21a5ddac",
  "@metamask-previews/multichain-network-controller": "2.0.0-preview-21a5ddac",
  "@metamask-previews/multichain-transactions-controller": "6.0.0-preview-21a5ddac",
  "@metamask-previews/name-controller": "9.0.0-preview-21a5ddac",
  "@metamask-previews/network-controller": "25.0.0-preview-21a5ddac",
  "@metamask-previews/network-enablement-controller": "3.1.0-preview-21a5ddac",
  "@metamask-previews/notification-services-controller": "20.0.0-preview-21a5ddac",
  "@metamask-previews/permission-controller": "12.1.0-preview-21a5ddac",
  "@metamask-previews/permission-log-controller": "5.0.0-preview-21a5ddac",
  "@metamask-previews/phishing-controller": "15.0.1-preview-21a5ddac",
  "@metamask-previews/polling-controller": "15.0.0-preview-21a5ddac",
  "@metamask-previews/preferences-controller": "21.0.0-preview-21a5ddac",
  "@metamask-previews/profile-sync-controller": "26.0.0-preview-21a5ddac",
  "@metamask-previews/rate-limit-controller": "7.0.0-preview-21a5ddac",
  "@metamask-previews/remote-feature-flag-controller": "2.0.0-preview-21a5ddac",
  "@metamask-previews/sample-controllers": "3.0.0-preview-21a5ddac",
  "@metamask-previews/seedless-onboarding-controller": "6.1.0-preview-21a5ddac",
  "@metamask-previews/selected-network-controller": "25.0.0-preview-21a5ddac",
  "@metamask-previews/shield-controller": "2.1.1-preview-21a5ddac",
  "@metamask-previews/signature-controller": "36.0.0-preview-21a5ddac",
  "@metamask-previews/subscription-controller": "4.2.2-preview-21a5ddac",
  "@metamask-previews/token-search-discovery-controller": "4.0.0-preview-21a5ddac",
  "@metamask-previews/transaction-controller": "61.3.0-preview-21a5ddac",
  "@metamask-previews/transaction-pay-controller": "8.0.0-preview-21a5ddac",
  "@metamask-previews/user-operation-controller": "40.0.0-preview-21a5ddac"
}

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.

feat(analytics-controller): update controller and adapter interface for mobile integration [Phase 1.4]

3 participants