Skip to content
18 changes: 18 additions & 0 deletions packages/perps-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- Bump `@metamask/account-tree-controller` from `^7.5.3` to `7.5.4` ([#9429](https://github.com/MetaMask/core/pull/9429))
- Gate HIP-3 markets to USDC collateral only, following HyperLiquid's USDH sunset (TAT-3304) ([#9530](https://github.com/MetaMask/core/pull/9530))
- Market discovery (`getMarkets`) now filters a HIP-3 DEX out entirely when its collateral token positively resolves to something other than USDC, so such a market can never be surfaced to trade, even via an allowlist entry naming the DEX.
- Placing an order on a non-USDC-collateral HIP-3 DEX now fails immediately with a new `UNSUPPORTED_COLLATERAL` error code instead of attempting the previous USDC→USDH auto-swap path.
- The collateral check fails open (treats the DEX as USDC-collateral) when the collateral token can't be resolved against spot metadata, so incomplete metadata doesn't spuriously block an otherwise-valid market.
- Removed the now-unreachable USDH auto-swap machinery this replaces (spot USDH/USDC balance lookups, the USDC→USDH spot swap, and the auto-swap orchestration).
- Subscribe to HyperLiquid's `fastAssetCtxs` WebSocket feed for mark/mid price updates, replacing `assetCtxs` as the latency-sensitive price source now that HyperLiquid has slowed the public `assetCtxs` feed cadence ([#9530](https://github.com/MetaMask/core/pull/9530))
- `assetCtxs` continues to populate funding, open interest, volume, and oracle price data, and no longer writes prices for any symbol `fastAssetCtxs` covers, so a slower `assetCtxs` batch tick can't overwrite a fresher `fastAssetCtxs` price; it remains the price source only for symbols outside `fastAssetCtxs`' coverage (e.g. HIP-3 DEX markets).
- `fastAssetCtxs` is a single global subscription (the HyperLiquid SDK exposes no per-DEX variant): the first message is a full snapshot keyed by coin, and later messages contain diffs for only the coins that changed. Coins without an active price subscriber are ignored.
- Established alongside the global `allMids` subscription, restored together on WebSocket reconnect, and torn down on `clearAll()`. Subscribe attempts use the same 3-attempt/500ms-backoff retry as `assetCtxs` for transient SDK errors.
- Report the effective leverage (`positionUSD / marginUSD`, rounded to 1 decimal place) on `PERPS_POSITION_CLOSE_TRANSACTION` analytics instead of the configured `leverage.value`, and populate it for every close including TP/SL triggers ([#9471](https://github.com/MetaMask/core/pull/9471))
- Emit an additional `partially_filled` `PERPS_TRADE_TRANSACTION` event with `order_size` (the final submitted size), `amount_filled`, and `remaining_amount` when an open trade fills for less than the size actually submitted to the exchange, mirroring the close path so partial fills are visible in analytics; classification uses the provider's post-normalization submitted size (returned as `OrderResult.submittedSize`) rather than the caller's pre-normalization `size`, so a complete fill of the normalized size is not misreported as partial; full fills are unchanged ([#9471](https://github.com/MetaMask/core/pull/9471))
- Widen the `TradeAction` type to include `flip_long_to_short` and `flip_short_to_long` (already forwarded verbatim at runtime), so clients no longer need casts when deriving flip actions ([#9471](https://github.com/MetaMask/core/pull/9471))
- Add `number_positions_closed` (the successful-close count) to the batch `PERPS_POSITION_CLOSE_TRANSACTION` summary event emitted by `closePositions`, which previously carried only status/completion_duration/bulk_action_id ([#9471](https://github.com/MetaMask/core/pull/9471))

### Removed

- **BREAKING:** Remove the `USDH_CONFIG` export, following HyperLiquid's USDH sunset (TAT-3304) ([#9530](https://github.com/MetaMask/core/pull/9530))
- This constant configured the now-removed USDC→USDH auto-swap path; consumers importing it should remove the reference, as USDH-collateral HIP-3 DEXs are no longer supported (see the collateral gating change above).

### Fixed

- Scope `#notifyAllPriceSubscribers` to the symbols that actually changed, instead of always fanning out to every price subscriber ([#9530](https://github.com/MetaMask/core/pull/9530))
- The `allMids` handler now tracks a per-symbol `changedSymbols` set (replacing the previous all-or-nothing `hasUpdates` boolean) and only notifies subscribers of symbols whose price changed.
- The `activeAssetCtx` handler now notifies only the subscribers of the symbol it just updated, instead of re-notifying every subscribed symbol on each tick.
- This eliminates redundant reference-equal `PriceUpdate` deliveries to list-view subscribers (e.g. market overview, watchlist) whenever an unrelated symbol's fast-stream price ticks.
- Emit the failed Perp Risk Management analytics event when `updateMargin` receives a non-throwing `{ success: false }` provider result, which previously lost the terminal event (only the thrown-error path emitted it); the event fires exactly once per operation ([#9471](https://github.com/MetaMask/core/pull/9471))
- Fix the CommonJS build inlining an absolute `file:` path in place of the `@nktkas/hyperliquid` specifier ([#9471](https://github.com/MetaMask/core/pull/9471))
- `dist/services/HyperLiquidClientService.cjs` and `dist/utils/standaloneInfoClient.cjs` in `9.2.1` emitted `require("file:///home/runner/work/hyperliquid/hyperliquid/src/mod.ts")` instead of `require("@nktkas/hyperliquid")`, breaking any CommonJS/Jest/bundler consumer with "Cannot find module".
Expand Down
18 changes: 0 additions & 18 deletions packages/perps-controller/src/constants/hyperLiquidConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -649,24 +649,6 @@ export const HIP3_MARGIN_CONFIG = {
RebalanceMinThreshold: 0.1,
} as const;

/**
* Configuration for USDH collateral handling on HIP-3 DEXs
* Per HyperLiquid docs: USDH DEXs pull collateral from spot balance automatically
*
* USDH is HyperLiquid's native stablecoin pegged 1:1 to USDC
*/
export const USDH_CONFIG = {
/** Token name for USDH collateral */
TokenName: 'USDH',

/**
* Maximum slippage for USDC→USDH spot swap in basis points
* USDH is pegged 1:1 to USDC so slippage should be minimal
* 10 bps (0.1%) provides small buffer for spread
*/
SwapSlippageBps: 10,
} as const;

// Progress bar constants
export const INITIAL_AMOUNT_UI_PROGRESS = 10;
export const WITHDRAWAL_PROGRESS_STAGES = [
Expand Down
1 change: 0 additions & 1 deletion packages/perps-controller/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,6 @@ export {
TESTNET_HIP3_CONFIG,
MAINNET_HIP3_CONFIG,
HIP3_MARGIN_CONFIG,
USDH_CONFIG,
INITIAL_AMOUNT_UI_PROGRESS,
WITHDRAWAL_PROGRESS_STAGES,
PROGRESS_BAR_COMPLETION_DELAY_MS,
Expand Down
2 changes: 2 additions & 0 deletions packages/perps-controller/src/perpsErrorCodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ export const PERPS_ERROR_CODES = {
SWAP_FAILED: 'SWAP_FAILED',
SPOT_PAIR_NOT_FOUND: 'SPOT_PAIR_NOT_FOUND',
PRICE_UNAVAILABLE: 'PRICE_UNAVAILABLE',
// Market/collateral errors
UNSUPPORTED_COLLATERAL: 'UNSUPPORTED_COLLATERAL', // DEX collateral token is not USDC (TAT-3304)
// Batch operation errors
BATCH_CANCEL_FAILED: 'BATCH_CANCEL_FAILED',
BATCH_CLOSE_FAILED: 'BATCH_CLOSE_FAILED',
Expand Down
Loading