@metamask-previews/perps-controller 19.0.0-preview-260a6054e → 19.0.0-preview-136f5f1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/CHANGELOG.md +139 -1
  2. package/README.md +595 -5
  3. package/dist/PerpsController-method-action-types.d.ts +137 -14
  4. package/dist/PerpsController-method-action-types.d.ts.map +1 -1
  5. package/dist/PerpsController-method-action-types.js.map +1 -1
  6. package/dist/PerpsController.d.ts +115 -14
  7. package/dist/PerpsController.d.ts.map +1 -1
  8. package/dist/PerpsController.js +594 -41
  9. package/dist/PerpsController.js.map +1 -1
  10. package/dist/aggregation/SubscriptionMultiplexer.d.ts +7 -3
  11. package/dist/aggregation/SubscriptionMultiplexer.d.ts.map +1 -1
  12. package/dist/aggregation/SubscriptionMultiplexer.js +4 -2
  13. package/dist/aggregation/SubscriptionMultiplexer.js.map +1 -1
  14. package/dist/constants/hyperLiquidConfig.d.ts +15 -1
  15. package/dist/constants/hyperLiquidConfig.d.ts.map +1 -1
  16. package/dist/constants/hyperLiquidConfig.js +16 -2
  17. package/dist/constants/hyperLiquidConfig.js.map +1 -1
  18. package/dist/constants/lighterConfig.d.ts +61 -1
  19. package/dist/constants/lighterConfig.d.ts.map +1 -1
  20. package/dist/constants/lighterConfig.js +62 -1
  21. package/dist/constants/lighterConfig.js.map +1 -1
  22. package/dist/index.d.ts +3 -3
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js.map +1 -1
  25. package/dist/perpsErrorCodes.d.ts +1 -0
  26. package/dist/perpsErrorCodes.d.ts.map +1 -1
  27. package/dist/perpsErrorCodes.js +1 -0
  28. package/dist/perpsErrorCodes.js.map +1 -1
  29. package/dist/providers/AggregatedPerpsProvider.d.ts +69 -4
  30. package/dist/providers/AggregatedPerpsProvider.d.ts.map +1 -1
  31. package/dist/providers/AggregatedPerpsProvider.js +176 -7
  32. package/dist/providers/AggregatedPerpsProvider.js.map +1 -1
  33. package/dist/providers/HyperLiquidProvider.d.ts +5 -5
  34. package/dist/providers/HyperLiquidProvider.d.ts.map +1 -1
  35. package/dist/providers/HyperLiquidProvider.js +826 -225
  36. package/dist/providers/HyperLiquidProvider.js.map +1 -1
  37. package/dist/providers/LighterProvider.d.ts +149 -57
  38. package/dist/providers/LighterProvider.d.ts.map +1 -1
  39. package/dist/providers/LighterProvider.js +8232 -1089
  40. package/dist/providers/LighterProvider.js.map +1 -1
  41. package/dist/services/DataLakeService.d.ts.map +1 -1
  42. package/dist/services/DataLakeService.js +20 -2
  43. package/dist/services/DataLakeService.js.map +1 -1
  44. package/dist/services/HyperLiquidClientService.d.ts +20 -2
  45. package/dist/services/HyperLiquidClientService.d.ts.map +1 -1
  46. package/dist/services/HyperLiquidClientService.js +58 -4
  47. package/dist/services/HyperLiquidClientService.js.map +1 -1
  48. package/dist/services/HyperLiquidSubscriptionService.d.ts +7 -1
  49. package/dist/services/HyperLiquidSubscriptionService.d.ts.map +1 -1
  50. package/dist/services/HyperLiquidSubscriptionService.js.map +1 -1
  51. package/dist/services/HyperLiquidWalletService.d.ts +7 -3
  52. package/dist/services/HyperLiquidWalletService.d.ts.map +1 -1
  53. package/dist/services/HyperLiquidWalletService.js +42 -19
  54. package/dist/services/HyperLiquidWalletService.js.map +1 -1
  55. package/dist/services/LighterChaseService.d.ts +578 -0
  56. package/dist/services/LighterChaseService.d.ts.map +1 -0
  57. package/dist/services/LighterChaseService.js +1117 -0
  58. package/dist/services/LighterChaseService.js.map +1 -0
  59. package/dist/services/LighterClientService.d.ts +30 -2
  60. package/dist/services/LighterClientService.d.ts.map +1 -1
  61. package/dist/services/LighterClientService.js +151 -10
  62. package/dist/services/LighterClientService.js.map +1 -1
  63. package/dist/services/LighterTwapService.d.ts +288 -0
  64. package/dist/services/LighterTwapService.d.ts.map +1 -0
  65. package/dist/services/LighterTwapService.js +511 -0
  66. package/dist/services/LighterTwapService.js.map +1 -0
  67. package/dist/services/RewardsIntegrationService.d.ts.map +1 -1
  68. package/dist/services/RewardsIntegrationService.js +50 -41
  69. package/dist/services/RewardsIntegrationService.js.map +1 -1
  70. package/dist/services/TradingService.d.ts.map +1 -1
  71. package/dist/services/TradingService.js +23 -2
  72. package/dist/services/TradingService.js.map +1 -1
  73. package/dist/services/lighterDispatchIdentity.d.ts +28 -0
  74. package/dist/services/lighterDispatchIdentity.d.ts.map +1 -0
  75. package/dist/services/lighterDispatchIdentity.js +43 -0
  76. package/dist/services/lighterDispatchIdentity.js.map +1 -0
  77. package/dist/services/missingActionHandler.d.ts +17 -0
  78. package/dist/services/missingActionHandler.d.ts.map +1 -0
  79. package/dist/services/missingActionHandler.js +29 -0
  80. package/dist/services/missingActionHandler.js.map +1 -0
  81. package/dist/types/index.d.ts +436 -27
  82. package/dist/types/index.d.ts.map +1 -1
  83. package/dist/types/index.js.map +1 -1
  84. package/dist/types/lighter-types.d.ts +94 -1
  85. package/dist/types/lighter-types.d.ts.map +1 -1
  86. package/dist/types/lighter-types.js.map +1 -1
  87. package/dist/utils/guardedHyperLiquidClient.d.ts +13 -0
  88. package/dist/utils/guardedHyperLiquidClient.d.ts.map +1 -0
  89. package/dist/utils/guardedHyperLiquidClient.js +38 -0
  90. package/dist/utils/guardedHyperLiquidClient.js.map +1 -0
  91. package/dist/utils/lighterAdapter.d.ts +7 -0
  92. package/dist/utils/lighterAdapter.d.ts.map +1 -1
  93. package/dist/utils/lighterAdapter.js +4 -4
  94. package/dist/utils/lighterAdapter.js.map +1 -1
  95. package/dist/utils/lighterAttachedOrders.d.ts +53 -0
  96. package/dist/utils/lighterAttachedOrders.d.ts.map +1 -0
  97. package/dist/utils/lighterAttachedOrders.js +212 -0
  98. package/dist/utils/lighterAttachedOrders.js.map +1 -0
  99. package/dist/utils/lighterChase.d.ts +75 -0
  100. package/dist/utils/lighterChase.d.ts.map +1 -0
  101. package/dist/utils/lighterChase.js +207 -0
  102. package/dist/utils/lighterChase.js.map +1 -0
  103. package/dist/utils/lighterLosslessJson.d.ts +11 -0
  104. package/dist/utils/lighterLosslessJson.d.ts.map +1 -0
  105. package/dist/utils/lighterLosslessJson.js +136 -0
  106. package/dist/utils/lighterLosslessJson.js.map +1 -0
  107. package/dist/utils/lighterNativeEdit.d.ts +238 -0
  108. package/dist/utils/lighterNativeEdit.d.ts.map +1 -0
  109. package/dist/utils/lighterNativeEdit.js +573 -0
  110. package/dist/utils/lighterNativeEdit.js.map +1 -0
  111. package/dist/utils/lighterScaleOrders.d.ts +106 -0
  112. package/dist/utils/lighterScaleOrders.d.ts.map +1 -0
  113. package/dist/utils/lighterScaleOrders.js +496 -0
  114. package/dist/utils/lighterScaleOrders.js.map +1 -0
  115. package/dist/utils/lighterTwap.d.ts +42 -0
  116. package/dist/utils/lighterTwap.d.ts.map +1 -0
  117. package/dist/utils/lighterTwap.js +79 -0
  118. package/dist/utils/lighterTwap.js.map +1 -0
  119. package/dist/utils/lighterTwapReconciliation.d.ts +35 -0
  120. package/dist/utils/lighterTwapReconciliation.d.ts.map +1 -0
  121. package/dist/utils/lighterTwapReconciliation.js +237 -0
  122. package/dist/utils/lighterTwapReconciliation.js.map +1 -0
  123. package/dist/utils/positionProtection.d.ts +12 -0
  124. package/dist/utils/positionProtection.d.ts.map +1 -0
  125. package/dist/utils/positionProtection.js +29 -0
  126. package/dist/utils/positionProtection.js.map +1 -0
  127. package/dist/utils/subscriptionFeeWaiver.d.ts +8 -6
  128. package/dist/utils/subscriptionFeeWaiver.d.ts.map +1 -1
  129. package/dist/utils/subscriptionFeeWaiver.js +14 -6
  130. package/dist/utils/subscriptionFeeWaiver.js.map +1 -1
  131. package/package.json +6 -6
package/CHANGELOG.md CHANGED
@@ -7,13 +7,151 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Added
11
+
12
+ - Add `reconcileChaseOrderCancellation` to the controller, messenger and optional provider contract. Lighter reconciles an already attempted cancellation under its exact original owner, handle, child and transaction identity with local settlement writes but no new financial dispatch, even if acknowledgement becomes failure while the child remains open. Missing, malformed or stale original ownership rejects; unknown outcomes remain unresolved. Aggregated mode routes only the explicit provider and unsupported providers never fall back to ordinary cancellation ([#10638](https://github.com/MetaMask/core/pull/10638)).
13
+
14
+ - Export `LIGHTER_SCALE_SETTLEMENT_WINDOW_MS`, `LIGHTER_SCALE_SETTLEMENT_POLL_MS`, `LIGHTER_CHASE_CANCEL_SETTLEMENT_WINDOW_MS` and `LIGHTER_CHASE_CANCEL_SETTLEMENT_POLL_MS` through the `constants` and `constants/lighterConfig` package entrypoints for shared settlement policy ([#10638](https://github.com/MetaMask/core/pull/10638)).
15
+
16
+ - Support explicit independent Lighter partial TP/SL pairs, including captured full-position siblings, through cancellation-first durable per-leg dispatch. Expose supported pair linkages and role-bound protection receipts without changing native OCO defaults ([#10638](https://github.com/MetaMask/core/pull/10638)).
17
+
18
+ - Support explicit Lighter `marginMode` selections with required leverage, authoritative position/order locks and exact mode transaction execution before dependent exposure. Ready active perpetual capabilities report both native modes ([#10638](https://github.com/MetaMask/core/pull/10638)).
19
+ - Add `getChaseOrderOwnership({handle, providerId, owner?})` to the controller, messenger and optional provider contract. Lighter returns validated durable local history for every exact child under its original wallet/network/account/key owner, including superseded and unresolved attempts, without signing, transport, automatic continuation or durable writes. Missing handles and owner mismatches return unavailable; corrupt storage rejects. Aggregated mode routes one explicit provider; providers without durable history return unsupported. Existing Chase and disabled TWAP behavior remain unchanged ([#10638](https://github.com/MetaMask/core/pull/10638)).
20
+
21
+ - Add the default-off testnet-only `chaseTestnetProbe` constructor option to `LighterProvider` for bounded, durable native Chase cancel/replace. Production strategy capabilities remain unavailable ([#10638](https://github.com/MetaMask/core/pull/10638)).
22
+ - Implement Lighter `getChaseOrders`, `suspendChaseOrders` and `cancelOrder` with `orderType: 'chase'`. Unbound or recordless absent accounts return empty management state; absent venue discovery retains remembered wallet/network cleanup obligations without signing authority. Confirmed cancel-on-stop reports `canceled`; native records retain the first `stopReason` and uncertain cleanup remains `termination_pending` ([#10638](https://github.com/MetaMask/core/pull/10638)).
23
+ - Expose `LIGHTER_MAX_CLIENT_ORDER_INDEX`, `LIGHTER_NATIVE_PROBE_MAX_NOTIONAL` and `LIGHTER_CHASE_*` bounds/defaults through `constants/lighterConfig` for shared native identity and Chase policy validation ([#10638](https://github.com/MetaMask/core/pull/10638)).
24
+ - Expose `utils/lighterChase.readLighterChaseQuote`, `reconcileLighterChaseChild` and `identifyLighterChaseChild` for native quotes, exact fill accounting and immutable child validation ([#10638](https://github.com/MetaMask/core/pull/10638)).
25
+ - Reconcile failed or expired never-landed Chase transactions without releasing uncertain ownership. Keep accepted orders active through indexer lag, use absolute duration deadlines, and interrupt replacements synchronously when cancellation is requested. Retain TWAP exclusion when expired-placement order evidence is incomplete. Fence starts waiting on preparation, signer readiness or the account mutex when suspension occurs; preserve duration cleanup after a wrong-symbol cancellation. Report confirmed explicit cleanup independently of an earlier failed stop cause, and keep basis-point conversion independent of policy limits ([#10638](https://github.com/MetaMask/core/pull/10638)).
26
+
27
+ - Support native Lighter same-order price and size edits for verified unfilled ordinary perpetual limits. Add `OrderResult.orderEdit` and `OrderEditObservation` for durable pending, settled, failed and terminal outcomes; acceptance alone is pending. Export the seven-argument `LighterSignModifyOrderWireParams` bridge contract. Trigger, strategy and protection children remain unsupported ([#10638](https://github.com/MetaMask/core/pull/10638)).
28
+ - Preserve attached exact-failure settlement across review and nonce-ledger retries. Explicit attached review can settle fresh complete exact-leg acceptance into an acknowledgeable recovered outcome when the transaction hash is absent and its nonce advanced; saved IDs alone remain insufficient. Bound history by preparation time and page/row budgets, reporting optional `AttachedOrderGroup.historyStatus` for incomplete reviews ([#10638](https://github.com/MetaMask/core/pull/10638)).
29
+ - Expose `OrderResult.attachedOrderGroup`, `AttachedOrderGroup`, `ReadyPerpsOrderCapabilities.attachedTpsl`, optional provider `getAttachedOrderGroups`/`reviewAttachedOrderGroups`, and controller messenger actions `PerpsControllerGetAttachedOrderGroupsAction`/`PerpsControllerReviewAttachedOrderGroupsAction`. The group submission union includes `completed` for exactly correlated terminal legs ([#10638](https://github.com/MetaMask/core/pull/10638)).
30
+ - Export `LIGHTER_MAX_WIRE_PRICE`, `LIGHTER_GROUPING_ONE_TRIGGERS_THE_OTHER` and `LIGHTER_GROUPING_ONE_TRIGGERS_OCO` through `constants` and `constants/lighterConfig`. The public `utils/lighterAttachedOrders` subpath exposes `LighterAttachedGroup`, `parseLighterAttachedGroups`, `correlateLighterAttachedOrders`, `toAttachedOrderGroup`, `LIGHTER_ATTACHED_MAX_GROUPS` and `LIGHTER_ATTACHED_HANDLE_PREFIX` ([#10638](https://github.com/MetaMask/core/pull/10638)).
31
+ - Add optional `OrderParams.expectedScaleLadder` and exported `ExpectedScaleLadder` to bind Lighter Scale placement to approved prices, quantities, totals, minimums and size precision. Refuse stale or malformed constraints with `ORDER_SCALE_PREVIEW_STALE` before writes. Snapshot caller intent before readiness and fee waits, and recheck the complete normalized ladder and venue precision/minimums before signing and final dispatch, preserving accepted child receipts when later metadata changes. Omission preserves unbound placement-time normalization; other providers refuse the constraint ([#10638](https://github.com/MetaMask/core/pull/10638)).
32
+
33
+ - Add optional `GetScalePriceLadderParams.sizing` for exact base size or bounded quote budget and optional skew. Lighter returns venue-valid `PerpsScalePriceLadder.sizingPreview` quantities, totals and maker minimums without account or signer setup; unsupported providers leave the preview absent ([#10638](https://github.com/MetaMask/core/pull/10638)).
34
+ - Add durable Lighter Scale ladders with exact-grid preview, aggregate exposure checks, uncertain-child retention and exact group cancellation ([#10638](https://github.com/MetaMask/core/pull/10638)).
35
+ - Add optional `getScaleOrderGroups` and `reviewScaleOrderGroups` provider methods and controller actions, with the exported `ScaleOrderGroup` inventory type ([#10638](https://github.com/MetaMask/core/pull/10638)).
36
+ - Attribute real Lighter Scale order rows through `strategyGroupId`; keep rows that contradict durably rejected children unattributed and retain ordinary order reads when optional attribution is unavailable ([#10638](https://github.com/MetaMask/core/pull/10638)).
37
+ - Reconcile Scale dispatch proof across review, expiry and nonce recovery, and poll bounded venue visibility after placement and cancellation ([#10638](https://github.com/MetaMask/core/pull/10638)).
38
+ - Add default-off bounded Lighter Chase probe coordination with durable child ownership, exact fill-aware cancel/replace, public management views and explicit termination; TWAP and production Chase capabilities remain unavailable. Expose `utils/lighterChase.readLighterChaseQuote`, `reconcileLighterChaseChild` and `identifyLighterChaseChild` for native quote, fill and immutable child validation ([#10638](https://github.com/MetaMask/core/pull/10638)).
39
+
40
+ - Support ordinary Lighter post-only limit placement with native TIF 2, fresh crossing checks and durable dispatch recovery; TWAP and production Chase capabilities remain unavailable ([#10638](https://github.com/MetaMask/core/pull/10638)).
41
+
42
+ - Add the default-off `nativeTwapTestnetProbe` constructor option for bounded Lighter native TWAP validation with durable account/network/slot ownership. Unresolved TWAP and Chase probes exclude further probe placement on the same account ([#10638](https://github.com/MetaMask/core/pull/10638)).
43
+ - Add provider-only `getNativeTwapObservations()` for exact parent/client-ID reads and complete child-trade reconciliation. Cancellation acknowledgment retains ownership pending independently verified terminal mapping ([#10638](https://github.com/MetaMask/core/pull/10638)).
44
+ - Expose `utils/lighterTwapReconciliation.reconcileLighterTwapObservation` and `identifyLighterTwapParent` for exact native reconciliation and immutable cancellation ownership. Exact cancellation remains available when mutable fill history is unavailable ([#10638](https://github.com/MetaMask/core/pull/10638)).
45
+ - Release provably unsent native probe transactions and expired, never-landed TWAP transactions while retaining attempted and uncertain cleanup obligations. Validate optional native trade string IDs against numeric counterparts ([#10638](https://github.com/MetaMask/core/pull/10638)).
46
+
47
+ - Add `utils/lighterTwap.prepareLighterTwapOrder` for exact native TWAP wire preparation only. Keep Lighter TWAP unavailable pending authoritative parent-fill and terminal-cancellation semantics. Reject unsupported management reads and TWAP cancellation before signer setup rather than reporting an empty inventory or treating generic cancel acknowledgment as schedule termination ([#10638](https://github.com/MetaMask/core/pull/10638)).
48
+
49
+ - Support fixed partial Lighter position protection with single triggers or equal-quantity OCO pairs, exact downward quantity normalization and cancellation-first replacement. Expose optional `positionTpsl.defaultCoverage`, `positionTpsl.partialCoverage` and `PerpsPendingManualRecovery.partialIntent`. Lighter reports snapshot defaults, equal-quantity OCO and explicit current-position recovery; `HYPERLIQUID_ORDER_CAPABILITIES` reports dynamic defaults, independent partial pairs and provider-default recovery. Release proven-unsent partial attempts without removing prior protection or unresolved dispatched obligations ([#10638](https://github.com/MetaMask/core/pull/10638)).
50
+ - Expose `LIGHTER_RECOVERY_ACCOUNT_INDEX_LIMIT` through `constants` and `constants/lighterConfig` to bound the durable wallet/network recovery account index. Record verified account identity before venue mutation so pending dispatches remain discoverable after account absence ([#10638](https://github.com/MetaMask/core/pull/10638)).
51
+ - Add native Lighter parent orders with attached TP/SL through OTO and OTOCO groups, durable parent/child identities, local `getAttachedOrderGroups`, explicit read-only `reviewAttachedOrderGroups`, and exact group cancellation. Preserve local groups for confirmed absent and known Premium accounts. Explicit partial child sizes and position linkage remain unsupported; activation, partial-fill coverage and automatic cancellation guarantees remain unverified. Persist exact terminal non-acceptance before nonce evidence retirement. Dispatched intent requires fresh absent transaction/order evidence after expiry, or exact transaction failure, before abandonment. Review traverses bounded history, batches reads per market, skips unchanged writes and reclaims only proven terminal groups ([#10638](https://github.com/MetaMask/core/pull/10638)).
52
+ - Add strict provider-scoped `reviewRecoveryVenue` and explicit `resolveRecoveryProtection` controller/provider capabilities, including opaque manual-obligation identities, original-slot reconciliation and durable source-to-successor protection settlement. Review uses matching registered read authority without registration or financial writes; unsupported providers report a distinct capability result. Manual and dispatch rows expose optional provider, wallet and network metadata; aggregate rows carry their owning provider. Ordinary protection changes refuse pending selected transfers across trading slots. Pending or unknown transaction statuses remain unresolved even when order books already match; executed (2), pending-final (3) with matching books, or definitive failure resolves them ([#10638](https://github.com/MetaMask/core/pull/10638)).
53
+ - Add optional `reconcileRecoveredDispatches` provider capability and controller action for explicit non-financial venue checks with local persistence. Lighter checks owner-null dispatches across trading slots without signing, retrying or acknowledging outcomes; unsupported providers return their local listing. Reject account, network or provider changes while readiness, reconciliation or fallback listing completes; propagate provider failures unchanged ([#10638](https://github.com/MetaMask/core/pull/10638)).
54
+ - Expose `utils/positionProtection.assertExpectedPosition` and `utils/guardedHyperLiquidClient.createGuardedHyperLiquidClient` through the existing public wildcard exports for position snapshot validation and operation-local signed-dispatch guards ([#10638](https://github.com/MetaMask/core/pull/10638))
55
+ - Add optional `UpdatePositionTPSLParams.expectedPosition` signed-size and entry-price preconditions. Lighter and HyperLiquid reject stale or invalid protection preconditions with `TPSL_UPDATE_FAILED` before setup and recheck before writes ([#10638](https://github.com/MetaMask/core/pull/10638))
56
+ - Report `positionTpsl` precondition support, receipt identity guarantees and native TP/SL execution types in ready order capabilities ([#10638](https://github.com/MetaMask/core/pull/10638))
57
+ - Return exact `OrderResult.childOrderIds` receipts for settled Lighter full-position TP/SL updates and HyperLiquid updates with complete response- or signed-client-ID-correlated IDs. Removals return an empty receipt; IDs may already be terminal and do not imply resting protection. HyperLiquid position-protection client IDs reserve the subscription program layout; only the fee-reduction flag, not the marker alone, attributes a discount ([#10638](https://github.com/MetaMask/core/pull/10638))
58
+ - Support native Lighter standalone `stop_market`, `stop_limit`, `take_profit_market` and `take_profit_limit` placement and validation for active perpetual markets, preserving trigger levels, execution protection and reduce-only quantities. Report the supported types through `getOrderCapabilities` and expose the fixed venue grid as optional `MarketInfo.priceDecimals` ([#10638](https://github.com/MetaMask/core/pull/10638))
59
+ - Export `LIGHTER_ORDER_TYPE_STOP_LOSS_LIMIT` and `LIGHTER_ORDER_TYPE_TAKE_PROFIT_LIMIT` from both `constants` and `constants/lighterConfig` ([#10638](https://github.com/MetaMask/core/pull/10638))
60
+ - Export Lighter trading-slot bounds/count, registration visibility timeout/poll/attempt cap and fill replay capacity from both `constants` and `constants/lighterConfig`: `LIGHTER_MIN_TRADING_API_KEY_INDEX`, `LIGHTER_MAX_TRADING_API_KEY_INDEX`, `LIGHTER_TRADING_API_KEY_COUNT`, `LIGHTER_KEY_REGISTRATION_VISIBILITY_TIMEOUT_MS`, `LIGHTER_KEY_REGISTRATION_VISIBILITY_POLL_MS`, `LIGHTER_KEY_REGISTRATION_VISIBILITY_MAX_ATTEMPTS`, and `LIGHTER_FILL_REPLAY_LIMIT` ([#10618](https://github.com/MetaMask/core/pull/10618))
61
+ - Add optional `supportedTriggerOrderTypes` to ready order capabilities and the public `HYPERLIQUID_ORDER_CAPABILITIES` constant. Hyperliquid reports its implemented standalone stop/take-profit placements; missing declarations mean unsupported, independently of strategy and attached TP/SL support ([#10638](https://github.com/MetaMask/core/pull/10638))
62
+ - Add optional `LighterSignerBridge.getRecoverableKeyIndices` and `getStoredKeyIndices` discovery, and an optional `walletAddress` binding on client creation and discovery. Hosts can restore wallet-derived trading keys; Core verifies registered public keys before reuse and skips unrelated candidate ledgers without changing them ([#10618](https://github.com/MetaMask/core/pull/10618))
63
+ - Add optional `onError` callbacks and delivery provider identifiers to order and fill subscriptions, including empty aggregated updates, so clients can identify the provider delivering an update. Lighter currently reports detectable subscription setup failures; other providers may not invoke `onError` ([#10618](https://github.com/MetaMask/core/pull/10618))
64
+ - Add optional `PerpsAccountSigner.getChainId`. When set, HyperLiquid user-signed actions (builder fee approval, withdrawals, transfers) are signed for the chain it returns instead of chain 1, so a wallet that only signs for its connected chain does not switch chains ([#10643](https://github.com/MetaMask/core/pull/10643))
65
+ - Add optional `feeSource` to `FeeCalculationResult`, reporting which fee source (`default`, `rewards` or `subscription`) won the fee resolution the quoted MetaMask fee was priced from, so clients can attribute the discount shown in a fee preview without re-deriving it from the rates ([#10650](https://github.com/MetaMask/core/pull/10650))
66
+ - Absent when the quote was not re-priced from a fee resolution, for example a placement that carries no MetaMask builder fee
67
+ - `rewards` can carry a 0% discount, so check `metamaskFeeRate` before presenting it as a reduction
68
+ - Add optional `metamaskFeeDiscountBips` and `undiscountedMetamaskFeeRate` to `FeeCalculationResult`, so clients can show the original MetaMask fee next to the discounted one without the default builder fee constant ([#10683](https://github.com/MetaMask/core/pull/10683))
69
+ - `metamaskFeeDiscountBips` is the discount the winning fee source applied, in basis points off the default builder fee; `undiscountedMetamaskFeeRate` is the MetaMask fee rate before it
70
+ - `metamaskFeeDiscountBips` is `0` when no reduction applied: when `default` won, or when `rewards` won with a 0% discount. A `feeSource` other than `default` does not imply a discount
71
+ - `metamaskFeeRate` is already discounted; do not apply `metamaskFeeDiscountBips` to it again
72
+ - Absent whenever `feeSource` is absent, for example a placement that carries no MetaMask builder fee
73
+
10
74
  ### Changed
11
75
 
76
+ - **BREAKING:** Lighter `placeOrder` and `validateOrder` now accept supported native attached TP/SL instead of refusing all attachments; omitted `tpslLinkage` defaults to `order`. Mobile and Extension must gate forwarding on `attachedTpsl` and their rollout policy. Native lifecycle verification remains pending; client adoption is not included ([#10638](https://github.com/MetaMask/core/pull/10638)).
77
+ - **BREAKING:** Grouped Lighter signer calls require grouping/count `1/2` or `2/2` with two orders, or `3/3` with three orders. Update `LighterSignCreateGroupedOrdersWireParams` and `LighterWasmCall<'_signCreateGroupedOrders'>` callers to these tuple unions; each order retains its ten-field wire tuple ([#10638](https://github.com/MetaMask/core/pull/10638)).
78
+ - **BREAKING:** Add `canceled` to `ScaleOrderChild.state` for accepted children canceled after placement. Consumers exhaustively matching this union must handle the new state. Scale receipts distinguish submitted, accepted and known filled exposure ([#10638](https://github.com/MetaMask/core/pull/10638)).
79
+ - **BREAKING:** Add `order_market_unsupported` to `DirectProviderOrderCapabilitiesUnavailableReason` and `OrderCapabilitiesUnavailableReason` for known markets that are inactive or not perpetual and cannot accept native triggers. Consumers exhaustively matching these unions must include the new reason; Scale price-ladder reasons are unchanged ([#10638](https://github.com/MetaMask/core/pull/10638))
80
+ - **BREAKING:** Refuse stray `triggerPrice` on Lighter basic market and limit orders with `ORDER_TRIGGER_PRICE_NOT_SUPPORTED` rather than silently ignoring it. Omit the field or select an explicit trigger order type ([#10638](https://github.com/MetaMask/core/pull/10638))
81
+ - **BREAKING:** Lighter position TP/SL replacement and removal preserve independent partial triggers and trigger limits. Legacy unrecorded trigger-market orders count as protection only on the closing side with exactly the in-lock position quantity and a known restorable time-in-force. Cancel independent orders and pre-upgrade protection whose quantity no longer matches explicitly ([#10638](https://github.com/MetaMask/core/pull/10638))
12
82
  - **BREAKING:** `OrderFill.pnl` is optional when the venue omits realized PnL. Consumers must preserve missing amounts as unknown when aggregating or displaying fills; only a reported `'0'` is zero ([#10605](https://github.com/MetaMask/core/pull/10605))
83
+ - Treat `lighterAuthConfig.apiKeyIndex` as a preferred slot when key discovery is available; `getRecoverableKeyIndices` takes precedence over `getStoredKeyIndices` ([#10618](https://github.com/MetaMask/core/pull/10618))
84
+ - List local recovery obligations across all trading slots with optional `PerpsRecoveredDispatch.apiKeyIndex` and opaque wallet/network/account/slot-bound IDs. Raw pending dispatches have `acknowledgeable:false`; only resolved stored outcomes can be acknowledged, and legacy IDs must be unique across the account ([#10618](https://github.com/MetaMask/core/pull/10618))
85
+ - Wait for in-flight key selection in recovery readers and retain unfinished TP/SL journals after failed signer initialization ([#10618](https://github.com/MetaMask/core/pull/10618))
86
+ - `HyperLiquidProvider.getExchangeClient` initializes the provider's SDK clients before returning the exchange client, so it signs L1 actions with the provider's agent ([#10643](https://github.com/MetaMask/core/pull/10643))
13
87
 
14
88
  ### Fixed
15
89
 
16
- - Accept Lighter trades that omit position-sign flags, preserve omitted account PnL as unknown, and reject known reductions without realized PnL. Retain side-only fill directions when lifecycle context is ambiguous ([#10605](https://github.com/MetaMask/core/pull/10605))
90
+ - Retain each Lighter Scale child cancellation identity and acknowledgement before transport completion so unresolved requests and provider restarts reconcile without signing or sending again. Permit explicit retry only after exact failure or expired, venue-confirmed never-landed evidence; legacy acknowledgement omissions remain uncertain. Reobserve exact active/history overlaps while preserving strict identity and cumulative-fill checks ([#10638](https://github.com/MetaMask/core/pull/10638)).
91
+
92
+ - Give Lighter Scale placement a dedicated ten-second visibility window and share one ten-second deadline across a group's exact child cancellations ([#10638](https://github.com/MetaMask/core/pull/10638)).
93
+
94
+ - Wait for exact Lighter Chase cancellation settlement and reconcile retained attempts without signing or sending again, preserving session authority and cumulative fill evidence. Save transport acceptance and exact nonfailed transaction observations under their original owner before nonce retirement, including across session changes. Keep accepted placement and cancellation journals readable when completion reads, parsing or matching fail. Keep conflicting and legacy unknown evidence unresolved; expiry release also requires explicit unacknowledged evidence, a fresh unconsumed slot nonce and exact owned order evidence ([#10638](https://github.com/MetaMask/core/pull/10638)).
95
+
96
+ - Recognize and cancel exact Lighter Chase children when the venue order nonce differs from the signed transaction nonce, preserving transaction and order ownership checks ([#10638](https://github.com/MetaMask/core/pull/10638)).
97
+
98
+ - Wait for bounded exact transaction and order settlement after an accepted Lighter native edit, without signing or sending the edit again. Preserve pending outcomes when visibility does not settle within the polling bound ([#10638](https://github.com/MetaMask/core/pull/10638)).
99
+
100
+ - Wait for bounded exact transaction execution reads before completing Lighter margin mode and collateral updates, without resubmitting pending transactions ([#10638](https://github.com/MetaMask/core/pull/10638)).
101
+
102
+ - Retire the exact HyperLiquid agent signature when a post-signing guard refuses dispatch, preserving the original wallet attribution, other pending requests and the guard error ([#10638](https://github.com/MetaMask/core/pull/10638)).
103
+
104
+ - Select and persist the bounded testnet Chase child's final book quote after preparation and nonce acquisition, retaining five-second quote freshness, original duration and dispatch safety checks ([#10638](https://github.com/MetaMask/core/pull/10638)).
105
+
106
+ - Reject Scale children above Lighter's native base-amount maximum before preview readiness or trading setup, and validate the same limit in durable records. Preserve valid larger aggregates split across bounded children ([#10638](https://github.com/MetaMask/core/pull/10638)).
107
+ - Resolve public perps constant and utility subpaths from source during monorepo checks without requiring built outputs; retain separate compiled consumer validation ([#10638](https://github.com/MetaMask/core/pull/10638)).
108
+
109
+ - Preserve exact replacement child receipts when reconciling committed protection successors; omit unavailable identities and reserve empty receipts for confirmed removal ([#10638](https://github.com/MetaMask/core/pull/10638)).
110
+
111
+ - Require fresh isolated-position identity and collateral bounds for Lighter margin adjustments, recheck before signing and dispatch, and report success only after exact transaction execution. Preserve unresolved collateral/mode transactions across expiry, nonce advance and restart until exact terminal proof; require exact micro-USDC amounts ([#10638](https://github.com/MetaMask/core/pull/10638)).
112
+
113
+ - Keep ordinary Lighter orders unattributed when a live row contradicts a durably rejected Scale child ([#10638](https://github.com/MetaMask/core/pull/10638)).
114
+ - Return `ORDER_SCALE_PREVIEW_STALE` as an unsuccessful order result for malformed Scale expectations passed directly to `TradingService`, before fee resolution or placement ([#10638](https://github.com/MetaMask/core/pull/10638))
115
+ - Preserve Lighter Chase cancellation capacity when venue account authority is absent. Persist repeated local stop intent without adding cancellation attempts, retain uncertain dispatched cleanup across restart, and allow exact cleanup after the original authority returns ([#10638](https://github.com/MetaMask/core/pull/10638)).
116
+ - Treat confirmed absent and known Premium Lighter accounts as local-only recovery inventories without acknowledgment. Verify account ownership and index before caching or recording recovery authority. Preserve durable obligations and refuse transport, storage, ownership or unverified account-type failures; Premium trading remains unsupported ([#10638](https://github.com/MetaMask/core/pull/10638)).
117
+ - Persist guarded Lighter protection removals as non-resumable before dispatch. Recovery reconciles attempted cancellations and preserves surviving orders for explicit review even when saving a later refusal fails; fully settled removals clear without an obsolete warning ([#10638](https://github.com/MetaMask/core/pull/10638))
118
+ - Recheck HyperLiquid position protection after SDK signing and correlate partial SDK acknowledgments by exact signed child IDs. Preserve uncertain outcomes and restore only exact pre-call reduce-only protection when replacement becomes stale after cancellation; report protection loss if restoration fails ([#10638](https://github.com/MetaMask/core/pull/10638))
119
+ - Release only proven-unsent Lighter TP/SL attempts, ownership and nonce reservations after final position rejection, allowing a refreshed update or close while retaining older uncertain attempts ([#10638](https://github.com/MetaMask/core/pull/10638))
120
+ - Refuse position-protection dispatch when the final Lighter account response is ambiguous, belongs to another account or has an invalid position sign, while preserving old protection and allowing a refreshed retry ([#10638](https://github.com/MetaMask/core/pull/10638))
121
+ - Keep newly created Lighter TP/SL ownership across resizing and restart. Bound history reads to one page, reclaim only proven terminal or expired IDs, and retain uncertain IDs when history is unavailable ([#10638](https://github.com/MetaMask/core/pull/10638))
122
+ - Keep Lighter TP/SL recovery obligations for venue-accepted submissions when a later lookup cannot find them, so recovery cannot discard live protection ([#10638](https://github.com/MetaMask/core/pull/10638))
123
+ - Allow removal of proven managed Lighter TP/SL IDs when the position disappears, becomes zero or falls below the size tick after preflight. Require an authoritative account/positions response, preserve unrecorded protection without valid live quantity and side, and retain replacement size/side guards ([#10638](https://github.com/MetaMask/core/pull/10638))
124
+ - Restore canceled HyperLiquid protection after definitive top-level exchange rejection, invalidate rejected agents, preserve venue error details and reconcile partial or lost restoration responses by signed child IDs. Triggered and unknown in-flight children retain their exact IDs and block duplicate restoration. Probe multisig eligibility at each signed protection dispatch without caching readiness ([#10638](https://github.com/MetaMask/core/pull/10638))
125
+ - Reconcile non-selected-slot Lighter protection journals using their original transaction identity without signing follow-up operations. Block new protection changes while attempts remain unsettled, preserve surviving orders for current-key review, and clear previous-slot warnings only after an explicit update settles their recorded orders and obligations ([#10618](https://github.com/MetaMask/core/pull/10618))
126
+ - Reject recovered-dispatch acknowledgment when the selected wallet, network, provider or provider lifetime changes during readiness or acknowledgment, including failed provider/network switch rollbacks and legacy recovery IDs. A stale-context rejection after provider success does not undo acknowledgment in the issuing account; callers must re-list outcomes before acting again ([#10618](https://github.com/MetaMask/core/pull/10618))
127
+ - Refuse stale signer readiness after a wallet switch or bridge reset while setup finishes, preserving unfinished TP/SL recovery visibility ([#10618](https://github.com/MetaMask/core/pull/10618))
128
+ - Fence Lighter financial writes across every local account key slot so migration cannot bypass a pending or quarantined dispatch. Reconcile exact transaction identities under an account-wide write mutex; discovery and key registration share this mutex but bypass other-slot financial obligations. Nonterminal or mismatched transactions stay unresolved and cannot be acknowledged ([#10618](https://github.com/MetaMask/core/pull/10618))
129
+ - Reuse matching Lighter trading keys before allocating a free slot, preserve occupied device keys and wait for new registration visibility. Persist pending registration identity across reconnects and provider restarts so an accepted but invisible key cannot allocate another slot. Remember exact execution observed during reconnect before later expired index absence can authorize another registration ([#10618](https://github.com/MetaMask/core/pull/10618))
130
+ - Deliver Lighter signer setup failures to the current wallet's subscribers. Replay confirmed empty orders and validated newest-first fill history to late subscribers in the same authenticated session; malformed order/trade containers, null order/trade rows and rejected order rows never authorize empty replay; omitted orders or trades containers leave the last snapshot unchanged; throwing error listeners cannot suppress sibling delivery or prevent setup retries ([#10618](https://github.com/MetaMask/core/pull/10618))
131
+ - Accept Lighter trades that omit position-sign flags and preserve omitted account PnL, including closing and flipping fill PnL, as unknown for Activity and late-subscriber replay. Retain side-only fill directions when lifecycle context is ambiguous ([#10605](https://github.com/MetaMask/core/pull/10605), [#10618](https://github.com/MetaMask/core/pull/10618))
132
+ - Detect a revoked or expired HyperLiquid agent that the venue answers with "Must deposit before performing actions" ([#10643](https://github.com/MetaMask/core/pull/10643))
133
+ - The provider then checks `extraAgents` for the agent that signed the answered request. When it is missing or past its `validUntil`, the write fails with `KEYRING_LOCKED`, the agent is dropped and `onAgentRejected` is called. Requests signed by the main account, or by a wallet of an earlier network or session, are not checked
134
+ - When the agent is still listed (an account with no funds), or the list cannot be read, the venue error is returned as before
135
+ - Sign a HyperLiquid L1 action the SDK queued before a network switch with the agent of the network it was queued on, not the new network's ([#10643](https://github.com/MetaMask/core/pull/10643))
136
+ - Attribute a HyperLiquid "User or API Wallet ... does not exist" rejection to the network of the request it answers, so an agent used on both networks is dropped, and `onAgentRejected` called, only for that network ([#10643](https://github.com/MetaMask/core/pull/10643))
137
+ - Stop asking again for a HyperLiquid builder fee approval the venue refused for a reason signing again cannot fix, such as "Builder has insufficient balance to be approved" ([#10643](https://github.com/MetaMask/core/pull/10643))
138
+ - Until the provider disconnects, the approval is not requested again: orders are sent as after any failed approval, TP/SL updates fail with `TPSL_UPDATE_FAILED`, and `prepareTradingWallet` returns the venue error
139
+ - Stop reporting HyperLiquid WebSocket transport failures (a closed or terminated socket, request timeout or abort) during the unified-account setup as errors ([#10651](https://github.com/MetaMask/core/pull/10651))
140
+ - After such a failure, provider entry waits one minute before running the setup again instead of retrying every time; `reconnect()` or `disconnect()` ends the wait, and trading and withdraw still run the setup
141
+ - Venue rejections, signing failures and other setup errors are still reported
142
+ - Degrade without logging an error when the host does not provide an optional messenger action, whether it is unregistered or not delegated to `PerpsController` ([#10665](https://github.com/MetaMask/core/pull/10665))
143
+ - `SubscriptionController:getBenefits` (fee waiver): an undelegated action now reads as no subscription source, as an unregistered one already did, instead of logging an error when no injected `subscription` source is wired
144
+ - `NetworkController:getState` / `getNetworkClientById` (rewards discount): no discount instead of an error
145
+ - `AuthenticationController:getBearerToken` (data-lake report): skipped instead of logged and retried; a report skipped for a missing account or token now also ends its trace
146
+ - `AuthenticatedUserStorageService:getNotificationPreferences` / `putNotificationPreferences` (watchlist sync): the local watchlist is kept instead of logging an error and reverting the toggle. AUS stays the source of truth: with the read but not the write, a toggle is replaced by the next hydration from AUS queued after it, which every initialization runs (`init()`, including after `disconnect()`, `toggleTestnet()` and `switchProvider()`)
147
+ - Only a missing handler for the exact action called counts. A delegated handler that fails is still reported, including when it fails on a missing handler for another action (such as AUS missing `AuthenticationController:getBearerToken`, or a `NetworkController` read missing the other one), and so is a failure of the injected `rewards` dependency. The exceptions are unchanged: when an injected `subscription` source is wired, a failing `SubscriptionController:getBenefits` handler still falls back to it, and so does a `registerAddress` handler that throws synchronously (an asynchronous `registerAddress` rejection skips registration)
148
+ - The "Chain ID not found" error for the rewards discount now includes the `getNetworkClientById` failure that caused it
149
+ - `RemoteFeatureFlagController:getState` in the constructor and `startEligibilityMonitoring`, `GeolocationController`, `KeyringController` and `TransactionController` are unchanged and still report errors
150
+ - Keep watchlist toggles made while an AuthenticatedUserStorageService hydration is queued or in flight, applying them on top of the remote watchlist instead of overwriting them with it ([#10665](https://github.com/MetaMask/core/pull/10665), [#10670](https://github.com/MetaMask/core/pull/10670))
151
+ - A hydration started by a re-initialization (`init()` after `disconnect()`, `toggleTestnet()`, `switchProvider()`) now waits for earlier watchlist writes, so it no longer drops a star made just before it. Re-initialization no longer replaces the AUS queue, so a hydration read that never settles now also holds later watchlist writes
152
+ - Undo only the failed toggle when syncing a watchlist toggle to AuthenticatedUserStorageService fails, instead of restoring the watchlist from before that toggle, which also discarded hydrated markets and later toggles of other markets ([#10670](https://github.com/MetaMask/core/pull/10670))
153
+ - An unstarred market goes back to its position
154
+ - A toggle is not undone when a later toggle of the same market supersedes it; that toggle's own sync decides the market's state
17
155
 
18
156
  ## [19.0.0]
19
157