Skip to content

feat: emit RPC service analytics from NetworkController (core)#43934

Draft
cryptodev-2s wants to merge 4 commits into
mainfrom
feat/network-controller-analytics-via-core
Draft

feat: emit RPC service analytics from NetworkController (core)#43934
cryptodev-2s wants to merge 4 commits into
mainfrom
feat/network-controller-analytics-via-core

Conversation

@cryptodev-2s

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

Copy link
Copy Markdown
Contributor

Description

Draft to verify the new @metamask/network-controller analytics logic (MetaMask/core#9270) works end to end in the extension.

Previously the extension subscribed to NetworkController's rpcEndpointUnavailable / rpcEndpointDegraded events and translated them into the RPC Service Unavailable / RPC Service Degraded Segment events by hand, duplicating logic that mobile also carries. The core change moves that translation into NetworkController itself, which now emits the events through AnalyticsController:trackEvent.

This PR wires the extension onto that new logic:

  • network-controller-init.ts: pass the new analytics option to NetworkController:
    • isRpcEndpointUrlPublic: the extension's existing isPublicEndpointUrl(url, infuraProjectId)
    • rpcServiceEventsSampleRate: derived from the build environment (1% in production/RC, 100% in dev/test, 0 when unknown). The per user 1% sampling is now applied inside the controller.
  • messengers/network-controller-messenger.ts: delegate AnalyticsController:getState and AnalyticsController:trackEvent to the NetworkController messenger so the controller can deliver events.
  • Removed the duplicated rpcEndpointUnavailable / rpcEndpointDegraded subscriptions, messenger-action-handlers.ts, and the now unused NetworkController init messenger.
  • utils.ts slimmed to a single getRpcServiceEventsSampleRate() helper.

Behavior parity is preserved (same events, names, properties, sampling, connection error skipping, public/private URL handling). The only move is that the logic lives in core now and delivers through AnalyticsController instead of MetaMetricsController (mobile already routes through AnalyticsController). Uses a preview build of @metamask/network-controller (33.0.0-preview-14cbc2873) while the core PR is in review.

Do not merge before MetaMask/core#9270 lands and a real @metamask/network-controller release replaces the preview resolution in package.json.

Open question carried from core: AnalyticsTrackingEvent has no category field, so the old category: 'Network' is not carried right now, pending confirmation from the analytics owners.

Changelog

CHANGELOG entry: null

Related issues

Fixes:

Manual testing steps

  1. Build the extension from this branch (it resolves @metamask/network-controller to the preview build).
  2. Opt into MetaMask metrics.
  3. Force an RPC endpoint to fail or degrade (e.g. point a network at an unreachable RPC URL, or throttle/return 5xx) so the controller publishes rpcEndpointUnavailable / rpcEndpointDegraded.
  4. Confirm an RPC Service Unavailable / RPC Service Degraded event is sent through AnalyticsController with the expected properties (chain_id_caip, rpc_domain, etc.).
  5. Confirm private/custom RPC URLs report rpc_domain: custom and that local connection errors do not produce events.

Screenshots/Recordings

N/A (no UI changes)

Before

After

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.

NetworkController now emits the "RPC Service Unavailable" and "RPC Service
Degraded" analytics events itself (via the new core analytics option that
calls AnalyticsController:trackEvent), so the extension no longer needs to
subscribe to the rpcEndpointUnavailable/rpcEndpointDegraded events and
translate them by hand.

Changes:
- Pass the new `analytics` option to NetworkController with the extension's
  isPublicEndpointUrl predicate and a sample rate derived from the build
  environment.
- Delegate AnalyticsController:getState and AnalyticsController:trackEvent to
  the NetworkController messenger so the controller can deliver events.
- Delete the duplicated messenger-action-handlers, drop the now unused
  NetworkController init messenger, and slim utils down to the sample rate
  helper.

Uses a preview build of @metamask/network-controller while the core PR is in
review.
@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-core-platform Core Platform team label Jun 26, 2026
@socket-security

socket-security Bot commented Jun 26, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​metamask/​network-controller@​33.0.0-preview-e0ee14da700000
Updated@​metamask/​analytics-controller@​1.1.1 ⏵ 1.2.198 +110088 +195 +1100

View full report

@cryptodev-2s

