Skip to content

feat: Perps Controller integration#40078

Draft
gambinish wants to merge 285 commits intomainfrom
perps/poc-controller-integration-temp
Draft

feat: Perps Controller integration#40078
gambinish wants to merge 285 commits intomainfrom
perps/poc-controller-integration-temp

Conversation

@gambinish
Copy link
Contributor

@gambinish gambinish commented Feb 13, 2026

Description

Summary

This PR integrates the @metamask/perps-controller package into MetaMask Extension, establishing the foundational controller layer for perpetual futures trading functionality. This branch began from a larger feature branch that included both controller integration and UI components - we've decoupled the UI in a separate downstream PR to unblock merging while using a preview package dependency.

The UI PR should go in before this one: #40076

Background

Originally developed as a comprehensive feature branch as a PoC, it included both backend controller integration and frontend UI. This quickly became bloated and difficult to manage, and was blocked to merge due to a preview-package dependency. This PR has been scoped down to focus on controller integration only.

The main blocker for merging was the dependency on a preview package (@metamask/perps-controller@0.0.0-preview-e4aa1532) which cannot be merged into main.

Core Controller Setup:

  • Added PerpsController integration via app/scripts/controllers/perps/index.ts
  • Implemented platform-specific infrastructure wiring in app/scripts/controllers/perps/infrastructure.ts
    • Connects controller to KeyringController for signing operations
    • Stubs for metrics (MetaMetrics), logging (Sentry), and performance monitoring
    • Stream manager for real-time market data
  • Integrated controller into metamask-controller.js

Dependencies:

  • Added preview package: @metamask/perps-controller@0.0.0-preview-e4aa1532 (temporary)
  • Updated LavaMoat policies for all build variants (MV2/MV3, main/beta/flask/experimental)

Architecture Notes

The PerpsController currently runs in the UI process (instantiated via getPerpsController.ts) but is intentionally structured to support eventual migration to the background script:

  • Infrastructure code lives in app/scripts/controllers/perps/ (background location)
  • UI-specific dependencies are injected via options to avoid cross-layer imports
  • Clean separation between controller logic and UI presentation

Migration Path

To use production package when ready:

  1. Update package.json:
    "dependencies": {
    "@metamask/perps-controller": "^1.0.0" // Replace preview version
    }

  2. Remove previewBuilds section in package.json

  3. Run yarn install and regenerate LavaMoat policies

When integrating the real @metamask/perps-controller we'll also need to remove aliases to the mock services:

  1. ✅ Install the real package: yarn add @metamask/perps-controller
  2. ✅ Remove the moduleNameMapper entries from both Jest configs
  3. ✅ Remove the webpack alias entry
  4. ✅ Remove the TypeScript paths entry
  5. ✅ Delete the entire ui/mocks/perps/perps-controller/ directory
  6. ✅ Update ui/hooks/perps/marginUtils.ts to import constants from the real package
  7. ✅ Test that all imports resolve correctly

Related Branches

Open in GitHub Codespaces

Changelog

CHANGELOG entry: Integrate Perps Controller

Related issues

Fixes:

Manual testing steps

  1. Go to this page...

Screenshots/Recordings

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.

gambinish and others added 30 commits February 2, 2026 18:23
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/39888?quickstart=1)

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry:

## **Related issues**

Fixes:

## **Manual testing steps**

1. Go to this page...
2.
3.

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] 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).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] 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]
> <sup>[Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) is
generating a summary for commit
d4f1f4a. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/39889?quickstart=1)

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry:

## **Related issues**

Fixes:

## **Manual testing steps**

1. Go to this page...
2.
3.

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] 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).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] 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.
@metamaskbotv2
Copy link
Contributor

metamaskbotv2 bot commented Feb 27, 2026

Builds ready [5e656c1]
⚡ Performance Benchmarks
👆 Interaction Benchmarks
🔌 Startup Benchmarks
BenchmarkMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P75 (ms)P95 (ms)
Power User HomeuiStartup2625159410416139727605150
load13661183199416814091805
domContentLoaded13491170198916113891696
domInteractive43241732840115
firstPaint20883596101293379
backgroundConnect66030448558005422223
firstReactRender25176372738
initialActions107114
loadScripts1090920172015711231446
setupStore187104131939
numNetworkReqs73351512787129
🧭 User Journey Benchmarks
🌐 Dapp Page Load Benchmarks

Current Commit: 5e656c1 | Date: 2/27/2026

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.04s (±54ms) 🟡 | historical mean value: 1.05s ⬇️ (historical data)
  • domContentLoaded-> current mean value: 733ms (±52ms) 🟢 | historical mean value: 740ms ⬇️ (historical data)
  • firstContentfulPaint-> current mean value: 79ms (±14ms) 🟢 | historical mean value: 83ms ⬇️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.04s 54ms 1.01s 1.33s 1.10s 1.33s
domContentLoaded 733ms 52ms 705ms 1.02s 797ms 1.02s
firstPaint 79ms 14ms 60ms 200ms 88ms 200ms
firstContentfulPaint 79ms 14ms 60ms 200ms 88ms 200ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: -61.66 KiB (-1.15%)
  • ui: 13.18 KiB (0.16%)
  • common: 2.51 MiB (23.07%)

@metamaskbotv2
Copy link
Contributor

metamaskbotv2 bot commented Feb 28, 2026

Builds ready [8c7c33d]
⚡ Performance Benchmarks
👆 Interaction Benchmarks
BenchmarkMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P75 (ms)P95 (ms)
Load New Accountload_new_account36028148077417480
total36028148077417480
Confirm Txconfirm_tx6117607561412661356141
total6117607561412661356141
Bridge User Actionsbridge_load_page20117723922213239
bridge_load_asset_picker26019033450281334
bridge_search_token7307217418734741
total1205113512886012611288
🔌 Startup Benchmarks
BenchmarkMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P75 (ms)P95 (ms)
Standard HomeuiStartup15031238175610915771684
load12731049148010113581427
domContentLoaded12661044147210113511420
domInteractive2816121192580
firstPaint194631359175222330
backgroundConnect23721627511241258
firstReactRender18103551928
initialActions2011226
loadScripts1044819124810111301192
setupStore1474671433
numNetworkReqs312296212289
Power User HomeuiStartup19351548253716119822286
load12961138179014412871685
domContentLoaded12821131176714112751670
domInteractive3823123194160
firstPaint1718845883211340
backgroundConnect34330141524356384
firstReactRender25165772642
initialActions103112
loadScripts1029900151514110141410
setupStore1884581937
numNetworkReqs58361462365120
🧭 User Journey Benchmarks
BenchmarkMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P75 (ms)P95 (ms)
Onboarding Import WalletimportWalletToSocialScreen2192182211221221
srpButtonToSrpForm95939829598
confirmSrpToPwForm22212202222
pwFormToMetricsScreen16151601616
metricsToWalletReadyScreen17171801718
doneButtonToHomeScreen965772121419211831214
openAccountMenuToAccountListLoaded74397021765426476517654
total8827879388652688318865
Onboarding New WalletcreateWalletToSocialScreen2252182347233234
srpButtonToPwForm1091091090109109
createPwToRecoveryScreen889099
skipBackupToMetricsScreen38373913839
agreeButtonToOnboardingSuccess16161601616
doneButtonToAssetList60654068954601689
total100392810825510011082
Asset DetailsassetClickToPriceChart41364534245
total41364534245
Solana Asset DetailsassetClickToPriceChart48484804848
total48484804848
Import Srp HomeloginToHomeScreen22252029245319224522453
openAccountMenuAfterLogin47425654956
homeAfterImportWithNewWallet24652238272117926212721
total47364436513025248305130
Send TransactionsopenSendPageFromHome18171911819
selectTokenToSendFormLoaded21192532025
reviewTransactionToConfirmationPage8588498687864868
total9029009063906906
SwapopenSwapPageFromHome1129413917121139
fetchAndDisplaySwapQuotes52944573636681161996366
total54054669648780862936487
🌐 Dapp Page Load Benchmarks

Current Commit: 8c7c33d | Date: 2/28/2026

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.04s (±39ms) 🟡 | historical mean value: 1.05s ⬇️ (historical data)
  • domContentLoaded-> current mean value: 728ms (±38ms) 🟢 | historical mean value: 739ms ⬇️ (historical data)
  • firstContentfulPaint-> current mean value: 79ms (±10ms) 🟢 | historical mean value: 83ms ⬇️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.04s 39ms 1.02s 1.34s 1.06s 1.34s
domContentLoaded 728ms 38ms 709ms 1.02s 752ms 1.02s
firstPaint 79ms 10ms 64ms 160ms 88ms 160ms
firstContentfulPaint 79ms 10ms 64ms 160ms 88ms 160ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: -63.35 KiB (-1.18%)
  • ui: 27.86 KiB (0.33%)
  • common: 2.51 MiB (23.02%)

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