Skip to content

feat(perps-controller): add pro-mode layout preferences and mode state - #9550

Merged
michalconsensys merged 5 commits into
mainfrom
feat/perps-controller-pro-mode-state-tat-3582
Jul 20, 2026
Merged

feat(perps-controller): add pro-mode layout preferences and mode state#9550
michalconsensys merged 5 commits into
mainfrom
feat/perps-controller-pro-mode-state-tat-3582

Conversation

@michalconsensys

@michalconsensysmichalconsensys commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Explanation

Before Perps Pro mode v1 UI work can start, @metamask/perps-controller needs two core-state additions. This PR is core-package preparation only — there are no mobile UI changes.

  • Pro-mode layout preferences. Adds a new top-level proLayoutPreferences field to PerpsControllerState (orderBookExpanded, chartExpanded, orderBookPosition, orderFormPosition). It follows the existing marketFilterPreferences pattern — a flat, network-independent, persisted object — rather than the per-market tradeConfigurations.orderBookGrouping pattern, because these preferences must survive across markets instead of resetting per symbol. All four fields get sensible defaults now (chartExpanded/positions are reserved for future container-position UI), so no state-shape migration is needed later. Access is via getProLayoutPreferences() and a patch-style setProLayoutPreferences(patch) setter (so future fields don't require new setter signatures), plus a selectProLayoutPreferences selector.
  • Lite/Pro mode field. Adds a PerpsMode enum (Lite/Pro) and a mode: PerpsMode field defaulting to PerpsMode.Lite, with a setPerpsMode(mode) method (mirroring the existing toggleTestnet write pattern) and a selectPerpsMode selector. This supersedes the "State:" bullet previously sketched in TAT-3551, which will consume this field/enum/setter instead of redefining them.

Both fields are persisted (persist: true) consistent with the controller's existing global-preference metadata (marketFilterPreferences/maxSlippageBps). The new methods are exposed as messenger actions via the existing method-action codegen (PerpsController-method-action-types.ts regenerated), and the enum, type, defaults, selectors, and action types are exported from the package entry point.

To keep the API ergonomic and robust for consumers:

  • The canonical PerpsMode enum, ProLayoutPreferences type, and the DEFAULT_PERPS_MODE / DEFAULT_PRO_LAYOUT_PREFERENCES constants live in the dependency-free constants/perpsConfig module (alongside SortOptionId/MARKET_SORTING_CONFIG) and are re-exported from the controller/package entry points. This preserves the one-way PerpsController → perpsConfig dependency (no cycle) and keeps selectors.ts free of heavy transitive imports.
  • getProLayoutPreferences(), selectProLayoutPreferences, and selectPerpsMode merge over / fall back to those defaults, so callers always receive a fully-populated preferences object and always default to PerpsMode.Lite — matching the fallback behavior of getMarketFilterPreferences/selectMarketFilterPreferences even when persisted state predates the new fields.

Bumping the @metamask/perps-controller dependency version in mobile is intentionally out of scope and tracked as a separate follow-up once this ships.

References

Changelog

@metamask/perps-controller

  • ADDED: proLayoutPreferences state field (orderBookExpanded, chartExpanded, orderBookPosition, orderFormPosition) with the exported ProLayoutPreferences type and DEFAULT_PRO_LAYOUT_PREFERENCES constant, getProLayoutPreferences()/setProLayoutPreferences(patch) methods (exposed as messenger actions), and a selectProLayoutPreferences selector; the getter and selector merge over defaults so callers always receive a fully-populated object.
  • ADDED: PerpsMode enum (Lite/Pro) and a persisted mode field (default PerpsMode.Lite) with the exported DEFAULT_PERPS_MODE constant, a setPerpsMode(mode) method (exposed as a messenger action), and a selectPerpsMode selector that falls back to the default mode.

Manual testing steps

Feature: Pro-mode layout preferences and mode state on PerpsControllerScenario: Default stateGiven a freshly constructed PerpsController
When I read getProLayoutPreferences() and state.mode
Then proLayoutPreferences is { orderBookExpanded: false, chartExpanded: true, orderBookPosition: 'left', orderFormPosition: 'right' }
And mode is PerpsMode.Lite
Scenario: Partial patch does not clobber other fieldsGiven a PerpsController with default proLayoutPreferences
When I call setProLayoutPreferences({ orderBookExpanded: true })
Then orderBookExpanded is true
And chartExpanded, orderBookPosition, and orderFormPosition retain their previous values
Scenario: Reading state that predates a field falls back to defaultsGiven persisted proLayoutPreferences that only contains orderBookExpanded
When I call getProLayoutPreferences() or selectProLayoutPreferences(state)
Then the missing fields are populated from DEFAULT_PRO_LAYOUT_PREFERENCES
Scenario: Setting and defaulting the interface modeGiven a PerpsController in Lite mode
When I call setPerpsMode(PerpsMode.Pro)
Then state.mode is PerpsMode.Pro
And selectPerpsMode(state) returns PerpsMode.Pro
And selectPerpsMode(stateWithoutMode) returns PerpsMode.Lite
Scenario: PersistenceGiven proLayoutPreferences and mode have persist metadata
When the app restarts and state is rehydrated
Then both values survive the restart

Screenshots/Recordings

N/A — no UI changes in this PR (core package only).

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
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Low Risk
Additive persisted preferences and API surface only; no trading, auth, or provider logic changes.

Overview
Adds persisted, network-independent Perps UI preferences to @metamask/perps-controller so Pro-mode mobile work can read/write shared state without redefining it.

Pro layout: New proLayoutPreferences on controller state (orderBookExpanded, chartExpanded, orderBookPosition, orderFormPosition), modeled like marketFilterPreferences (global, not per-market). getProLayoutPreferences() and patch-style setProLayoutPreferences(patch) merge with DEFAULT_PRO_LAYOUT_PREFERENCES; selectProLayoutPreferences does the same for reselect consumers.

Lite vs Pro:PerpsMode (lite/pro), default mode of Lite, setPerpsMode, and selectPerpsMode with default fallback.

Types, defaults, and the enum live in constants/perpsConfig and are re-exported from the controller and package entry; messenger action types are wired in PerpsController-method-action-types.ts. Both fields use persist: true in state metadata. Unit tests cover controller behavior and selectors.

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

Add core-package state preparation for Perps Pro mode v1:
- Add `proLayoutPreferences` state field (orderBookExpanded, chartExpanded,
orderBookPosition, orderFormPosition) with defaults, persisted metadata,
getProLayoutPreferences()/setProLayoutPreferences(patch) methods, and a
selectProLayoutPreferences selector.
- Add `PerpsMode` enum (Lite/Pro) and persisted `mode` field defaulting to
Lite, with a setPerpsMode(mode) method and selectPerpsMode selector.
- Expose new methods as messenger actions and regenerate method-action-types.

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit deee807. Configure here.

Comment threadpackages/perps-controller/src/selectors.ts Outdated
… them
Move PerpsMode/ProLayoutPreferences and their defaults into the
dependency-free perpsConfig module and export DEFAULT_PERPS_MODE /
DEFAULT_PRO_LAYOUT_PREFERENCES. getProLayoutPreferences() and the
selectProLayoutPreferences/selectPerpsMode selectors now merge over these
defaults so callers always receive a fully-populated object and default to
PerpsMode.Lite, matching the marketFilterPreferences pattern.
Comment threadpackages/perps-controller/src/constants/perpsConfig.ts Outdated
@michalconsensys
michalconsensys added this pull request to the merge queueJul 20, 2026
Merged via the queue into main with commit e4317feJul 20, 2026
429 checks passed
@michalconsensys
michalconsensys deleted the feat/perps-controller-pro-mode-state-tat-3582 branch July 20, 2026 16:33
Sign up for freeto 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

@michalconsensys@aganglada