Skip to content

feat(network-controller): emit RPC service analytics via AnalyticsController#9270

Draft
cryptodev-2s wants to merge 7 commits into
mainfrom
feat/network-controller-analytics-events
Draft

feat(network-controller): emit RPC service analytics via AnalyticsController#9270
cryptodev-2s wants to merge 7 commits into
mainfrom
feat/network-controller-analytics-events

Conversation

@cryptodev-2s

@cryptodev-2s cryptodev-2s commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Explanation

Today NetworkController emits no analytics. It publishes rpcEndpointUnavailable and rpcEndpointDegraded events, and each client app independently subscribes to them and turns them into the RPC Service Unavailable / RPC Service Degraded Segment events. The extension still routes those through MetaMetricsController; mobile already routes them through AnalyticsController. The handlers are near identical duplication across both repos.

This moves that translation into NetworkController so it is written once and delivered through the AnalyticsController:trackEvent action over the messenger (which is the whole reason AnalyticsController exists). Clients can then delete their duplicated handlers and just wire the new option.

The feature is fully opt in via a new optional analytics constructor option. When omitted, no analytics are emitted and AnalyticsController is never called, so existing consumers are unaffected. The two genuinely client specific pieces are injected because core cannot know them:

  • isRpcEndpointUrlPublic(url): whether an endpoint URL is safe to report verbatim (depends on the client network lists, Quicknode URLs, Infura key)
  • rpcServiceEventsSampleRate: the proportion of events to emit (depends on the build environment, typically 1% in production and 100% in dev)

Core reads analyticsId via AnalyticsController:getState, applies the sample rate with generateDeterministicRandomNumber, skips local connection errors, builds the properties, and delivers the event. AnalyticsController keeps owning consent gating.

What changed

  • New src/rpc-service-events.ts: pure helpers (sanitizeRpcEndpointUrl, buildRpcServiceEventProperties, toAnalyticsTrackingEvent) plus the NetworkControllerAnalyticsOptions and RpcServiceEventName types
  • src/NetworkController.ts: new optional analytics option, widened AllowedActions with AnalyticsController:getState + AnalyticsController:trackEvent, two guarded self subscriptions, and a private #trackRpcServiceEvent
  • Added @metamask/analytics-controller dependency and tsconfig references (no dependency cycle)
  • index.ts, tests/helpers.ts, CHANGELOG.md, and a new tests/NetworkController.analytics.test.ts

Open question

AnalyticsTrackingEvent has no category field, so the old category: 'Network' is not carried for now. Confirming with the analytics owners how they want category mapped before relying on it downstream.

Follow ups (separate repos)

  • metamask-extension: delete messenger-action-handlers.ts + utils.ts, pass the analytics option, delegate the two AnalyticsController actions. This is where the extension stops using MetaMetricsController for these events.
  • metamask-mobile: same deletion and wiring (it already delegates AnalyticsController).

References

N/A

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 highlighted breaking changes using the "BREAKING" category above as appropriate
  • I've manually tested code paths covered by the new tests

Note

Medium Risk
Opt-in analytics wiring touches the network controller messenger contract (breaking for adopters) and emits RPC endpoint metadata, though private URLs are redacted and consent still flows through AnalyticsController.

Overview
NetworkController gains an opt-in analytics constructor option. When set, it listens to existing rpcEndpointUnavailable and rpcEndpointDegraded events and emits RPC Service Unavailable / RPC Service Degraded through AnalyticsController:trackEvent, with URL sanitization, deterministic sampling, and skips for local connection errors and missing analyticsId.

A new rpc-service-events module holds property builders and exported NetworkControllerAnalyticsOptions / RpcServiceEventName types. The package adds @metamask/analytics-controller and documents a breaking requirement: messengers must delegate AnalyticsController:getState and AnalyticsController:trackEvent when using analytics. Omitting the option leaves behavior unchanged.

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

…troller

NetworkController now emits "RPC Service Unavailable" and "RPC Service
Degraded" analytics events itself through the AnalyticsController:trackEvent
action, instead of relying on each client app to translate its
rpcEndpointUnavailable/rpcEndpointDegraded events into MetaMetrics.

The feature is opt in via a new optional `analytics` constructor option.
When omitted, no analytics are emitted and AnalyticsController is never
called. The two client specific pieces stay injected because core cannot
know them: `isRpcEndpointUrlPublic` (depends on the client network lists)
and `rpcServiceEventsSampleRate` (depends on the build environment).

The generic property building, event naming, connection error skipping and
delivery now live in core (src/rpc-service-events.ts), so both clients can
drop their duplicated handlers in follow up PRs.
@cryptodev-2s cryptodev-2s requested review from a team as code owners June 25, 2026 20:19
The build tsconfig flagged passing the `unknown` catch variable to
`captureException`, which expects an `Error`. Cast it, matching the other
captureException call sites. Also regenerate the root README dependency
graph to include the new analytics-controller edge.
@cryptodev-2s cryptodev-2s marked this pull request as draft June 26, 2026 09:14
@cryptodev-2s

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

@github-actions

Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@7.5.3-preview-14cbc2873
@metamask-previews/accounts-controller@39.0.3-preview-14cbc2873
@metamask-previews/address-book-controller@7.1.2-preview-14cbc2873
@metamask-previews/ai-controllers@0.7.0-preview-14cbc2873
@metamask-previews/analytics-controller@1.2.0-preview-14cbc2873
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-14cbc2873
@metamask-previews/announcement-controller@8.1.0-preview-14cbc2873
@metamask-previews/app-metadata-controller@2.0.1-preview-14cbc2873
@metamask-previews/approval-controller@9.0.2-preview-14cbc2873
@metamask-previews/assets-controller@9.1.0-preview-14cbc2873
@metamask-previews/assets-controllers@109.2.2-preview-14cbc2873
@metamask-previews/authenticated-user-storage@2.1.0-preview-14cbc2873
@metamask-previews/base-controller@9.1.0-preview-14cbc2873
@metamask-previews/base-data-service@0.1.3-preview-14cbc2873
@metamask-previews/bitcoin-regtest-up@0.0.0-preview-14cbc2873
@metamask-previews/bridge-controller@77.0.0-preview-14cbc2873
@metamask-previews/bridge-status-controller@73.0.0-preview-14cbc2873
@metamask-previews/build-utils@3.0.4-preview-14cbc2873
@metamask-previews/chain-agnostic-permission@1.6.2-preview-14cbc2873
@metamask-previews/chomp-api-service@3.1.0-preview-14cbc2873
@metamask-previews/claims-controller@0.5.3-preview-14cbc2873
@metamask-previews/client-controller@1.0.1-preview-14cbc2873
@metamask-previews/compliance-controller@2.1.0-preview-14cbc2873
@metamask-previews/composable-controller@12.0.1-preview-14cbc2873
@metamask-previews/config-registry-controller@0.4.1-preview-14cbc2873
@metamask-previews/connectivity-controller@0.2.0-preview-14cbc2873
@metamask-previews/controller-utils@12.3.0-preview-14cbc2873
@metamask-previews/core-backend@6.3.3-preview-14cbc2873
@metamask-previews/delegation-controller@3.0.2-preview-14cbc2873
@metamask-previews/earn-controller@12.2.1-preview-14cbc2873
@metamask-previews/eip-5792-middleware@3.0.4-preview-14cbc2873
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.1-preview-14cbc2873
@metamask-previews/eip1193-permission-middleware@2.0.1-preview-14cbc2873
@metamask-previews/ens-controller@19.1.4-preview-14cbc2873
@metamask-previews/eth-block-tracker@15.0.1-preview-14cbc2873
@metamask-previews/eth-json-rpc-middleware@23.1.3-preview-14cbc2873
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-14cbc2873
@metamask-previews/foundryup@1.0.1-preview-14cbc2873
@metamask-previews/gas-fee-controller@26.2.3-preview-14cbc2873
@metamask-previews/gator-permissions-controller@4.2.1-preview-14cbc2873
@metamask-previews/geolocation-controller@0.1.3-preview-14cbc2873
@metamask-previews/java-tron-up@0.0.0-preview-14cbc2873
@metamask-previews/json-rpc-engine@10.5.0-preview-14cbc2873
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-14cbc2873
@metamask-previews/keyring-controller@27.1.0-preview-14cbc2873
@metamask-previews/local-node-utils@0.0.0-preview-14cbc2873
@metamask-previews/logging-controller@8.0.2-preview-14cbc2873
@metamask-previews/message-manager@14.1.2-preview-14cbc2873
@metamask-previews/messenger@1.2.0-preview-14cbc2873
@metamask-previews/messenger-cli@0.2.0-preview-14cbc2873
@metamask-previews/money-account-balance-service@2.1.1-preview-14cbc2873
@metamask-previews/money-account-controller@0.3.3-preview-14cbc2873
@metamask-previews/money-account-upgrade-controller@2.1.0-preview-14cbc2873
@metamask-previews/multichain-account-service@11.1.0-preview-14cbc2873
@metamask-previews/multichain-api-middleware@3.1.5-preview-14cbc2873
@metamask-previews/multichain-network-controller@3.2.0-preview-14cbc2873
@metamask-previews/multichain-transactions-controller@7.1.1-preview-14cbc2873
@metamask-previews/name-controller@9.1.2-preview-14cbc2873
@metamask-previews/network-controller@33.0.0-preview-14cbc2873
@metamask-previews/network-enablement-controller@5.4.0-preview-14cbc2873
@metamask-previews/notification-services-controller@24.2.0-preview-14cbc2873
@metamask-previews/passkey-controller@2.0.1-preview-14cbc2873
@metamask-previews/permission-controller@13.1.1-preview-14cbc2873
@metamask-previews/permission-log-controller@5.1.0-preview-14cbc2873
@metamask-previews/perps-controller@9.0.0-preview-14cbc2873
@metamask-previews/phishing-controller@17.2.0-preview-14cbc2873
@metamask-previews/polling-controller@16.0.7-preview-14cbc2873
@metamask-previews/preferences-controller@23.1.0-preview-14cbc2873
@metamask-previews/profile-metrics-controller@4.0.0-preview-14cbc2873
@metamask-previews/profile-sync-controller@28.2.0-preview-14cbc2873
@metamask-previews/ramps-controller@15.0.0-preview-14cbc2873
@metamask-previews/rate-limit-controller@7.0.1-preview-14cbc2873
@metamask-previews/react-data-query@0.2.1-preview-14cbc2873
@metamask-previews/remote-feature-flag-controller@4.2.2-preview-14cbc2873
@metamask-previews/sample-controllers@5.0.2-preview-14cbc2873
@metamask-previews/seedless-onboarding-controller@10.0.3-preview-14cbc2873
@metamask-previews/selected-network-controller@26.1.4-preview-14cbc2873
@metamask-previews/shield-controller@5.1.2-preview-14cbc2873
@metamask-previews/signature-controller@39.2.6-preview-14cbc2873
@metamask-previews/smart-transactions-controller@24.2.3-preview-14cbc2873
@metamask-previews/snap-account-service@1.0.0-preview-14cbc2873
@metamask-previews/social-controllers@2.3.1-preview-14cbc2873
@metamask-previews/solana-test-validator-up@0.0.0-preview-14cbc2873
@metamask-previews/storage-service@1.0.2-preview-14cbc2873
@metamask-previews/subscription-controller@6.2.0-preview-14cbc2873
@metamask-previews/transaction-controller@68.2.0-preview-14cbc2873
@metamask-previews/transaction-pay-controller@23.16.1-preview-14cbc2873
@metamask-previews/user-operation-controller@41.2.5-preview-14cbc2873
@metamask-previews/wallet@5.0.0-preview-14cbc2873
@metamask-previews/wallet-cli@0.0.0-preview-14cbc2873

@cryptodev-2s cryptodev-2s marked this pull request as ready for review June 29, 2026 14:09
@cryptodev-2s

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

@github-actions

Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@7.5.3-preview-e0ee14da7
@metamask-previews/accounts-controller@39.0.3-preview-e0ee14da7
@metamask-previews/address-book-controller@7.1.2-preview-e0ee14da7
@metamask-previews/ai-controllers@0.7.0-preview-e0ee14da7
@metamask-previews/analytics-controller@1.2.1-preview-e0ee14da7
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-e0ee14da7
@metamask-previews/announcement-controller@8.1.0-preview-e0ee14da7
@metamask-previews/app-metadata-controller@2.0.1-preview-e0ee14da7
@metamask-previews/approval-controller@9.0.2-preview-e0ee14da7
@metamask-previews/assets-controller@9.1.0-preview-e0ee14da7
@metamask-previews/assets-controllers@109.2.2-preview-e0ee14da7
@metamask-previews/authenticated-user-storage@2.1.0-preview-e0ee14da7
@metamask-previews/base-controller@9.1.0-preview-e0ee14da7
@metamask-previews/base-data-service@0.1.3-preview-e0ee14da7
@metamask-previews/bitcoin-regtest-up@0.0.0-preview-e0ee14da7
@metamask-previews/bridge-controller@77.1.0-preview-e0ee14da7
@metamask-previews/bridge-status-controller@73.1.0-preview-e0ee14da7
@metamask-previews/build-utils@3.0.4-preview-e0ee14da7
@metamask-previews/chain-agnostic-permission@1.6.2-preview-e0ee14da7
@metamask-previews/chomp-api-service@3.1.0-preview-e0ee14da7
@metamask-previews/claims-controller@0.5.3-preview-e0ee14da7
@metamask-previews/client-controller@1.0.1-preview-e0ee14da7
@metamask-previews/compliance-controller@2.1.0-preview-e0ee14da7
@metamask-previews/composable-controller@12.0.1-preview-e0ee14da7
@metamask-previews/config-registry-controller@0.4.1-preview-e0ee14da7
@metamask-previews/connectivity-controller@0.2.0-preview-e0ee14da7
@metamask-previews/controller-utils@12.3.0-preview-e0ee14da7
@metamask-previews/core-backend@6.3.3-preview-e0ee14da7
@metamask-previews/delegation-controller@3.0.2-preview-e0ee14da7
@metamask-previews/earn-controller@12.2.1-preview-e0ee14da7
@metamask-previews/eip-5792-middleware@3.0.4-preview-e0ee14da7
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.1-preview-e0ee14da7
@metamask-previews/eip1193-permission-middleware@2.0.1-preview-e0ee14da7
@metamask-previews/ens-controller@19.1.4-preview-e0ee14da7
@metamask-previews/eth-block-tracker@15.0.1-preview-e0ee14da7
@metamask-previews/eth-json-rpc-middleware@23.1.3-preview-e0ee14da7
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-e0ee14da7
@metamask-previews/foundryup@1.0.1-preview-e0ee14da7
@metamask-previews/gas-fee-controller@26.2.3-preview-e0ee14da7
@metamask-previews/gator-permissions-controller@4.2.1-preview-e0ee14da7
@metamask-previews/geolocation-controller@0.1.3-preview-e0ee14da7
@metamask-previews/java-tron-up@0.0.0-preview-e0ee14da7
@metamask-previews/json-rpc-engine@10.5.0-preview-e0ee14da7
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-e0ee14da7
@metamask-previews/keyring-controller@27.1.0-preview-e0ee14da7
@metamask-previews/local-node-utils@0.0.0-preview-e0ee14da7
@metamask-previews/logging-controller@8.0.2-preview-e0ee14da7
@metamask-previews/message-manager@14.1.2-preview-e0ee14da7
@metamask-previews/messenger@1.2.0-preview-e0ee14da7
@metamask-previews/messenger-cli@0.2.0-preview-e0ee14da7
@metamask-previews/money-account-balance-service@2.1.1-preview-e0ee14da7
@metamask-previews/money-account-controller@0.3.3-preview-e0ee14da7
@metamask-previews/money-account-upgrade-controller@2.1.0-preview-e0ee14da7
@metamask-previews/multichain-account-service@11.1.0-preview-e0ee14da7
@metamask-previews/multichain-api-middleware@3.1.5-preview-e0ee14da7
@metamask-previews/multichain-network-controller@3.2.0-preview-e0ee14da7
@metamask-previews/multichain-transactions-controller@7.1.1-preview-e0ee14da7
@metamask-previews/name-controller@9.1.2-preview-e0ee14da7
@metamask-previews/network-controller@33.0.0-preview-e0ee14da7
@metamask-previews/network-enablement-controller@5.4.0-preview-e0ee14da7
@metamask-previews/notification-services-controller@24.2.0-preview-e0ee14da7
@metamask-previews/passkey-controller@2.0.1-preview-e0ee14da7
@metamask-previews/permission-controller@13.1.1-preview-e0ee14da7
@metamask-previews/permission-log-controller@5.1.0-preview-e0ee14da7
@metamask-previews/perps-controller@9.0.0-preview-e0ee14da7
@metamask-previews/phishing-controller@17.2.0-preview-e0ee14da7
@metamask-previews/polling-controller@16.0.7-preview-e0ee14da7
@metamask-previews/preferences-controller@23.1.0-preview-e0ee14da7
@metamask-previews/profile-metrics-controller@4.0.0-preview-e0ee14da7
@metamask-previews/profile-sync-controller@28.2.0-preview-e0ee14da7
@metamask-previews/ramps-controller@15.0.0-preview-e0ee14da7
@metamask-previews/rate-limit-controller@7.0.1-preview-e0ee14da7
@metamask-previews/react-data-query@0.2.1-preview-e0ee14da7
@metamask-previews/remote-feature-flag-controller@4.2.2-preview-e0ee14da7
@metamask-previews/sample-controllers@5.0.2-preview-e0ee14da7
@metamask-previews/seedless-onboarding-controller@10.0.3-preview-e0ee14da7
@metamask-previews/selected-network-controller@26.1.4-preview-e0ee14da7
@metamask-previews/shield-controller@5.1.2-preview-e0ee14da7
@metamask-previews/signature-controller@39.2.6-preview-e0ee14da7
@metamask-previews/smart-transactions-controller@24.2.3-preview-e0ee14da7
@metamask-previews/snap-account-service@1.0.0-preview-e0ee14da7
@metamask-previews/social-controllers@2.3.1-preview-e0ee14da7
@metamask-previews/solana-test-validator-up@0.0.0-preview-e0ee14da7
@metamask-previews/stellar-quickstart-up@0.0.0-preview-e0ee14da7
@metamask-previews/storage-service@1.0.2-preview-e0ee14da7
@metamask-previews/subscription-controller@6.2.0-preview-e0ee14da7
@metamask-previews/transaction-controller@68.2.0-preview-e0ee14da7
@metamask-previews/transaction-pay-controller@23.17.1-preview-e0ee14da7
@metamask-previews/user-operation-controller@41.2.5-preview-e0ee14da7
@metamask-previews/wallet@5.0.0-preview-e0ee14da7
@metamask-previews/wallet-cli@0.0.0-preview-e0ee14da7

@cryptodev-2s cryptodev-2s marked this pull request as draft June 30, 2026 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant