@metamask-previews/perps-controller 8.0.0-preview-51b287c55 → 8.1.0-preview-3af52b79c

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 (78) hide show
  1. package/CHANGELOG.md +29 -1
  2. package/dist/constants/hyperLiquidConfig.cjs +166 -1
  3. package/dist/constants/hyperLiquidConfig.cjs.map +1 -1
  4. package/dist/constants/hyperLiquidConfig.d.cts +33 -0
  5. package/dist/constants/hyperLiquidConfig.d.cts.map +1 -1
  6. package/dist/constants/hyperLiquidConfig.d.mts +33 -0
  7. package/dist/constants/hyperLiquidConfig.d.mts.map +1 -1
  8. package/dist/constants/hyperLiquidConfig.mjs +163 -0
  9. package/dist/constants/hyperLiquidConfig.mjs.map +1 -1
  10. package/dist/constants/perpsConfig.cjs +2 -0
  11. package/dist/constants/perpsConfig.cjs.map +1 -1
  12. package/dist/constants/perpsConfig.d.cts +1 -0
  13. package/dist/constants/perpsConfig.d.cts.map +1 -1
  14. package/dist/constants/perpsConfig.d.mts +1 -0
  15. package/dist/constants/perpsConfig.d.mts.map +1 -1
  16. package/dist/constants/perpsConfig.mjs +2 -0
  17. package/dist/constants/perpsConfig.mjs.map +1 -1
  18. package/dist/index.cjs +48 -44
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.cts +2 -1
  21. package/dist/index.d.cts.map +1 -1
  22. package/dist/index.d.mts +2 -1
  23. package/dist/index.d.mts.map +1 -1
  24. package/dist/index.mjs +2 -1
  25. package/dist/index.mjs.map +1 -1
  26. package/dist/providers/HyperLiquidProvider.cjs +2 -2
  27. package/dist/providers/HyperLiquidProvider.cjs.map +1 -1
  28. package/dist/providers/HyperLiquidProvider.d.cts +1 -1
  29. package/dist/providers/HyperLiquidProvider.d.cts.map +1 -1
  30. package/dist/providers/HyperLiquidProvider.d.mts +1 -1
  31. package/dist/providers/HyperLiquidProvider.d.mts.map +1 -1
  32. package/dist/providers/HyperLiquidProvider.mjs +3 -3
  33. package/dist/providers/HyperLiquidProvider.mjs.map +1 -1
  34. package/dist/services/HyperLiquidSubscriptionService.cjs +109 -185
  35. package/dist/services/HyperLiquidSubscriptionService.cjs.map +1 -1
  36. package/dist/services/HyperLiquidSubscriptionService.d.cts +3 -3
  37. package/dist/services/HyperLiquidSubscriptionService.d.cts.map +1 -1
  38. package/dist/services/HyperLiquidSubscriptionService.d.mts +3 -3
  39. package/dist/services/HyperLiquidSubscriptionService.d.mts.map +1 -1
  40. package/dist/services/HyperLiquidSubscriptionService.mjs +109 -185
  41. package/dist/services/HyperLiquidSubscriptionService.mjs.map +1 -1
  42. package/dist/services/TradingService.cjs +50 -3
  43. package/dist/services/TradingService.cjs.map +1 -1
  44. package/dist/services/TradingService.d.cts.map +1 -1
  45. package/dist/services/TradingService.d.mts.map +1 -1
  46. package/dist/services/TradingService.mjs +50 -3
  47. package/dist/services/TradingService.mjs.map +1 -1
  48. package/dist/types/index.cjs.map +1 -1
  49. package/dist/types/index.d.cts +1 -1
  50. package/dist/types/index.d.cts.map +1 -1
  51. package/dist/types/index.d.mts +1 -1
  52. package/dist/types/index.d.mts.map +1 -1
  53. package/dist/types/index.mjs.map +1 -1
  54. package/dist/utils/index.cjs +1 -0
  55. package/dist/utils/index.cjs.map +1 -1
  56. package/dist/utils/index.d.cts +1 -0
  57. package/dist/utils/index.d.cts.map +1 -1
  58. package/dist/utils/index.d.mts +1 -0
  59. package/dist/utils/index.d.mts.map +1 -1
  60. package/dist/utils/index.mjs +1 -0
  61. package/dist/utils/index.mjs.map +1 -1
  62. package/dist/utils/marketDataTransform.cjs +5 -2
  63. package/dist/utils/marketDataTransform.cjs.map +1 -1
  64. package/dist/utils/marketDataTransform.d.cts +4 -1
  65. package/dist/utils/marketDataTransform.d.cts.map +1 -1
  66. package/dist/utils/marketDataTransform.d.mts +4 -1
  67. package/dist/utils/marketDataTransform.d.mts.map +1 -1
  68. package/dist/utils/marketDataTransform.mjs +6 -3
  69. package/dist/utils/marketDataTransform.mjs.map +1 -1
  70. package/dist/utils/marketSearch.cjs +85 -0
  71. package/dist/utils/marketSearch.cjs.map +1 -0
  72. package/dist/utils/marketSearch.d.cts +47 -0
  73. package/dist/utils/marketSearch.d.cts.map +1 -0
  74. package/dist/utils/marketSearch.d.mts +47 -0
  75. package/dist/utils/marketSearch.d.mts.map +1 -0
  76. package/dist/utils/marketSearch.mjs +80 -0
  77. package/dist/utils/marketSearch.mjs.map +1 -0
  78. package/package.json +2 -2
