feat: Integrate perps infrastructure and streaming bridge#40769
feat: Integrate perps infrastructure and streaming bridge#40769
Conversation
✨ Files requiring CODEOWNER review ✨👨🔧 @MetaMask/extension-platform (4 files, +24 -0)
👨🔧 @MetaMask/perps (4 files, +1335 -0)
📜 @MetaMask/policy-reviewers (8 files, +912 -0)
Tip Follow the policy review process outlined in the LavaMoat Policy Review Process doc before expecting an approval from Policy Reviewers. 👨🔧 @itsyoboieltr (4 files, +24 -0)
|
…rps-controller-infrastructure-stream
d9da503 to
bf9f17c
Compare
Builds ready [445be1c]
⚡ Performance Benchmarks
🌐 Dapp Page Load BenchmarksCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
app/scripts/metamask-controller.js
Outdated
| assetsUnifyFlag, | ||
| ASSETS_UNIFY_STATE_VERSION_1, | ||
| ); | ||
| const shouldInitPerpsController = isPerpsFeatureEnabled( |
There was a problem hiding this comment.
We cannot conditionally instantiate the controller using a remote feature flag. The shape of our controller state cannot change at runtime, but feature flags can.
There was a problem hiding this comment.
You can use a build flag for something like this, but not a remote flag that can change at runtime.
For runtime changes you could disable the controller conditionally but we need to instantiate it at least.
There was a problem hiding this comment.
I've refactored this to initialize the controller conditionally based on the PERPS_ENABLED build flag here: 4b6042d
This turned out a bit more complicated than I initially thought. We now have 2 main guards in place:
- Build flag
PERPS_ENABLEDthat prevents the controller from initializing during build time in designated environments. - Remote flag
perpsEnabledthat prevents the UI from rendering at run time, controlled by LaunchDarkly
We definitely don't want the UI to render if the build time flag is false, and the controller isn't initialized. It probably doesn't matter as much in the inverse scenario, where the UI is hidden but we initialize the controller. The newly renamed getIsPerpsExperienceAvailable selector gates on both.
On that note, these flags were annoyingly similar in naming conventions, and hard to distinguish which is used where. So, this commit also includes changes to rename some of our selectors and helpers to hopefully make this more clear.
This caused a larger file diff and more codeowners, but I think it made sense to do it.
Builds ready [a646f34]
⚡ Performance Benchmarks
🌐 Dapp Page Load BenchmarksCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
Builds ready [ae702a9]
⚡ Performance Benchmarks
🌐 Dapp Page Load BenchmarksCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
…S_ENABLED build flag
| "mainnet": false, | ||
| "testnet": false | ||
| }, | ||
| "hip3ConfigVersion": 1, |
There was a problem hiding this comment.
E2E fixture has wrong hip3ConfigVersion default value
Low Severity
The hip3ConfigVersion in default-fixture.json is set to 1, while the onboarding-fixture.json and the unit test mock for getDefaultPerpsControllerState both use 0. Since both fixtures represent initial PerpsController state and the controller's default state function returns 0, the default fixture likely has an incorrect value. This inconsistency could cause E2E tests using the default fixture to operate with non-default state, potentially masking bugs related to hip3 config version handling.
Additional Locations (1)
Builds ready [4b6042d]
⚡ Performance Benchmarks
🌐 Dapp Page Load BenchmarksCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 4 total unresolved issues (including 3 from previous reviews).
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
|
| export const getIsPerpsExperienceAvailable = createSelector( | ||
| getRemoteFeatureFlags, | ||
| (remoteFeatureFlags) => | ||
| isPerpsFeatureEnabled(remoteFeatureFlags.perpsEnabledVersion), | ||
| getIsPerpsIncludedInBuild() && | ||
| isPerpsRemoteConfigSatisfied(remoteFeatureFlags.perpsEnabledVersion), |
There was a problem hiding this comment.
This selector is what we would use in the UI to not render until both the controller is initialized and the remote flag is true
Builds ready [224d079]
⚡ Performance Benchmarks
🌐 Dapp Page Load BenchmarksCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
ccharly
left a comment
There was a problem hiding this comment.
LGTM for accounts files:
ui/components/multichain/account-overview/account-overview-tabs.tsx
| 'data.ProfileMetricsController.syncQueue', | ||
| // non-EVM account IDs ARE NOT deterministic and each keyring has metadata (with source of randomness) | ||
| 'data.KeyringController.vault', | ||
| // PerpsController is conditionally included in build via PERPS_ENABLED env var |
There was a problem hiding this comment.
The fixture validation won't use different values for PERPS_ENABLED between runs though, so I'm not sure why this would be a relevant reason to exclude this.
Also this may be related to the Cursor comment about the fixture state being incorrect.
| "permissionActivityLog": "object", | ||
| "permissionHistory": "object" | ||
| }, | ||
| "PerpsController": "object", |
There was a problem hiding this comment.
Nit: This shows that perps data would not be included in Sentry debug snapshots. We should update SENTRY_BACKGROUND_STATE in app/scripts/constants/sentry-state.ts to expose data that is PII-free, so that we have more data to use when diagnosing Sentry errors
Gudahtt
left a comment
There was a problem hiding this comment.
LGTM!
I found two potential problems (potential out-of-sync fixtures, and lack of Perps data in Sentry snapshots), but I'm OK with those being addressed in a follow up PR if you'd prefer