Copy link
Copy Markdown
Contributor Author

@metamaskbot update-policies

@mm-token-exchange-service

Copy link
Copy Markdown

Policies updated.
👀 Please review the diff for suspicious new powers.

Tip

Follow the policy review process outlined in the LavaMoat Policy Review Process doc before expecting an approval from Policy Reviewers.
🧠 Learn how to read policy diffs: https://lavamoat.github.io/guides/policy-diff/#what-to-look-for-when-reviewing-a-policy-diff

👀 lavamoat/browserify/beta/policy.json changes differ from lavamoat/browserify/main/policy.json changes
👀 lavamoat/browserify/experimental/policy.json changes differ from lavamoat/browserify/main/policy.json changes
👀 lavamoat/browserify/flask/policy.json changes differ from lavamoat/browserify/main/policy.json changes
👀 lavamoat/webpack/mv2/beta/policy.json changes differ from lavamoat/webpack/mv2/main/policy.json changes
👀 lavamoat/webpack/mv2/experimental/policy.json changes differ from lavamoat/webpack/mv2/main/policy.json changes
👀 lavamoat/webpack/mv2/flask/policy.json changes differ from lavamoat/webpack/mv2/main/policy.json changes
👀 lavamoat/webpack/mv3/beta/policy.json changes differ from lavamoat/webpack/mv3/main/policy.json changes
👀 lavamoat/webpack/mv3/experimental/policy.json changes differ from lavamoat/webpack/mv3/main/policy.json changes
👀 lavamoat/webpack/mv3/flask/policy.json changes differ from lavamoat/webpack/mv3/main/policy.json changes

@mm-token-exchange-service

Copy link
Copy Markdown

✨ Files requiring CODEOWNER review ✨

📜 @MetaMask/policy-reviewers (12 files, +48 -0)
  • 📁 lavamoat/
    • 📁 browserify/
      • 📁 beta/
        • 📄 policy.json +1 -0
      • 📁 experimental/
        • 📄 policy.json +1 -0
      • 📁 flask/
        • 📄 policy.json +1 -0
      • 📁 main/
        • 📄 policy.json +1 -0
    • 📁 webpack/
      • 📁 mv2/
        • 📁 beta/
          • 📄 policy.json +1 -0
        • 📁 experimental/
          • 📄 policy.json +1 -0
        • 📁 flask/
          • 📄 policy.json +1 -0
        • 📁 main/
          • 📄 policy.json +1 -0
      • 📁 mv3/
        • 📁 beta/
          • 📄 policy.json +10 -0
        • 📁 experimental/
          • 📄 policy.json +10 -0
        • 📁 flask/
          • 📄 policy.json +10 -0
        • 📁 main/
          • 📄 policy.json +10 -0

Tip

Follow the policy review process outlined in the LavaMoat Policy Review Process doc before expecting an approval from Policy Reviewers.

@mm-token-exchange-service

Copy link
Copy Markdown
Builds ready [dccd401]
Deprecated Browserify fallback builds
⚡ Performance Benchmarks (Total: 🟢 19 pass · 🟡 4 warn · 🔴 1 fail)

Baseline (latest main): 5370656 | Date: 6/26/2026 | Pipeline: 28234544552 | 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: +12%
  • loadNewAccount/total: +12%
  • loadNewAccount/inp: +27%
  • loadNewAccount/cls: -75%
  • confirmTx/inp: -22%
  • bridgeUserActions/bridge_load_page: -13%
  • bridgeUserActions/longTaskCount: -29%
  • bridgeUserActions/longTaskTotalDuration: -27%
  • bridgeUserActions/longTaskMaxDuration: -10%
  • bridgeUserActions/tbt: -31%
  • loadNewAccount/inp: -37%
  • loadNewAccount/lcp: +1091%
  • confirmTx/confirm_tx: +11%
  • confirmTx/longTaskCount: -100%
  • confirmTx/longTaskTotalDuration: -100%
  • confirmTx/longTaskMaxDuration: -100%
  • confirmTx/tbt: -100%
  • confirmTx/total: +11%
  • confirmTx/inp: -22%
  • confirmTx/lcp: +1184%
  • bridgeUserActions/bridge_load_page: +125%
  • bridgeUserActions/bridge_load_asset_picker: +67%
  • bridgeUserActions/longTaskCount: -100%
  • bridgeUserActions/longTaskTotalDuration: -100%
  • bridgeUserActions/longTaskMaxDuration: -100%
  • bridgeUserActions/tbt: -100%
  • bridgeUserActions/inp: -12%
  • bridgeUserActions/fcp: -50%
  • bridgeUserActions/lcp: +1158%
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
startupPowerUserHome
[Sentry log · main/release]
🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/domInteractive: -36%
  • startupStandardHome/initialActions: +11%
  • startupStandardHome/setupStore: -11%
  • startupStandardHome/fcp: -32%
  • startupPowerUserHome/uiStartup: -13%
  • startupPowerUserHome/load: -11%
  • startupPowerUserHome/domContentLoaded: -11%
  • startupPowerUserHome/domInteractive: -35%
  • startupPowerUserHome/backgroundConnect: -34%
  • startupPowerUserHome/firstReactRender: -10%
  • startupPowerUserHome/loadScripts: -10%
  • startupPowerUserHome/setupStore: +13%
  • startupPowerUserHome/fcp: -32%
  • startupPowerUserHome/lcp: -14%

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

  • 🟡 startupPowerUserHome/INP: p75 208ms
  • 🟡 startupPowerUserHome/LCP: p75 3.2s
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/pwFormToMetricsScreen: +20%
  • onboardingImportWallet/metricsToWalletReadyScreen: -33%
  • onboardingImportWallet/doneButtonToHomeScreen: -81%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: -100%
  • onboardingImportWallet/longTaskCount: -72%
  • onboardingImportWallet/longTaskTotalDuration: -90%
  • onboardingImportWallet/longTaskMaxDuration: -84%
  • onboardingImportWallet/tbt: -95%
  • onboardingImportWallet/total: -84%
  • onboardingNewWallet/agreeButtonToOnboardingSuccess: +11%
  • onboardingNewWallet/doneButtonToAssetList: -28%
  • onboardingNewWallet/longTaskCount: -50%
  • onboardingNewWallet/longTaskTotalDuration: -50%
  • onboardingNewWallet/longTaskMaxDuration: -10%
  • onboardingNewWallet/tbt: -54%
  • onboardingNewWallet/total: -23%
  • solanaAssetDetails/assetClickToPriceChart: -57%
  • solanaAssetDetails/total: -57%
  • solanaAssetDetails/cls: +40%
  • importSrpHome/loginToHomeScreen: -20%
  • importSrpHome/homeAfterImportWithNewWallet: -38%
  • importSrpHome/longTaskCount: -24%
  • importSrpHome/longTaskTotalDuration: -40%
  • importSrpHome/longTaskMaxDuration: -25%
  • importSrpHome/tbt: -45%
  • importSrpHome/total: -37%
  • importSrpHome/inp: -28%
  • importSrpHome/lcp: +17%
  • importSrpHome/cls: -63%
  • sendTransactions/selectTokenToSendFormLoaded: +143%
  • sendTransactions/reviewTransactionToConfirmationPage: -11%
  • sendTransactions/longTaskCount: -100%
  • sendTransactions/longTaskTotalDuration: -100%
  • sendTransactions/longTaskMaxDuration: -100%
  • sendTransactions/tbt: -100%
  • sendTransactions/total: -10%
  • sendTransactions/inp: -23%
  • sendTransactions/lcp: +12%
  • sendTransactions/cls: -91%

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

  • 🔴 assetDetails/INP: p75 744ms
  • 🟡 assetDetails/FCP: p75 1.8s
  • 🟡 solanaAssetDetails/FCP: p75 1.8s
  • 🟡 importSrpHome/FCP: p75 2.1s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: -305 Bytes (0%)
  • ui: 2.57 KiB (0.01%)
  • common: 0 Bytes (0%)
  • other: 0 Bytes (0%)
  • contentScripts: 326 Bytes (0.02%)
  • zip: 839 Bytes (0%)

@sonarqubecloud

Copy link
Copy Markdown

@mm-token-exchange-service

Copy link
Copy Markdown
Builds ready [4827d78]
Deprecated Browserify fallback builds
⚡ Performance Benchmarks (Total: 🟢 19 pass · 🟡 5 warn · 🔴 0 fail)

Baseline (latest main): becf282 | Date: 6/29/2026 | Pipeline: 28384145839 | Baseline logs

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/inp: -13%
  • confirmTx/inp: +35%
  • bridgeUserActions/bridge_load_page: +11%
  • bridgeUserActions/bridge_load_asset_picker: +15%
  • bridgeUserActions/longTaskCount: -17%
  • bridgeUserActions/tbt: +13%
  • bridgeUserActions/inp: -18%
  • loadNewAccount/load_new_account: +120%
  • loadNewAccount/total: +120%
  • loadNewAccount/inp: -21%
  • loadNewAccount/fcp: -69%
  • loadNewAccount/lcp: +1034%
  • confirmTx/longTaskCount: -100%
  • confirmTx/longTaskTotalDuration: -100%
  • confirmTx/longTaskMaxDuration: -100%
  • confirmTx/tbt: -100%
  • confirmTx/lcp: +1052%
  • bridgeUserActions/bridge_load_page: +107%
  • bridgeUserActions/bridge_load_asset_picker: +64%
  • bridgeUserActions/longTaskCount: -100%
  • bridgeUserActions/longTaskTotalDuration: -100%
  • bridgeUserActions/longTaskMaxDuration: -100%
  • bridgeUserActions/tbt: -100%
  • bridgeUserActions/total: +11%
  • bridgeUserActions/inp: -18%
  • bridgeUserActions/lcp: +1199%

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

  • 🟡 loadNewAccount/FCP: p75 1.8s
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
startupPowerUserHome
[Sentry log · main/release]
🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/domInteractive: -27%
  • startupStandardHome/fcp: -25%
  • startupPowerUserHome/backgroundConnect: -16%
  • startupPowerUserHome/setupStore: +27%
  • startupPowerUserHome/fcp: -12%

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

  • 🟡 startupPowerUserHome/LCP: p75 3.9s
User Journey Benchmarks · Samples: 5 · mock API
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: -80%
  • onboardingImportWallet/longTaskTotalDuration: -92%
  • onboardingImportWallet/longTaskMaxDuration: -90%
  • onboardingImportWallet/tbt: -98%
  • onboardingImportWallet/total: -86%
  • onboardingNewWallet/skipBackupToMetricsScreen: +10%
  • onboardingNewWallet/agreeButtonToOnboardingSuccess: +14%
  • onboardingNewWallet/doneButtonToAssetList: -33%
  • onboardingNewWallet/longTaskTotalDuration: -33%
  • onboardingNewWallet/longTaskMaxDuration: -26%
  • onboardingNewWallet/tbt: -71%
  • onboardingNewWallet/total: -29%
  • solanaAssetDetails/assetClickToPriceChart: -74%
  • solanaAssetDetails/total: -74%
  • solanaAssetDetails/inp: -37%
  • solanaAssetDetails/lcp: +15%
  • solanaAssetDetails/cls: +1172%
  • importSrpHome/loginToHomeScreen: -15%
  • importSrpHome/openAccountMenuAfterLogin: -38%
  • importSrpHome/homeAfterImportWithNewWallet: -46%
  • importSrpHome/longTaskCount: -26%
  • importSrpHome/longTaskTotalDuration: -42%
  • importSrpHome/longTaskMaxDuration: -41%
  • importSrpHome/tbt: -40%
  • importSrpHome/total: -39%
  • importSrpHome/inp: -37%
  • importSrpHome/cls: -62%
  • sendTransactions/openSendPageFromHome: -17%
  • sendTransactions/selectTokenToSendFormLoaded: -35%
  • sendTransactions/reviewTransactionToConfirmationPage: +45%
  • sendTransactions/longTaskCount: -29%
  • sendTransactions/longTaskTotalDuration: -29%
  • sendTransactions/tbt: -47%
  • sendTransactions/total: +44%
  • sendTransactions/inp: -18%
  • sendTransactions/cls: -39%

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

  • 🟡 solanaAssetDetails/FCP: p75 1.8s
  • 🟡 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: 1.29 KiB (0.01%)
  • ui: 2.72 KiB (0.02%)
  • common: 0 Bytes (0%)
  • other: 0 Bytes (0%)
  • contentScripts: 326 Bytes (0.02%)
  • zip: 1.24 KiB (0%)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants