Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/perps-controller/CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- **BREAKING:** Add `positionsSideFilter`, `positionsSortField`, and `positionsSortDirection` to the flat `ProLayoutPreferences` object (defaults `'all'`, `'positionValue'`, `'desc'`) so Pro Positions/Orders panel sort and side-filter preferences persist across markets and app restarts via the existing `getProLayoutPreferences()` / `setProLayoutPreferences(patch)` API; export `ProPositionsSideFilter`, `ProPositionsSortField`, and `ProPositionsSortDirection` ([#9838](https://github.com/MetaMask/core/pull/9838))
- Consumers that construct a full `ProLayoutPreferences` object (instead of using `DEFAULT_PRO_LAYOUT_PREFERENCES`, the getter, or the patch setter) must include the new fields. Persisted state that predates them remains valid at runtime because the getter/selector merge over defaults.
- **BREAKING:** Add strategy placement order types to `OrderType`: `twap`, `scale`, and `chase`, placeable through `placeOrder` alongside the existing `market`, `limit`, and trigger types ([#9832](https://github.com/MetaMask/core/pull/9832))
- `OrderType` is a wider union again, so — exactly as for the trigger types added in 11.0.0 — any consumer signature that narrows it back to a smaller set no longer accepts a value typed `OrderType`. Such signatures must widen to `OrderType` or narrow explicitly at the call site.
- A strategy placement expands one request into an execution schedule rather than a single resting order, so `OrderResult.orderId` carries a _handle_ — a venue TWAP id, or a client-generated group/session id — rather than an exchange order id. Its documentation says so; the individual exchange ids are in `childOrderIds`.
Expand Down
7 changes: 6 additions & 1 deletion packages/perps-controller/src/PerpsController.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -250,7 +250,12 @@ export {
DEFAULT_PERPS_MODE,
DEFAULT_PRO_LAYOUT_PREFERENCES,
} from './constants/perpsConfig.js';
export type { ProLayoutPreferences } from './constants/perpsConfig.js';
export type {
ProLayoutPreferences,
ProPositionsSideFilter,
ProPositionsSortDirection,
ProPositionsSortField,
} from './constants/perpsConfig.js';

/**
* State shape for PerpsController
Expand Down
32 changes: 30 additions & 2 deletions packages/perps-controller/src/constants/perpsConfig.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -486,19 +486,44 @@ export enum PerpsMode {
Pro = 'pro',
}

/**
* Side filter for the Pro Positions/Orders panel (long/short/all).
*
* Shared across markets via `proLayoutPreferences.positionsSideFilter`.
*/
export type ProPositionsSideFilter = 'all' | 'long' | 'short';

/**
* Sort fields available on the Pro Positions list.
*/
export type ProPositionsSortField =
| 'positionValue'
| 'unrealizedPnl'
| 'fundingRate';

/**
* Sort direction for the Pro Positions list.
*/
export type ProPositionsSortDirection = 'asc' | 'desc';

/**
* Pro-mode layout preferences (network-independent).
*
* Flat object that persists across markets (unlike the per-market
* `tradeConfigurations`). `chartExpanded` and the `*Position` fields are
* reserved for future container-position UI and are kept here now so no
* state-shape migration is needed when that UI ships.
* reserved for future container-position UI. `positionsSideFilter` /
* `positionsSortField` / `positionsSortDirection` back the Positions/Orders
* panel sort and side filter so they survive market navigation and app
* restarts.
*/
export type ProLayoutPreferences = {
orderBookExpanded: boolean;
chartExpanded: boolean;
orderBookPosition: 'left' | 'right';
orderFormPosition: 'left' | 'right';
positionsSideFilter: ProPositionsSideFilter;
positionsSortField: ProPositionsSortField;
positionsSortDirection: ProPositionsSortDirection;
};

/**
Expand All@@ -513,6 +538,9 @@ export const DEFAULT_PRO_LAYOUT_PREFERENCES: ProLayoutPreferences = {
chartExpanded: false,
orderBookPosition: 'left',
orderFormPosition: 'right',
positionsSideFilter: 'all',
positionsSortField: 'positionValue',
positionsSortDirection: 'desc',
};

/**
Expand Down
3 changes: 3 additions & 0 deletions packages/perps-controller/src/index.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -44,6 +44,9 @@ export type {
PerpsControllerActions,
PerpsControllerEvents,
ProLayoutPreferences,
ProPositionsSideFilter,
ProPositionsSortDirection,
ProPositionsSortField,
} from './PerpsController.js';
export type {
PerpsControllerCalculateFeesAction,
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -694,12 +694,15 @@ describe('PerpsController', () => {
});

describe('pro layout preferences', () => {
it('defaults to collapsed order book, collapsed chart, and reserved positions', () => {
it('defaults to collapsed order book, collapsed chart, reserved positions, and positions sort/filter defaults', () => {
expect(controller.getProLayoutPreferences()).toEqual({
orderBookExpanded: false,
chartExpanded: false,
orderBookPosition: 'left',
orderFormPosition: 'right',
positionsSideFilter: 'all',
positionsSortField: 'positionValue',
positionsSortDirection: 'desc',
});
});

Expand All@@ -711,19 +714,50 @@ describe('PerpsController', () => {
chartExpanded: false,
orderBookPosition: 'left',
orderFormPosition: 'right',
positionsSideFilter: 'all',
positionsSortField: 'positionValue',
positionsSortDirection: 'desc',
});
});

it('merges successive partial patches', () => {
controller.setProLayoutPreferences({ orderBookExpanded: true });
controller.setProLayoutPreferences({ orderBookPosition: 'right' });
controller.setProLayoutPreferences({ orderFormPosition: 'left' });
controller.setProLayoutPreferences({ positionsSideFilter: 'long' });
controller.setProLayoutPreferences({
positionsSortField: 'unrealizedPnl',
positionsSortDirection: 'asc',
});

expect(controller.getProLayoutPreferences()).toEqual({
orderBookExpanded: true,
chartExpanded: false,
orderBookPosition: 'right',
orderFormPosition: 'left',
positionsSideFilter: 'long',
positionsSortField: 'unrealizedPnl',
positionsSortDirection: 'asc',
});
});

it('updates sort field without clobbering sort direction', () => {
controller.setProLayoutPreferences({
positionsSortField: 'fundingRate',
positionsSortDirection: 'asc',
});
controller.setProLayoutPreferences({
positionsSortField: 'unrealizedPnl',
});

expect(controller.getProLayoutPreferences()).toEqual({
orderBookExpanded: false,
chartExpanded: false,
orderBookPosition: 'left',
orderFormPosition: 'right',
positionsSideFilter: 'all',
positionsSortField: 'unrealizedPnl',
positionsSortDirection: 'asc',
});
});

Expand All@@ -746,6 +780,9 @@ describe('PerpsController', () => {
chartExpanded: false,
orderBookPosition: 'left',
orderFormPosition: 'right',
positionsSideFilter: 'all',
positionsSortField: 'positionValue',
positionsSortDirection: 'desc',
});
});
});
Expand Down
6 changes: 6 additions & 0 deletions packages/perps-controller/tests/src/selectors.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -636,6 +636,9 @@ describe('PerpsController selectors', () => {
chartExpanded: false,
orderBookPosition: 'left',
orderFormPosition: 'right',
positionsSideFilter: 'all',
positionsSortField: 'positionValue',
positionsSortDirection: 'desc',
};

it('returns the pro-mode layout preferences', () => {
Expand All@@ -644,6 +647,9 @@ describe('PerpsController selectors', () => {
chartExpanded: true,
orderBookPosition: 'right' as const,
orderFormPosition: 'left' as const,
positionsSideFilter: 'long' as const,
positionsSortField: 'unrealizedPnl' as const,
positionsSortDirection: 'asc' as const,
};
const state = {
proLayoutPreferences,
Expand Down