Description
This PR is scoped to the controller infrastructure and streaming bridge layer of the Perps integration. It builds on a prerequisite PR that installed
@metamask/perps-controllerand removed the local development alias — this PR assumes the real package is already present.Broken out from intitial feature branch PR: #40078
Controller infrastructure (
app/scripts/controllers/perps/):infrastructure.ts— wires platform-specific dependencies (KeyringController signing, MetaMetrics, Sentry, performance monitoring) for injection intoPerpsControllerperps-stream-bridge.ts— per-UI-connection WebSocket subscription lifecycle manager; bridges background controller streams to the UIoutStreamand tears down cleanly on disconnect, testnet toggle, or stream endinfrastructure.test.ts+perps-stream-bridge.test.ts— comprehensive unit test coverageController registration (
app/scripts/metamask-controller.js):PerpsControllerInitregistered viaapp/scripts/controller-init/perps-controller-init.tsapp/scripts/controller-init/messengers/perps-controller-messenger.tsperpsInit, streaming activation, trading/data methods, preference helpersRelated PRs:
Changelog
CHANGELOG entry: Integrates perps controller v1 with messenger streams and API
Related issues
Fixes:
Manual testing steps
Screenshots/Recordings
Before
After
Pre-merge author checklist
Pre-merge reviewer checklist
Note
Medium Risk
Adds a new background controller, RPC surface, and WebSocket streaming bridge gated by
PERPS_ENABLED, which can impact controller initialization and connection lifecycle if misconfigured. Risk is mitigated by compile-time gating, conservative eligibility checks, and extensive unit tests around init/stream teardown.Overview
Introduces a build-time
PERPS_ENABLEDgate for Perps support and wiresPerpsControllerinto controller initialization only when enabled, including default env/build config updates.Adds
PerpsControllerInitplus a restrictedPerpsControllermessenger and background API mapping (most methods delegate directly;perpsDepositWithConfirmationreturnslastDepositTransactionId, andperpsGetUserHistoryproxies to the active provider). Eligibility monitoring is started/stopped based onPreferencesController.useExternalServicesand network request lifecycle.Adds
createPerpsInfrastructure(logger/Sentry hook, version-gated feature flags, formatting helpers, and stubbed metrics/tracing/cache/rewards) and aPerpsStreamBridgethat manages per-UI-connection static/dynamic subscriptions and emitsperpsStreamUpdatemessages only while the perps view is active.Updates build/tooling to accommodate perps dependencies (Lavamoat policies, sourcemap validator skip for perps dynamic
import(), webpack warning ignore, additional ignored module patterns), bumps@metamask/perps-controllerto^1.3.0, and updates tests/fixtures to includePerpsControllerstate where applicable.Written by Cursor Bugbot for commit 224d079. This will update automatically on new commits. Configure here.