@@ -426,7 +426,7 @@ class HyperLiquidSubscriptionService {
426
426
  }
427
427
  /**
428
428
  * Subscribe to open interest cap updates
429
- * OI caps are extracted from webData2 subscription (zero additional overhead)
429
+ * OI caps are extracted from the shared webData3 subscription (zero additional overhead)
430
430
  *
431
431
  * @param params - The subscription parameters including callback and account ID.
432
432
  * @returns A cleanup function to unsubscribe from OI cap updates.
@@ -493,7 +493,7 @@ class HyperLiquidSubscriptionService {
493
493
  }
494
494
  /**
495
495
  * Subscribe to live order updates
496
- * Uses the shared webData2 subscription to avoid duplicate connections
496
+ * Uses the shared per-DEX subscriptions to avoid duplicate connections
497
497
  *
498
498
  * @param params - The subscription parameters including callback and account ID.
499
499
  * @returns A cleanup function to unsubscribe from order updates.
@@ -519,7 +519,7 @@ class HyperLiquidSubscriptionService {
519
519
  }
520
520
  /**
521
521
  * Subscribe to live account updates
522
- * Uses the shared webData2 subscription to avoid duplicate connections
522
+ * Uses the shared per-DEX subscriptions to avoid duplicate connections
523
523
  *
524
524
  * @param params - The subscription parameters including callback and account ID.
525
525
  * @returns A cleanup function to unsubscribe from account updates.
@@ -753,11 +753,11 @@ class HyperLiquidSubscriptionService {
753
753
  // Clear existing subscription references (they're dead after reconnection)
754
754
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_webData3Subscriptions, "f").clear();
755
755
  __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_webData3SubscriptionPromise, undefined, "f");
756
- // Clear individual subscriptions (clearinghouseState + openOrders) for HIP-3 mode
756
+ // Clear individual subscriptions (clearinghouseState + openOrders)
757
757
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_clearinghouseStateSubscriptions, "f").clear();
758
758
  __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_openOrdersSubscriptions, "f").clear();
759
759
  // Re-establish the subscription (will use current account)
760
- // This will set up webData2 for non-HIP-3, or individual subscriptions + webData3 (OI caps only) for HIP-3
760
+ // This sets up per-DEX clearinghouseState + openOrders subscriptions plus webData3 (OI caps only)
761
761
  await __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_ensureSharedWebData3Subscription).call(this);
762
762
  }
763
763
  // Re-establish activeAsset subscriptions if there are market data subscribers
@@ -1614,12 +1614,18 @@ async function _HyperLiquidSubscriptionService_ensureSharedWebData3Subscription(
1614
1614
  // Note: webData3 includes all DEX data, so no separate HIP-3 subscriptions needed
1615
1615
  }, _HyperLiquidSubscriptionService_createUserDataSubscription =
1616
1616
  /**
1617
- * Create WebSocket subscription for user data (positions, orders, account)
1618
- * - Uses webData2 when HIP-3 disabled (main DEX only)
1619
- * - Uses webData3 when HIP-3 enabled (main + HIP-3 DEXs)
1617
+ * Create WebSocket subscription for user data (positions, orders, account).
1620
1618
  *
1621
- * webData2 provides data for main DEX only
1622
- * webData3 provides perpDexStates[] array containing data for all DEXs:
1619
+ * Positions, orders, and account/spot balance are always delivered via
1620
+ * per-DEX `clearinghouseState` + `openOrders` subscriptions (sub-second
1621
+ * updates). webData3 is used only for OI caps extraction (not
1622
+ * latency-sensitive). The deprecated webData2 snapshot channel is no longer
1623
+ * used (TAT-3332).
1624
+ *
1625
+ * - HIP-3 disabled: subscribe to the main DEX only (`dexsToSubscribe = ['']`).
1626
+ * - HIP-3 enabled: subscribe to the main DEX plus each enabled HIP-3 DEX.
1627
+ *
1628
+ * webData3 provides perpDexStates[] array containing OI caps for all DEXs:
1623
1629
  * - Index 0: Main DEX (dexName = '')
1624
1630
  * - Index 1+: HIP-3 DEXs in order of enabledDexs array
1625
1631
  *
@@ -1648,187 +1654,105 @@ async function _HyperLiquidSubscriptionService_createUserDataSubscription(accoun
1648
1654
  });
1649
1655
  }
1650
1656
  return new Promise((resolve, reject) => {
1651
- // Choose channel based on HIP-3 master switch
1652
- if (__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_hip3Enabled, "f")) {
1653
- // HIP-3 enabled: Use individual subscriptions for positions/orders/account
1654
- // webData3 is only used for OI caps extraction
1655
- // Determine which DEXs to subscribe to
1656
- const dexsToSubscribe = [
1657
- '', // Main DEX
1657
+ // Use per-DEX clearinghouseState + openOrders subscriptions for
1658
+ // positions/orders/account on every path. webData3 is used only for OI
1659
+ // caps extraction. The deprecated webData2 channel is no longer used.
1660
+ // Determine which DEXs to subscribe to:
1661
+ // - HIP-3 enabled: main DEX + each enabled HIP-3 DEX.
1662
+ // - HIP-3 disabled: main DEX only.
1663
+ const dexsToSubscribe = __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_hip3Enabled, "f")
1664
+ ? [
1665
+ '',
1658
1666
  ...__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_enabledDexs, "f").filter((dexId) => __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_isDexEnabled).call(this, dexId)),
1659
- ];
1660
- // Track expected DEXs for synchronized notifications
1661
- // Clear previous tracking and set new expected DEXs
1662
- __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_expectedDexs, new Set(dexsToSubscribe), "f");
1663
- __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_initializedDexs, new Set(), "f");
1664
- // Set up individual subscriptions for each DEX
1665
- const subscriptionPromises = [];
1666
- for (const currentDexName of dexsToSubscribe) {
1667
- // Set up clearinghouseState subscription for positions + account
1668
- subscriptionPromises.push(__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_ensureClearinghouseStateSubscription).call(this, userAddress, currentDexName));
1669
- // Set up openOrders subscription for orders
1670
- subscriptionPromises.push(__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_ensureOpenOrdersSubscription).call(this, userAddress, currentDexName));
1671
- }
1672
- // Also set up webData3 for OI caps only
1673
- const webData3Promise = subscriptionClient
1674
- .webData3({ user: userAddress }, (data) => {
1675
- try {
1676
- // webData3 is ONLY used for OI caps extraction
1677
- // Positions, orders, and account data come from individual subscriptions
1678
- const allOICaps = [];
1679
- data.perpDexStates.forEach((dexState, index) => {
1680
- // Map webData3 index to DEX name
1681
- // Index 0 = main DEX (null), Index 1+ = HIP-3 DEXs from discoveredDexNames
1682
- const dexIdentifier = index === 0 ? null : __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_discoveredDexNames, "f")[index - 1];
1683
- // Skip unknown DEXs (not in discoveredDexNames) to prevent main DEX cache corruption
1684
- if (index > 0 && dexIdentifier === undefined) {
1685
- return; // Unknown DEX - skip to prevent misidentifying as main DEX
1686
- }
1687
- // Only process DEXs we care about (skip others silently)
1688
- if (!__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_isDexEnabled).call(this, dexIdentifier ?? null)) {
1689
- return; // Skip this DEX - not enabled in our configuration
1690
- }
1691
- const currentDexName = dexIdentifier ?? '';
1692
- const oiCaps = dexState.perpsAtOpenInterestCap ?? [];
1693
- // Add DEX prefix for HIP-3 symbols (e.g., "xyz:TSLA")
1694
- if (currentDexName) {
1695
- allOICaps.push(...oiCaps.map((symbol) => `${currentDexName}:${symbol}`));
1696
- }
1697
- else {
1698
- // Main DEX - no prefix needed
1699
- allOICaps.push(...oiCaps);
1700
- }
1701
- });
1702
- // Update OI caps cache and notify if changed
1703
- const oiCapsHash = [...allOICaps]
1704
- .sort((a, b) => a.localeCompare(b))
1705
- .join(',');
1706
- if (oiCapsHash !== __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_cachedOICapsHash, "f")) {
1707
- __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_cachedOICaps, allOICaps, "f");
1708
- __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_cachedOICapsHash, oiCapsHash, "f");
1709
- __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_oiCapsCacheInitialized, true, "f");
1710
- // Notify all subscribers
1711
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_oiCapSubscribers, "f").forEach((callback) => callback(allOICaps));
1712
- }
1713
- }
1714
- catch (error) {
1715
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_logErrorUnlessClearing).call(this, (0, errorUtils_1.ensureError)(error, 'HyperLiquidSubscriptionService.createUserDataSubscription'), __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_getErrorContext).call(this, 'webData3 callback error', {
1716
- user: userAddress,
1717
- hasPerpDexStates: data?.perpDexStates !== undefined,
1718
- perpDexStatesLength: data?.perpDexStates?.length ?? 0,
1719
- }));
1720
- }
1721
- })
1722
- .then((sub) => {
1723
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_webData3Subscriptions, "f").set(dexName, sub);
1724
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_deps, "f").debugLogger.log(`webData3 subscription established for OI caps (main + HIP-3)`);
1725
- return undefined;
1726
- })
1727
- .catch((error) => {
1728
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_logErrorUnlessClearing).call(this, (0, errorUtils_1.ensureError)(error, 'HyperLiquidSubscriptionService.createUserDataSubscription'), __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_getErrorContext).call(this, 'createUserDataSubscription (webData3)', {
1729
- dex: dexName,
1730
- }));
1731
- throw error;
1732
- });
1733
- subscriptionPromises.push(webData3Promise);
1734
- // Wait for all subscriptions to be established
1735
- Promise.all(subscriptionPromises)
1736
- .then(() => {
1737
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_deps, "f").debugLogger.log(`HIP-3 user data subscriptions established for ${dexsToSubscribe.length} DEXs`);
1738
- resolve();
1739
- return undefined;
1740
- })
1741
- .catch((error) => {
1742
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_logErrorUnlessClearing).call(this, (0, errorUtils_1.ensureError)(error, 'HyperLiquidSubscriptionService.createUserDataSubscription'), __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_getErrorContext).call(this, 'createUserDataSubscription (HIP-3)', {
1743
- dexs: dexsToSubscribe,
1744
- }));
1745
- reject((0, errorUtils_1.ensureError)(error, 'HyperLiquidSubscriptionService.createUserDataSubscription'));
1746
- });
1747
- }
1748
- else {
1749
- // HIP-3 disabled: Use webData2 (main DEX only)
1750
- subscriptionClient
1751
- .webData2({ user: userAddress }, (data) => {
1752
- try {
1753
- // webData2 returns clearinghouseState for main DEX only
1754
- const currentDexName = ''; // Main DEX
1755
- // Check for removed fields before accessing
1756
- if (!data.clearinghouseState) {
1757
- return;
1758
- }
1759
- // Extract and process positions from clearinghouseState
1760
- const positions = data.clearinghouseState.assetPositions
1761
- .filter((assetPos) => assetPos.position.szi !== '0')
1762
- .map((assetPos) => (0, hyperLiquidAdapter_1.adaptPositionFromSDK)(assetPos));
1763
- // Extract TP/SL from orders
1764
- const { tpslMap, tpslCountMap, processedOrders: orders, } = __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_extractTPSLFromOrders).call(this, data.openOrders || [], positions);
1765
- // Merge TP/SL data into positions
1766
- const positionsWithTPSL = __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_mergeTPSLIntoPositions).call(this, positions, tpslMap, tpslCountMap);
1767
- // Extract account data (webData2 provides clearinghouseState)
1768
- const accountState = (0, hyperLiquidAdapter_1.adaptAccountStateFromSDK)(data.clearinghouseState);
1769
- // Store in caches (main DEX only)
1770
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_dexPositionsCache, "f").set(currentDexName, positionsWithTPSL);
1771
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_dexOrdersCache, "f").set(currentDexName, orders);
1772
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_dexAccountCache, "f").set(currentDexName, accountState);
1773
- // OI caps (main DEX only)
1774
- const oiCaps = data.perpsAtOpenInterestCap ?? [];
1775
- const oiCapsHash = [...oiCaps]
1776
- .sort((a, b) => a.localeCompare(b))
1777
- .join(',');
1778
- if (oiCapsHash !== __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_cachedOICapsHash, "f")) {
1779
- __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_cachedOICaps, oiCaps, "f");
1780
- __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_cachedOICapsHash, oiCapsHash, "f");
1781
- __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_oiCapsCacheInitialized, true, "f");
1782
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_oiCapSubscribers, "f").forEach((callback) => callback(oiCaps));
1667
+ ]
1668
+ : [''];
1669
+ // Track expected DEXs for synchronized notifications
1670
+ // Clear previous tracking and set new expected DEXs
1671
+ __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_expectedDexs, new Set(dexsToSubscribe), "f");
1672
+ __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_initializedDexs, new Set(), "f");
1673
+ // Set up individual subscriptions for each DEX
1674
+ const subscriptionPromises = [];
1675
+ for (const currentDexName of dexsToSubscribe) {
1676
+ // Set up clearinghouseState subscription for positions + account
1677
+ subscriptionPromises.push(__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_ensureClearinghouseStateSubscription).call(this, userAddress, currentDexName));
1678
+ // Set up openOrders subscription for orders
1679
+ subscriptionPromises.push(__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_ensureOpenOrdersSubscription).call(this, userAddress, currentDexName));
1680
+ }
1681
+ // Also set up webData3 for OI caps only
1682
+ const webData3Promise = subscriptionClient
1683
+ .webData3({ user: userAddress }, (data) => {
1684
+ try {
1685
+ // webData3 is ONLY used for OI caps extraction
1686
+ // Positions, orders, and account data come from individual subscriptions
1687
+ const allOICaps = [];
1688
+ data.perpDexStates.forEach((dexState, index) => {
1689
+ // Map webData3 index to DEX name
1690
+ // Index 0 = main DEX (null), Index 1+ = HIP-3 DEXs from discoveredDexNames
1691
+ const dexIdentifier = index === 0 ? null : __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_discoveredDexNames, "f")[index - 1];
1692
+ // Skip unknown DEXs (not in discoveredDexNames) to prevent main DEX cache corruption
1693
+ if (index > 0 && dexIdentifier === undefined) {
1694
+ return; // Unknown DEX - skip to prevent misidentifying as main DEX
1783
1695
  }
1784
- // Notify subscribers (no aggregation needed - only main DEX).
1785
- // Apply spot balance so single-DEX accounts see the same
1786
- // spot-inclusive totalBalance as the HIP-3 aggregation path.
1787
- const spotAdjustedAccount = (0, accountUtils_1.addSpotBalanceToAccountState)(accountState, __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_cachedSpotState, "f"), __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_getSpotBalanceOptions).call(this));
1788
- const positionsHash = __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_hashPositions).call(this, positionsWithTPSL);
1789
- const ordersHash = __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_hashOrders).call(this, orders);
1790
- const accountHash = __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_hashAccountState).call(this, spotAdjustedAccount);
1791
- if (positionsHash !== __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_cachedPositionsHash, "f")) {
1792
- __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_cachedPositions, positionsWithTPSL, "f");
1793
- __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_cachedPositionsHash, positionsHash, "f");
1794
- __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_positionsCacheInitialized, true, "f");
1795
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_positionSubscribers, "f").forEach((callback) => callback(positionsWithTPSL));
1696
+ // Only process DEXs we care about (skip others silently)
1697
+ if (!__classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_isDexEnabled).call(this, dexIdentifier ?? null)) {
1698
+ return; // Skip this DEX - not enabled in our configuration
1796
1699
  }
1797
- if (ordersHash !== __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_cachedOrdersHash, "f")) {
1798
- __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_cachedOrders, orders, "f");
1799
- __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_cachedOrdersHash, ordersHash, "f");
1800
- __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_ordersCacheInitialized, true, "f");
1801
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_orderSubscribers, "f").forEach((callback) => callback(orders));
1700
+ const currentDexName = dexIdentifier ?? '';
1701
+ const oiCaps = dexState.perpsAtOpenInterestCap ?? [];
1702
+ // Add DEX prefix for HIP-3 symbols (e.g., "xyz:TSLA")
1703
+ if (currentDexName) {
1704
+ allOICaps.push(...oiCaps.map((symbol) => `${currentDexName}:${symbol}`));
1802
1705
  }
1803
- if (accountHash !== __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_cachedAccountHash, "f")) {
1804
- __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_cachedAccount, spotAdjustedAccount, "f");
1805
- __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_cachedAccountHash, accountHash, "f");
1806
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_accountSubscribers, "f").forEach((callback) => callback(spotAdjustedAccount));
1706
+ else {
1707
+ // Main DEX - no prefix needed
1708
+ allOICaps.push(...oiCaps);
1807
1709
  }
1710
+ });
1711
+ // Update OI caps cache and notify if changed
1712
+ const oiCapsHash = [...allOICaps]
1713
+ .sort((a, b) => a.localeCompare(b))
1714
+ .join(',');
1715
+ if (oiCapsHash !== __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_cachedOICapsHash, "f")) {
1716
+ __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_cachedOICaps, allOICaps, "f");
1717
+ __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_cachedOICapsHash, oiCapsHash, "f");
1718
+ __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_oiCapsCacheInitialized, true, "f");
1719
+ // Notify all subscribers
1720
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_oiCapSubscribers, "f").forEach((callback) => callback(allOICaps));
1808
1721
  }
1809
- catch (error) {
1810
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_logErrorUnlessClearing).call(this, (0, errorUtils_1.ensureError)(error, 'HyperLiquidSubscriptionService.createUserDataSubscription'), __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_getErrorContext).call(this, 'webData2 callback error', {
1811
- user: userAddress,
1812
- dataKeys: data ? Object.keys(data) : 'data is null/undefined',
1813
- hasClearinghouseState: data?.clearinghouseState !== undefined,
1814
- hasOpenOrders: data?.openOrders !== undefined,
1815
- hasPerpsAtOpenInterestCap: data?.perpsAtOpenInterestCap !== undefined,
1816
- }));
1817
- }
1818
- })
1819
- .then((subscription) => {
1820
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_webData3Subscriptions, "f").set(dexName, subscription);
1821
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_deps, "f").debugLogger.log('webData2 subscription established for main DEX only');
1822
- resolve();
1823
- return undefined;
1824
- })
1825
- .catch((error) => {
1826
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_logErrorUnlessClearing).call(this, (0, errorUtils_1.ensureError)(error, 'HyperLiquidSubscriptionService.createUserDataSubscription'), __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_getErrorContext).call(this, 'createUserDataSubscription (webData2)', {
1827
- dex: dexName,
1722
+ }
1723
+ catch (error) {
1724
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_logErrorUnlessClearing).call(this, (0, errorUtils_1.ensureError)(error, 'HyperLiquidSubscriptionService.createUserDataSubscription'), __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_getErrorContext).call(this, 'webData3 callback error', {
1725
+ user: userAddress,
1726
+ hasPerpDexStates: data?.perpDexStates !== undefined,
1727
+ perpDexStatesLength: data?.perpDexStates?.length ?? 0,
1828
1728
  }));
1829
- reject((0, errorUtils_1.ensureError)(error, 'HyperLiquidSubscriptionService.createUserDataSubscription'));
1830
- });
1831
- }
1729
+ }
1730
+ })
1731
+ .then((sub) => {
1732
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_webData3Subscriptions, "f").set(dexName, sub);
1733
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_deps, "f").debugLogger.log(`webData3 subscription established for OI caps (main + HIP-3)`);
1734
+ return undefined;
1735
+ })
1736
+ .catch((error) => {
1737
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_logErrorUnlessClearing).call(this, (0, errorUtils_1.ensureError)(error, 'HyperLiquidSubscriptionService.createUserDataSubscription'), __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_getErrorContext).call(this, 'createUserDataSubscription (webData3)', {
1738
+ dex: dexName,
1739
+ }));
1740
+ throw error;
1741
+ });
1742
+ subscriptionPromises.push(webData3Promise);
1743
+ // Wait for all subscriptions to be established
1744
+ Promise.all(subscriptionPromises)
1745
+ .then(() => {
1746
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_deps, "f").debugLogger.log(`User data subscriptions established for ${dexsToSubscribe.length} DEX(s)`);
1747
+ resolve();
1748
+ return undefined;
1749
+ })
1750
+ .catch((error) => {
1751
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_logErrorUnlessClearing).call(this, (0, errorUtils_1.ensureError)(error, 'HyperLiquidSubscriptionService.createUserDataSubscription'), __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_instances, "m", _HyperLiquidSubscriptionService_getErrorContext).call(this, 'createUserDataSubscription', {
1752
+ dexs: dexsToSubscribe,
1753
+ }));
1754
+ reject((0, errorUtils_1.ensureError)(error, 'HyperLiquidSubscriptionService.createUserDataSubscription'));
1755
+ });
1832
1756
  });
1833
1757
  }, _HyperLiquidSubscriptionService_ensureClearinghouseStateSubscription =
1834
1758
  /**
@@ -2149,7 +2073,7 @@ async function _HyperLiquidSubscriptionService_createOpenOrdersSubscription(user
2149
2073
  __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_cachedPositionsHash, '', "f");
2150
2074
  __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_cachedOrdersHash, '', "f");
2151
2075
  __classPrivateFieldSet(this, _HyperLiquidSubscriptionService_cachedAccountHash, '', "f");
2152
- __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_deps, "f").debugLogger.log('All multi-DEX subscriptions cleaned up (webData2/3 + individual subscriptions)');
2076
+ __classPrivateFieldGet(this, _HyperLiquidSubscriptionService_deps, "f").debugLogger.log('All multi-DEX subscriptions cleaned up (webData3 + individual subscriptions)');
2153
2077
  }
2154
2078
  }, _HyperLiquidSubscriptionService_ensureOrderFillISubscription =
2155
2079
  /**