@metamask-previews/perps-controller 11.0.0-preview-9c0f91815 → 11.0.0-preview-e57e5c3dc

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 (82) hide show
  1. package/CHANGELOG.md +0 -49
  2. package/dist/PerpsController.cjs.map +1 -1
  3. package/dist/PerpsController.d.cts +1 -1
  4. package/dist/PerpsController.d.cts.map +1 -1
  5. package/dist/PerpsController.d.mts +1 -1
  6. package/dist/PerpsController.d.mts.map +1 -1
  7. package/dist/PerpsController.mjs.map +1 -1
  8. package/dist/constants/eventNames.cjs +0 -4
  9. package/dist/constants/eventNames.cjs.map +1 -1
  10. package/dist/constants/eventNames.d.cts +0 -3
  11. package/dist/constants/eventNames.d.cts.map +1 -1
  12. package/dist/constants/eventNames.d.mts +0 -3
  13. package/dist/constants/eventNames.d.mts.map +1 -1
  14. package/dist/constants/eventNames.mjs +0 -4
  15. package/dist/constants/eventNames.mjs.map +1 -1
  16. package/dist/constants/perpsConfig.cjs +1 -54
  17. package/dist/constants/perpsConfig.cjs.map +1 -1
  18. package/dist/constants/perpsConfig.d.cts +2 -71
  19. package/dist/constants/perpsConfig.d.cts.map +1 -1
  20. package/dist/constants/perpsConfig.d.mts +2 -71
  21. package/dist/constants/perpsConfig.d.mts.map +1 -1
  22. package/dist/constants/perpsConfig.mjs +0 -53
  23. package/dist/constants/perpsConfig.mjs.map +1 -1
  24. package/dist/index.cjs +3 -12
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +4 -4
  27. package/dist/index.d.cts.map +1 -1
  28. package/dist/index.d.mts +4 -4
  29. package/dist/index.d.mts.map +1 -1
  30. package/dist/index.mjs +2 -2
  31. package/dist/index.mjs.map +1 -1
  32. package/dist/perpsErrorCodes.cjs +0 -20
  33. package/dist/perpsErrorCodes.cjs.map +1 -1
  34. package/dist/perpsErrorCodes.d.cts +0 -19
  35. package/dist/perpsErrorCodes.d.cts.map +1 -1
  36. package/dist/perpsErrorCodes.d.mts +0 -19
  37. package/dist/perpsErrorCodes.d.mts.map +1 -1
  38. package/dist/perpsErrorCodes.mjs +0 -20
  39. package/dist/perpsErrorCodes.mjs.map +1 -1
  40. package/dist/providers/HyperLiquidProvider.cjs +14 -1276
  41. package/dist/providers/HyperLiquidProvider.cjs.map +1 -1
  42. package/dist/providers/HyperLiquidProvider.d.cts.map +1 -1
  43. package/dist/providers/HyperLiquidProvider.d.mts.map +1 -1
  44. package/dist/providers/HyperLiquidProvider.mjs +17 -1279
  45. package/dist/providers/HyperLiquidProvider.mjs.map +1 -1
  46. package/dist/types/index.cjs.map +1 -1
  47. package/dist/types/index.d.cts +2 -40
  48. package/dist/types/index.d.cts.map +1 -1
  49. package/dist/types/index.d.mts +2 -40
  50. package/dist/types/index.d.mts.map +1 -1
  51. package/dist/types/index.mjs.map +1 -1
  52. package/dist/types/perps-types.cjs.map +1 -1
  53. package/dist/types/perps-types.d.cts +2 -33
  54. package/dist/types/perps-types.d.cts.map +1 -1
  55. package/dist/types/perps-types.d.mts +2 -33
  56. package/dist/types/perps-types.d.mts.map +1 -1
  57. package/dist/types/perps-types.mjs.map +1 -1
  58. package/dist/utils/hyperLiquidValidation.cjs +3 -192
  59. package/dist/utils/hyperLiquidValidation.cjs.map +1 -1
  60. package/dist/utils/hyperLiquidValidation.d.cts +3 -30
  61. package/dist/utils/hyperLiquidValidation.d.cts.map +1 -1
  62. package/dist/utils/hyperLiquidValidation.d.mts +3 -30
  63. package/dist/utils/hyperLiquidValidation.d.mts.map +1 -1
  64. package/dist/utils/hyperLiquidValidation.mjs +5 -194
  65. package/dist/utils/hyperLiquidValidation.mjs.map +1 -1
  66. package/dist/utils/orderCalculations.cjs +1 -131
  67. package/dist/utils/orderCalculations.cjs.map +1 -1
  68. package/dist/utils/orderCalculations.d.cts +3 -88
  69. package/dist/utils/orderCalculations.d.cts.map +1 -1
  70. package/dist/utils/orderCalculations.d.mts +3 -88
  71. package/dist/utils/orderCalculations.d.mts.map +1 -1
  72. package/dist/utils/orderCalculations.mjs +2 -128
  73. package/dist/utils/orderCalculations.mjs.map +1 -1
  74. package/dist/utils/orderTypes.cjs +4 -56
  75. package/dist/utils/orderTypes.cjs.map +1 -1
  76. package/dist/utils/orderTypes.d.cts +3 -32
  77. package/dist/utils/orderTypes.d.cts.map +1 -1
  78. package/dist/utils/orderTypes.d.mts +3 -32
  79. package/dist/utils/orderTypes.d.mts.map +1 -1
  80. package/dist/utils/orderTypes.mjs +3 -54
  81. package/dist/utils/orderTypes.mjs.map +1 -1
  82. package/package.json +2 -2
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
12
  };
13
- var _HyperLiquidProvider_instances, _HyperLiquidProvider_deps, _HyperLiquidProvider_clientService, _HyperLiquidProvider_walletService, _HyperLiquidProvider_subscriptionService, _HyperLiquidProvider_symbolToAssetId, _HyperLiquidProvider_userFeeCache, _HyperLiquidProvider_maxLeverageCache, _HyperLiquidProvider_cachedMetaByDex, _HyperLiquidProvider_cachedMarketDataWithPrices, _HyperLiquidProvider_cachedSpotMeta, _HyperLiquidProvider_dexDiscoveryCache, _HyperLiquidProvider_referralCheckCache, _HyperLiquidProvider_builderFeeCheckCache, _HyperLiquidProvider_ensureReadyPromise, _HyperLiquidProvider_pendingBuilderFeeApprovals, _HyperLiquidProvider_compiledAllowlistPatterns, _HyperLiquidProvider_compiledBlocklistPatterns, _HyperLiquidProvider_userFeeDiscountBips, _HyperLiquidProvider_hip3Enabled, _HyperLiquidProvider_allowlistMarkets, _HyperLiquidProvider_blocklistMarkets, _HyperLiquidProvider_useUnifiedAccount, _HyperLiquidProvider_dexDiscoveryComplete, _HyperLiquidProvider_unifiedAccountSetupNeedsRetry, _HyperLiquidProvider_pendingValidatedDexsPromise, _HyperLiquidProvider_cachedUsdcTokenId, _HyperLiquidProvider_errorMappings, _HyperLiquidProvider_scaleOrderGroups, _HyperLiquidProvider_chaseSessions, _HyperLiquidProvider_chasePlacementsInFlight, _HyperLiquidProvider_chaseGeneration, _HyperLiquidProvider_clientsInitialized, _HyperLiquidProvider_initializationPromise, _HyperLiquidProvider_messenger, _HyperLiquidProvider_builderAddressTestnet, _HyperLiquidProvider_builderAddressMainnet, _HyperLiquidProvider_priceDeviationLimit, _HyperLiquidProvider_compilePatternsSafely, _HyperLiquidProvider_ensureClientsInitialized, _HyperLiquidProvider_isWalletOnHyperliquid, _HyperLiquidProvider_isHyperliquidMultiSigAccount, _HyperLiquidProvider_ensureUnifiedAccountEnabled, _HyperLiquidProvider_ensureReady, _HyperLiquidProvider_tradingSetupPromise, _HyperLiquidProvider_tradingSetupComplete, _HyperLiquidProvider_ensureReadyForTrading, _HyperLiquidProvider_getOrFetchPrice, _HyperLiquidProvider_filterFills, _HyperLiquidProvider_getAllAvailableDexs, _HyperLiquidProvider_getValidatedDexs, _HyperLiquidProvider_fetchValidatedDexsInternal, _HyperLiquidProvider_getCachedMeta, _HyperLiquidProvider_backfillAssetMapForDex, _HyperLiquidProvider_getAssetIdWithRepair, _HyperLiquidProvider_getCachedSpotMeta, _HyperLiquidProvider_getCachedPerpDexs, _HyperLiquidProvider_calculateHip3FeeMultiplier, _HyperLiquidProvider_getCacheKey, _HyperLiquidProvider_fetchMarketsForDex, _HyperLiquidProvider_getUsdcTokenId, _HyperLiquidProvider_isUsdcCollateralDex, _HyperLiquidProvider_buildAssetMapping, _HyperLiquidProvider_queryUserDataAcrossDexs, _HyperLiquidProvider_mapError, _HyperLiquidProvider_getErrorContext, _HyperLiquidProvider_isMappedAccountModeExchangeError, _HyperLiquidProvider_getTradingErrorContext, _HyperLiquidProvider_checkBuilderFeeApproval, _HyperLiquidProvider_ensureBuilderFeeApproval, _HyperLiquidProvider_checkBuilderFeeStatus, _HyperLiquidProvider_getBalanceForDex, _HyperLiquidProvider_findSourceDexWithBalance, _HyperLiquidProvider_autoTransferForHip3Order, _HyperLiquidProvider_autoTransferBackAfterClose, _HyperLiquidProvider_calculateHip3RequiredMargin, _HyperLiquidProvider_handleHip3PostOrderRebalance, _HyperLiquidProvider_handleHip3OrderRollback, _HyperLiquidProvider_validateOrderBeforePlacement, _HyperLiquidProvider_getAssetInfo, _HyperLiquidProvider_prepareAssetForTrading, _HyperLiquidProvider_handleHip3PreOrder, _HyperLiquidProvider_submitOrderWithRollback, _HyperLiquidProvider_handleOrderError, _HyperLiquidProvider_placeStrategyOrder, _HyperLiquidProvider_prepareStrategyPlacement, _HyperLiquidProvider_getMinimumOrderSize, _HyperLiquidProvider_buildScaleLadder, _HyperLiquidProvider_placeTwapOrder, _HyperLiquidProvider_placeScaleOrder, _HyperLiquidProvider_startChaseSession, _HyperLiquidProvider_getChaseQuotePrice, _HyperLiquidProvider_restChaseOrder, _HyperLiquidProvider_scheduleChaseTick, _HyperLiquidProvider_recoverFailedChaseTick, _HyperLiquidProvider_runChaseTick, _HyperLiquidProvider_resolveOwnRestingSizes, _HyperLiquidProvider_readOrderRemainder, _HyperLiquidProvider_cancelChaseChild, _HyperLiquidProvider_retractOrphanedChaseOrder, _HyperLiquidProvider_stopChaseSession, _HyperLiquidProvider_cancelStrategyOrder, _HyperLiquidProvider_cancelTwapOrder, _HyperLiquidProvider_cancelScaleOrder, _HyperLiquidProvider_cancelChaseOrder, _HyperLiquidProvider_readOrderIdFromStatus, _HyperLiquidProvider_getDiscountedBuilderFee, _HyperLiquidProvider_fetchOpenOrders, _HyperLiquidProvider_resolveReplacementOrderId, _HyperLiquidProvider_getStandaloneValidatedDexs, _HyperLiquidProvider_queryDexPositions, _HyperLiquidProvider_getAllMids, _HyperLiquidProvider_fetchSingleDexFresh, _HyperLiquidProvider_excludeNonUsdcCollateralResults, _HyperLiquidProvider_mergeDexResultsInto, _HyperLiquidProvider_cacheFreshMarketDataSnapshot, _HyperLiquidProvider_getStaleMarketDataSnapshot, _HyperLiquidProvider_isFeeCacheValid, _HyperLiquidProvider_getBuilderAddress, _HyperLiquidProvider_getReferralCode, _HyperLiquidProvider_ensureReferralSet, _HyperLiquidProvider_isReferralCodeReady, _HyperLiquidProvider_checkReferralSet, _HyperLiquidProvider_setReferralCode;
13
+ var _HyperLiquidProvider_instances, _HyperLiquidProvider_deps, _HyperLiquidProvider_clientService, _HyperLiquidProvider_walletService, _HyperLiquidProvider_subscriptionService, _HyperLiquidProvider_symbolToAssetId, _HyperLiquidProvider_userFeeCache, _HyperLiquidProvider_maxLeverageCache, _HyperLiquidProvider_cachedMetaByDex, _HyperLiquidProvider_cachedMarketDataWithPrices, _HyperLiquidProvider_cachedSpotMeta, _HyperLiquidProvider_dexDiscoveryCache, _HyperLiquidProvider_referralCheckCache, _HyperLiquidProvider_builderFeeCheckCache, _HyperLiquidProvider_ensureReadyPromise, _HyperLiquidProvider_pendingBuilderFeeApprovals, _HyperLiquidProvider_compiledAllowlistPatterns, _HyperLiquidProvider_compiledBlocklistPatterns, _HyperLiquidProvider_userFeeDiscountBips, _HyperLiquidProvider_hip3Enabled, _HyperLiquidProvider_allowlistMarkets, _HyperLiquidProvider_blocklistMarkets, _HyperLiquidProvider_useUnifiedAccount, _HyperLiquidProvider_dexDiscoveryComplete, _HyperLiquidProvider_unifiedAccountSetupNeedsRetry, _HyperLiquidProvider_pendingValidatedDexsPromise, _HyperLiquidProvider_cachedUsdcTokenId, _HyperLiquidProvider_errorMappings, _HyperLiquidProvider_clientsInitialized, _HyperLiquidProvider_initializationPromise, _HyperLiquidProvider_messenger, _HyperLiquidProvider_builderAddressTestnet, _HyperLiquidProvider_builderAddressMainnet, _HyperLiquidProvider_priceDeviationLimit, _HyperLiquidProvider_compilePatternsSafely, _HyperLiquidProvider_ensureClientsInitialized, _HyperLiquidProvider_isWalletOnHyperliquid, _HyperLiquidProvider_isHyperliquidMultiSigAccount, _HyperLiquidProvider_ensureUnifiedAccountEnabled, _HyperLiquidProvider_ensureReady, _HyperLiquidProvider_tradingSetupPromise, _HyperLiquidProvider_tradingSetupComplete, _HyperLiquidProvider_ensureReadyForTrading, _HyperLiquidProvider_getOrFetchPrice, _HyperLiquidProvider_filterFills, _HyperLiquidProvider_getAllAvailableDexs, _HyperLiquidProvider_getValidatedDexs, _HyperLiquidProvider_fetchValidatedDexsInternal, _HyperLiquidProvider_getCachedMeta, _HyperLiquidProvider_backfillAssetMapForDex, _HyperLiquidProvider_getAssetIdWithRepair, _HyperLiquidProvider_getCachedSpotMeta, _HyperLiquidProvider_getCachedPerpDexs, _HyperLiquidProvider_calculateHip3FeeMultiplier, _HyperLiquidProvider_getCacheKey, _HyperLiquidProvider_fetchMarketsForDex, _HyperLiquidProvider_getUsdcTokenId, _HyperLiquidProvider_isUsdcCollateralDex, _HyperLiquidProvider_buildAssetMapping, _HyperLiquidProvider_queryUserDataAcrossDexs, _HyperLiquidProvider_mapError, _HyperLiquidProvider_getErrorContext, _HyperLiquidProvider_isMappedAccountModeExchangeError, _HyperLiquidProvider_getTradingErrorContext, _HyperLiquidProvider_checkBuilderFeeApproval, _HyperLiquidProvider_ensureBuilderFeeApproval, _HyperLiquidProvider_checkBuilderFeeStatus, _HyperLiquidProvider_getBalanceForDex, _HyperLiquidProvider_findSourceDexWithBalance, _HyperLiquidProvider_autoTransferForHip3Order, _HyperLiquidProvider_autoTransferBackAfterClose, _HyperLiquidProvider_calculateHip3RequiredMargin, _HyperLiquidProvider_handleHip3PostOrderRebalance, _HyperLiquidProvider_handleHip3OrderRollback, _HyperLiquidProvider_validateOrderBeforePlacement, _HyperLiquidProvider_getAssetInfo, _HyperLiquidProvider_prepareAssetForTrading, _HyperLiquidProvider_handleHip3PreOrder, _HyperLiquidProvider_submitOrderWithRollback, _HyperLiquidProvider_handleOrderError, _HyperLiquidProvider_fetchOpenOrders, _HyperLiquidProvider_resolveReplacementOrderId, _HyperLiquidProvider_getStandaloneValidatedDexs, _HyperLiquidProvider_queryDexPositions, _HyperLiquidProvider_getAllMids, _HyperLiquidProvider_fetchSingleDexFresh, _HyperLiquidProvider_excludeNonUsdcCollateralResults, _HyperLiquidProvider_mergeDexResultsInto, _HyperLiquidProvider_cacheFreshMarketDataSnapshot, _HyperLiquidProvider_getStaleMarketDataSnapshot, _HyperLiquidProvider_isFeeCacheValid, _HyperLiquidProvider_getBuilderAddress, _HyperLiquidProvider_getReferralCode, _HyperLiquidProvider_ensureReferralSet, _HyperLiquidProvider_isReferralCodeReady, _HyperLiquidProvider_checkReferralSet, _HyperLiquidProvider_setReferralCode;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.HyperLiquidProvider = void 0;
16
16
  const utils_1 = require("@metamask/utils");
@@ -32,7 +32,6 @@ const errorUtils_js_1 = require("../utils/errorUtils.cjs");
32
32
  const hyperLiquidAbstraction_js_1 = require("../utils/hyperLiquidAbstraction.cjs");
33
33
  const hyperLiquidAdapter_js_1 = require("../utils/hyperLiquidAdapter.cjs");
34
34
  const hyperLiquidValidation_js_1 = require("../utils/hyperLiquidValidation.cjs");
35
- const idUtils_js_1 = require("../utils/idUtils.cjs");
36
35
  const marketDataTransform_js_1 = require("../utils/marketDataTransform.cjs");
37
36
  const marketUtils_js_1 = require("../utils/marketUtils.cjs");
38
37
  const orderCalculations_js_1 = require("../utils/orderCalculations.cjs");
@@ -47,137 +46,6 @@ const standaloneInfoClient_js_1 = require("../utils/standaloneInfoClient.cjs");
47
46
  * @returns The result of the operation.
48
47
  */
49
48
  const isStatusObject = (status) => typeof status === 'object' && status !== null;
50
- /**
51
- * Exchange messages that mean a cancel was refused because the order is not on
52
- * the book any more.
53
- *
54
- * HyperLiquid answers a cancel it cannot match with "Order was never placed,
55
- * already canceled, or filled." That is a rejection of the request but a
56
- * confirmation of what the caller wanted — nothing of that order is resting.
57
- * Every other rejection (multi-sig, a stale nonce, a rate limit) leaves the
58
- * order exactly where it was, which is a materially different outcome.
59
- */
60
- const ALREADY_GONE_CANCEL_MARKERS = [
61
- 'never placed',
62
- 'already canceled',
63
- 'already cancelled',
64
- 'order not found',
65
- ];
66
- /**
67
- * Classify one entry of a cancel response.
68
- *
69
- * @param status - A single status from the exchange's cancel response.
70
- * @returns Whether the order was cancelled, was already gone, or still rests.
71
- */
72
- const classifyCancelStatus = (status) => {
73
- if (status === 'success') {
74
- return 'cancelled';
75
- }
76
- const message = (isStatusObject(status) && typeof status.error === 'string'
77
- ? status.error
78
- : '').toLowerCase();
79
- return ALREADY_GONE_CANCEL_MARKERS.some((marker) => message.includes(marker))
80
- ? 'gone'
81
- : 'refused';
82
- };
83
- /**
84
- * Read the best price on one side of the book, discounting the chase's own
85
- * order.
86
- *
87
- * A chase rests one tick inside the spread, so its own order *is* the best
88
- * price on its side. Reading the raw book would therefore see the chase's own
89
- * quote every tick, conclude the touch has not moved, and never re-price —
90
- * masking exactly the adverse moves the strategy exists to follow. Levels this
91
- * provider occupies are netted down by what it holds there, and are skipped
92
- * entirely when nothing else is left on them.
93
- *
94
- * "Own" means *every* chase this provider is running on that side, not just the
95
- * one asking. Two chases on the same side each netting only themselves would
96
- * read the other as the external touch and improve on it, then improve on the
97
- * improvement — walking each other toward the opposite side of an unchanged
98
- * market.
99
- *
100
- * The sizes must be what the orders still have resting, not what they were
101
- * placed for: an order netted at its original size subtracts more than it
102
- * occupies, which can hide external liquidity sharing the level.
103
- *
104
- * @param levels - One side of the book, best-first.
105
- * @param ownByPrice - This provider's own resting size at each price.
106
- * @returns The best price other participants are showing, or null.
107
- */
108
- const readBestExternalPrice = (levels, ownByPrice) => {
109
- for (const level of levels ?? []) {
110
- const price = parseFloat(level.px);
111
- if (!Number.isFinite(price) || price <= 0) {
112
- continue;
113
- }
114
- const size = parseFloat(level.sz) - (ownByPrice.get(level.px) ?? 0);
115
- if (size > 0) {
116
- return price;
117
- }
118
- }
119
- return null;
120
- };
121
- /**
122
- * Narrow order params down to their strategy fields.
123
- *
124
- * Both validation entry points forward exactly this group, so a field added to
125
- * `StrategyOrderValidationParams` reaches both of them or neither.
126
- *
127
- * @param params - Order parameters.
128
- * @returns The strategy fields, as validation takes them.
129
- */
130
- const pickStrategyParams = (params) => ({
131
- twapDuration: params.twapDuration,
132
- twapRandomize: params.twapRandomize,
133
- scaleMinPrice: params.scaleMinPrice,
134
- scaleMaxPrice: params.scaleMaxPrice,
135
- scaleNumOrders: params.scaleNumOrders,
136
- chaseIntervalMs: params.chaseIntervalMs,
137
- chaseMaxDurationMs: params.chaseMaxDurationMs,
138
- chaseMaxRepricings: params.chaseMaxRepricings,
139
- });
140
- /**
141
- * Check a strategy placement's notional against the minimum the venue will
142
- * actually apply to it.
143
- *
144
- * The per-order minimum is charged against each order the venue receives, and a
145
- * strategy placement does not send one order:
146
- *
147
- * A `twap` is a single instruction the venue slices itself, so it is bounded by
148
- * the venue's own documented minimum for a TWAP rather than by the per-order
149
- * minimum that `validateOrder` has already applied.
150
- *
151
- * `scale` is deliberately absent. Its rungs are the orders the venue charges
152
- * the minimum against, and their sizes come from flooring onto the asset's size
153
- * grid with the remainder landing on the first rung — none of which is knowable
154
- * without `szDecimals`, which this check does not have. Every approximation
155
- * available here is unsound in one direction or the other, and the one that was
156
- * here rejected ladders whose submitted rungs all cleared the minimum.
157
- * `#buildScaleLadder` applies the exact per-rung check against the real grid
158
- * sizes, and it runs before anything is signed, so nothing is lost by leaving
159
- * the question to it.
160
- *
161
- * `chase` is absent too: it rests one order at a time, so the per-order minimum
162
- * the caller has already been checked against is the right bound.
163
- *
164
- * @param params - Notional parameters.
165
- * @param params.orderType - The order placement type.
166
- * @param params.orderValueUSD - Total notional of the placement, in USD.
167
- * @returns Validation result with isValid flag and optional error message.
168
- */
169
- const validateStrategyNotional = (params) => {
170
- const { orderType, orderValueUSD } = params;
171
- if (orderType === 'twap') {
172
- return orderValueUSD < perpsConfig_js_1.HYPERLIQUID_TWAP_LIMITS.MinNotionalUsd
173
- ? {
174
- isValid: false,
175
- error: perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_TWAP_NOTIONAL_TOO_SMALL,
176
- }
177
- : { isValid: true };
178
- }
179
- return { isValid: true };
180
- };
181
49
  /**
182
50
  * Collect the order IDs of every TP/SL child carried by a parent order.
183
51
  *
@@ -338,23 +206,6 @@ class HyperLiquidProvider {
338
206
  'multi-sig required': perpsErrorCodes_js_1.PERPS_ERROR_CODES.EXCHANGE_MULTI_SIG_REQUIRED,
339
207
  'invalid nonce': perpsErrorCodes_js_1.PERPS_ERROR_CODES.EXCHANGE_INVALID_NONCE,
340
208
  });
341
- // Scale ladders placed by this provider instance, keyed by group handle, so
342
- // one cancel can reach every rung. Cleared on disconnect; the rung IDs are
343
- // also returned to the caller as `OrderResult.childOrderIds`.
344
- _HyperLiquidProvider_scaleOrderGroups.set(this, new Map());
345
- // Chase sessions running on this provider instance, keyed by session handle.
346
- // Each owns a pending timer, so disconnect has to stop them.
347
- _HyperLiquidProvider_chaseSessions.set(this, new Map());
348
- // Chase placements that have reserved a slot against the venue's concurrency
349
- // cap but have not registered their session yet. Two round trips separate the
350
- // two, and a reservation is what keeps concurrent placements from both
351
- // passing the check.
352
- _HyperLiquidProvider_chasePlacementsInFlight.set(this, 0);
353
- // Bumped by every teardown that clears the chase registry. A placement
354
- // captures it before its round trips and refuses to register afterwards if it
355
- // has moved: a session registered after a disconnect would schedule a
356
- // background timer against a provider that has already been torn down.
357
- _HyperLiquidProvider_chaseGeneration.set(this, 0);
358
209
  // Track whether clients have been initialized (lazy initialization)
359
210
  _HyperLiquidProvider_clientsInitialized.set(this, false);
360
211
  // Promise-based lock to prevent race conditions in concurrent initialization
@@ -532,19 +383,10 @@ class HyperLiquidProvider {
532
383
  tpslLinkage: params.tpslLinkage,
533
384
  grouping: params.grouping,
534
385
  timeInForce: params.timeInForce,
535
- clientOrderId: params.clientOrderId,
536
- ...pickStrategyParams(params),
537
386
  });
538
387
  if (!validation.isValid) {
539
388
  throw new Error(validation.error);
540
389
  }
541
- // Strategy placements expand into an execution schedule rather than a
542
- // single order, so they leave the shared path here — before the order
543
- // array, the HIP-3 transfer, and the atomic single-order submit, none of
544
- // which describe what a TWAP, a ladder, or a chase does.
545
- if ((0, orderTypes_js_1.isStrategyOrderType)(params.orderType)) {
546
- return await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_placeStrategyOrder).call(this, params, params.orderType);
547
- }
548
390
  // Extract DEX name for API calls (main DEX = null)
549
391
  const { dex: dexName } = (0, hyperLiquidAdapter_js_1.parseAssetName)(params.symbol);
550
392
  // 1. Get asset info and current price before validation so price-less
@@ -711,14 +553,7 @@ class HyperLiquidProvider {
711
553
  // close, so the retry would either be rejected as "Reduce only order would
712
554
  // increase position" or resubmit an identical order. Surfacing the
713
555
  // minimum-value error names the real problem instead.
714
- //
715
- // Strategy placements are excluded for the same reason in a different
716
- // shape: the minimum applies to each TWAP slice and each ladder rung, not
717
- // to the total, so growing the total by 1.5% does not clear it.
718
- if (isMinimumOrderError &&
719
- retryCount === 0 &&
720
- !params.reduceOnly &&
721
- !(0, orderTypes_js_1.isStrategyOrderType)(params.orderType)) {
556
+ if (isMinimumOrderError && retryCount === 0 && !params.reduceOnly) {
722
557
  let adjustedUsdAmount;
723
558
  let originalValue;
724
559
  if (params.usdAmount) {
@@ -794,17 +629,6 @@ class HyperLiquidProvider {
794
629
  error: perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_EDIT_TRIGGER_UNSUPPORTED,
795
630
  };
796
631
  }
797
- // A strategy placement is not a single resting order, so there is nothing
798
- // for `modify` to rewrite: it would submit the edit as an ordinary
799
- // FrontendMarket modification and quietly drop the TWAP schedule, the
800
- // ladder, or the chase loop the caller asked for. Cancel by the strategy
801
- // handle and place again.
802
- if ((0, orderTypes_js_1.isStrategyOrderType)(params.newOrder.orderType)) {
803
- return {
804
- success: false,
805
- error: perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_EDIT_STRATEGY_UNSUPPORTED,
806
- };
807
- }
808
632
  // The WebSocket order cache is the cheap source for the resting order's
809
633
  // placement type, but it may be cold or stale.
810
634
  const cachedRestingOrder = __classPrivateFieldGet(this, _HyperLiquidProvider_subscriptionService, "f")
@@ -975,12 +799,6 @@ class HyperLiquidProvider {
975
799
  * @returns A promise that resolves to the result.
976
800
  */
977
801
  async cancelOrder(params) {
978
- // A strategy handle is not an exchange order ID, so it cannot go through
979
- // the single-order cancel below. Callers that omit `orderType` — every
980
- // existing one — keep the behaviour they have today.
981
- if (params.orderType && (0, orderTypes_js_1.isStrategyOrderType)(params.orderType)) {
982
- return await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_cancelStrategyOrder).call(this, params);
983
- }
984
802
  try {
985
803
  __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Canceling order:', params);
986
804
  // Hydrate the asset map before coin validation so a cold start (e.g.
@@ -3136,8 +2954,6 @@ class HyperLiquidProvider {
3136
2954
  tpslLinkage: params.tpslLinkage,
3137
2955
  grouping: params.grouping,
3138
2956
  timeInForce: params.timeInForce,
3139
- clientOrderId: params.clientOrderId,
3140
- ...pickStrategyParams(params),
3141
2957
  });
3142
2958
  if (!basicValidation.isValid) {
3143
2959
  return basicValidation;
@@ -3210,15 +3026,6 @@ class HyperLiquidProvider {
3210
3026
  error: perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_SIZE_MIN,
3211
3027
  };
3212
3028
  }
3213
- // A strategy placement's total clearing the per-order minimum does not
3214
- // mean the orders it expands into will.
3215
- const strategyMinimum = validateStrategyNotional({
3216
- orderType: params.orderType,
3217
- orderValueUSD,
3218
- });
3219
- if (!strategyMinimum.isValid) {
3220
- return strategyMinimum;
3221
- }
3222
3029
  }
3223
3030
  // Asset-specific leverage validation
3224
3031
  if (params.leverage && params.symbol) {
@@ -3984,17 +3791,11 @@ class HyperLiquidProvider {
3984
3791
  */
3985
3792
  async calculateFees(params) {
3986
3793
  const { orderType, isMaker = false, amount, symbol } = params;
3987
- // Every placement is charged as its execution kind: a stop_market fills as a
3988
- // market order (taker), a stop_limit as a limit order, a scale ladder as the
3989
- // resting limit orders it fans out into, and a TWAP as the marketable
3990
- // suborders it crosses the book with.
3794
+ // Trigger placements are charged as their execution kind: a stop_market fills
3795
+ // as a market order (taker), a stop_limit as a limit order.
3991
3796
  const isMarketExecution = (0, orderTypes_js_1.getTriggerExecution)(orderType) === 'market';
3992
- // A chase is post-only by construction, so it can only ever fill as a maker.
3993
- // Quoting it at the taker rate would overstate the fee whatever the caller
3994
- // passes for `isMaker`.
3995
- const chargesMakerRate = orderType === 'chase' || (!isMarketExecution && isMaker);
3996
3797
  // Start with base rates from config
3997
- let feeRate = chargesMakerRate ? hyperLiquidConfig_js_1.FEE_RATES.maker : hyperLiquidConfig_js_1.FEE_RATES.taker;
3798
+ let feeRate = isMarketExecution || !isMaker ? hyperLiquidConfig_js_1.FEE_RATES.taker : hyperLiquidConfig_js_1.FEE_RATES.maker;
3998
3799
  // Parse symbol to detect HIP-3 DEX (e.g., "xyz:TSLA" → dex="xyz", parsedSymbol="TSLA")
3999
3800
  const { dex, symbol: parsedSymbol } = (0, hyperLiquidAdapter_js_1.parseAssetName)(symbol);
4000
3801
  const isHip3Asset = dex !== null;
@@ -4038,12 +3839,10 @@ class HyperLiquidProvider {
4038
3839
  if (__classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_isFeeCacheValid).call(this, userAddress)) {
4039
3840
  const cached = __classPrivateFieldGet(this, _HyperLiquidProvider_userFeeCache, "f").get(userAddress);
4040
3841
  if (cached) {
4041
- // Same maker/taker decision as the base rates above, including the
4042
- // post-only chase case — re-deriving it here would quote a chase at
4043
- // the taker rate whenever the caller passed isMaker: false.
4044
- let userFeeRate = chargesMakerRate
4045
- ? cached.perpsMakerRate
4046
- : cached.perpsTakerRate;
3842
+ // Market orders always use taker rate, limit orders check isMaker
3843
+ let userFeeRate = isMarketExecution || !isMaker
3844
+ ? cached.perpsTakerRate
3845
+ : cached.perpsMakerRate;
4047
3846
  // Apply HIP-3 dynamic multiplier to user-specific rates (includes Growth Mode)
4048
3847
  if (isHip3Asset && hip3Multiplier > 0) {
4049
3848
  userFeeRate *= hip3Multiplier;
@@ -4148,10 +3947,10 @@ class HyperLiquidProvider {
4148
3947
  ttl: 5 * 60 * 1000, // 5 minutes
4149
3948
  };
4150
3949
  __classPrivateFieldGet(this, _HyperLiquidProvider_userFeeCache, "f").set(userAddress, rates);
4151
- // Same maker/taker decision as the base rates above, chase included.
4152
- let userFeeRate = chargesMakerRate
4153
- ? rates.perpsMakerRate
4154
- : rates.perpsTakerRate;
3950
+ // Market orders always use taker rate, limit orders check isMaker
3951
+ let userFeeRate = isMarketExecution || !isMaker
3952
+ ? rates.perpsTakerRate
3953
+ : rates.perpsMakerRate;
4155
3954
  // Apply HIP-3 dynamic multiplier to API-fetched rates (includes Growth Mode)
4156
3955
  if (isHip3Asset && hip3Multiplier > 0) {
4157
3956
  userFeeRate *= hip3Multiplier;
@@ -4280,17 +4079,6 @@ class HyperLiquidProvider {
4280
4079
  });
4281
4080
  // Clear subscriptions through subscription service
4282
4081
  __classPrivateFieldGet(this, _HyperLiquidProvider_subscriptionService, "f").clearAll();
4283
- // Stop every chase loop: each holds a pending timer, and re-pricing after
4284
- // a disconnect would sign orders against a client that is being torn down.
4285
- // Orders already resting are deliberately left alone — disconnecting is
4286
- // not a request to cancel the user's positions or orders.
4287
- for (const sessionId of __classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").keys()) {
4288
- __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_stopChaseSession).call(this, sessionId);
4289
- }
4290
- __classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").clear();
4291
- __classPrivateFieldGet(this, _HyperLiquidProvider_scaleOrderGroups, "f").clear();
4292
- // Placements still mid-flight check this before registering.
4293
- __classPrivateFieldSet(this, _HyperLiquidProvider_chaseGeneration, __classPrivateFieldGet(this, _HyperLiquidProvider_chaseGeneration, "f") + 1, "f");
4294
4082
  // Clear fee cache
4295
4083
  this.clearFeeCache();
4296
4084
  // Clear session caches (ensures fresh state on reconnect/account switch)
@@ -4477,7 +4265,7 @@ class HyperLiquidProvider {
4477
4265
  }
4478
4266
  }
4479
4267
  exports.HyperLiquidProvider = HyperLiquidProvider;
4480
- _HyperLiquidProvider_deps = new WeakMap(), _HyperLiquidProvider_clientService = new WeakMap(), _HyperLiquidProvider_walletService = new WeakMap(), _HyperLiquidProvider_subscriptionService = new WeakMap(), _HyperLiquidProvider_symbolToAssetId = new WeakMap(), _HyperLiquidProvider_userFeeCache = new WeakMap(), _HyperLiquidProvider_maxLeverageCache = new WeakMap(), _HyperLiquidProvider_cachedMetaByDex = new WeakMap(), _HyperLiquidProvider_cachedMarketDataWithPrices = new WeakMap(), _HyperLiquidProvider_cachedSpotMeta = new WeakMap(), _HyperLiquidProvider_dexDiscoveryCache = new WeakMap(), _HyperLiquidProvider_referralCheckCache = new WeakMap(), _HyperLiquidProvider_builderFeeCheckCache = new WeakMap(), _HyperLiquidProvider_ensureReadyPromise = new WeakMap(), _HyperLiquidProvider_pendingBuilderFeeApprovals = new WeakMap(), _HyperLiquidProvider_compiledAllowlistPatterns = new WeakMap(), _HyperLiquidProvider_compiledBlocklistPatterns = new WeakMap(), _HyperLiquidProvider_userFeeDiscountBips = new WeakMap(), _HyperLiquidProvider_hip3Enabled = new WeakMap(), _HyperLiquidProvider_allowlistMarkets = new WeakMap(), _HyperLiquidProvider_blocklistMarkets = new WeakMap(), _HyperLiquidProvider_useUnifiedAccount = new WeakMap(), _HyperLiquidProvider_dexDiscoveryComplete = new WeakMap(), _HyperLiquidProvider_unifiedAccountSetupNeedsRetry = new WeakMap(), _HyperLiquidProvider_pendingValidatedDexsPromise = new WeakMap(), _HyperLiquidProvider_cachedUsdcTokenId = new WeakMap(), _HyperLiquidProvider_errorMappings = new WeakMap(), _HyperLiquidProvider_scaleOrderGroups = new WeakMap(), _HyperLiquidProvider_chaseSessions = new WeakMap(), _HyperLiquidProvider_chasePlacementsInFlight = new WeakMap(), _HyperLiquidProvider_chaseGeneration = new WeakMap(), _HyperLiquidProvider_clientsInitialized = new WeakMap(), _HyperLiquidProvider_initializationPromise = new WeakMap(), _HyperLiquidProvider_messenger = new WeakMap(), _HyperLiquidProvider_builderAddressTestnet = new WeakMap(), _HyperLiquidProvider_builderAddressMainnet = new WeakMap(), _HyperLiquidProvider_priceDeviationLimit = new WeakMap(), _HyperLiquidProvider_tradingSetupPromise = new WeakMap(), _HyperLiquidProvider_tradingSetupComplete = new WeakMap(), _HyperLiquidProvider_instances = new WeakSet(), _HyperLiquidProvider_compilePatternsSafely = function _HyperLiquidProvider_compilePatternsSafely(patterns, listName) {
4268
+ _HyperLiquidProvider_deps = new WeakMap(), _HyperLiquidProvider_clientService = new WeakMap(), _HyperLiquidProvider_walletService = new WeakMap(), _HyperLiquidProvider_subscriptionService = new WeakMap(), _HyperLiquidProvider_symbolToAssetId = new WeakMap(), _HyperLiquidProvider_userFeeCache = new WeakMap(), _HyperLiquidProvider_maxLeverageCache = new WeakMap(), _HyperLiquidProvider_cachedMetaByDex = new WeakMap(), _HyperLiquidProvider_cachedMarketDataWithPrices = new WeakMap(), _HyperLiquidProvider_cachedSpotMeta = new WeakMap(), _HyperLiquidProvider_dexDiscoveryCache = new WeakMap(), _HyperLiquidProvider_referralCheckCache = new WeakMap(), _HyperLiquidProvider_builderFeeCheckCache = new WeakMap(), _HyperLiquidProvider_ensureReadyPromise = new WeakMap(), _HyperLiquidProvider_pendingBuilderFeeApprovals = new WeakMap(), _HyperLiquidProvider_compiledAllowlistPatterns = new WeakMap(), _HyperLiquidProvider_compiledBlocklistPatterns = new WeakMap(), _HyperLiquidProvider_userFeeDiscountBips = new WeakMap(), _HyperLiquidProvider_hip3Enabled = new WeakMap(), _HyperLiquidProvider_allowlistMarkets = new WeakMap(), _HyperLiquidProvider_blocklistMarkets = new WeakMap(), _HyperLiquidProvider_useUnifiedAccount = new WeakMap(), _HyperLiquidProvider_dexDiscoveryComplete = new WeakMap(), _HyperLiquidProvider_unifiedAccountSetupNeedsRetry = new WeakMap(), _HyperLiquidProvider_pendingValidatedDexsPromise = new WeakMap(), _HyperLiquidProvider_cachedUsdcTokenId = new WeakMap(), _HyperLiquidProvider_errorMappings = new WeakMap(), _HyperLiquidProvider_clientsInitialized = new WeakMap(), _HyperLiquidProvider_initializationPromise = new WeakMap(), _HyperLiquidProvider_messenger = new WeakMap(), _HyperLiquidProvider_builderAddressTestnet = new WeakMap(), _HyperLiquidProvider_builderAddressMainnet = new WeakMap(), _HyperLiquidProvider_priceDeviationLimit = new WeakMap(), _HyperLiquidProvider_tradingSetupPromise = new WeakMap(), _HyperLiquidProvider_tradingSetupComplete = new WeakMap(), _HyperLiquidProvider_instances = new WeakSet(), _HyperLiquidProvider_compilePatternsSafely = function _HyperLiquidProvider_compilePatternsSafely(patterns, listName) {
4481
4269
  const compiled = [];
4482
4270
  for (const pattern of patterns) {
4483
4271
  try {
@@ -6581,1056 +6369,6 @@ async function _HyperLiquidProvider_handleOrderError(params) {
6581
6369
  }));
6582
6370
  }
6583
6371
  return (0, hyperLiquidValidation_js_1.createErrorResult)(mappedError, { success: false });
6584
- }, _HyperLiquidProvider_placeStrategyOrder =
6585
- /**
6586
- * Dispatch a strategy placement to the handler that owns it.
6587
- *
6588
- * @param params - Order parameters, already validated.
6589
- * @param orderType - The strategy type, narrowed by the caller.
6590
- * @returns A promise that resolves to the result.
6591
- */
6592
- async function _HyperLiquidProvider_placeStrategyOrder(params, orderType) {
6593
- // Captured before the shared preamble, not after it: that preamble awaits
6594
- // asset info, validation, trading readiness and a leverage update, and a
6595
- // disconnect during any of them has to be seen by the chase registration
6596
- // at the end.
6597
- const generation = __classPrivateFieldGet(this, _HyperLiquidProvider_chaseGeneration, "f");
6598
- if (orderType !== 'chase') {
6599
- const context = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_prepareStrategyPlacement).call(this, params);
6600
- return orderType === 'twap'
6601
- ? await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_placeTwapOrder).call(this, params, context)
6602
- : await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_placeScaleOrder).call(this, params, context);
6603
- }
6604
- // The chase slot is claimed before the preamble, not after it: the preamble
6605
- // completes the signing setup and can change the asset's leverage, and a
6606
- // request that is going to be refused for exceeding the venue's cap must
6607
- // not cost either. Reserved in the same synchronous step it is checked, so
6608
- // concurrent placements cannot both see room during the round trips that
6609
- // follow.
6610
- const activeChases = [...__classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").values()].filter((session) => session.active).length;
6611
- if (activeChases + __classPrivateFieldGet(this, _HyperLiquidProvider_chasePlacementsInFlight, "f") >=
6612
- perpsConfig_js_1.CHASE_ORDER_CONFIG.MaxActiveSessions) {
6613
- throw new Error(perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_CHASE_LIMIT_REACHED);
6614
- }
6615
- __classPrivateFieldSet(this, _HyperLiquidProvider_chasePlacementsInFlight, __classPrivateFieldGet(this, _HyperLiquidProvider_chasePlacementsInFlight, "f") + 1, "f");
6616
- try {
6617
- const context = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_prepareStrategyPlacement).call(this, params);
6618
- return await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_startChaseSession).call(this, params, context, generation);
6619
- }
6620
- finally {
6621
- __classPrivateFieldSet(this, _HyperLiquidProvider_chasePlacementsInFlight, __classPrivateFieldGet(this, _HyperLiquidProvider_chasePlacementsInFlight, "f") - 1, "f");
6622
- }
6623
- }, _HyperLiquidProvider_prepareStrategyPlacement =
6624
- /**
6625
- * Run the shared preamble every strategy placement needs.
6626
- *
6627
- * Mirrors the single-order path's own preamble — validate against a live
6628
- * price, complete the signing setup, resolve the asset ID, apply leverage —
6629
- * so a strategy order is held to the same rules as an ordinary one.
6630
- *
6631
- * @param params - Order parameters.
6632
- * @returns The asset and sizing context the strategy handlers submit with.
6633
- */
6634
- async function _HyperLiquidProvider_prepareStrategyPlacement(params) {
6635
- const { dex: dexName } = (0, hyperLiquidAdapter_js_1.parseAssetName)(params.symbol);
6636
- // A HIP-3 order is preceded by a margin transfer onto the builder DEX and
6637
- // followed by a rebalance, both of which are wired into the single-order
6638
- // submit path and its rollback. Rather than half-support that here, a
6639
- // strategy placement on a HIP-3 market is refused outright.
6640
- if (dexName !== null) {
6641
- throw new Error(perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_STRATEGY_MARKET_UNSUPPORTED);
6642
- }
6643
- const { assetInfo, currentPrice, meta } = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getAssetInfo).call(this, {
6644
- symbol: params.symbol,
6645
- dexName,
6646
- });
6647
- const effectivePrice = params.currentPrice && params.currentPrice > 0
6648
- ? params.currentPrice
6649
- : currentPrice;
6650
- await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_validateOrderBeforePlacement).call(this, {
6651
- ...params,
6652
- currentPrice: effectivePrice,
6653
- });
6654
- const normalizedMaxSlippageBps = params.maxSlippageBps ??
6655
- (typeof params.slippage === 'number'
6656
- ? Math.round(params.slippage * hyperLiquidConfig_js_1.BASIS_POINTS_DIVISOR)
6657
- : undefined);
6658
- const { finalPositionSize } = (0, orderCalculations_js_1.calculateFinalPositionSize)({
6659
- usdAmount: params.usdAmount,
6660
- size: params.size,
6661
- currentPrice: effectivePrice,
6662
- priceAtCalculation: params.priceAtCalculation,
6663
- maxSlippageBps: normalizedMaxSlippageBps,
6664
- szDecimals: assetInfo.szDecimals,
6665
- leverage: params.leverage,
6666
- reduceOnly: params.reduceOnly,
6667
- });
6668
- const formattedSize = (0, hyperLiquidAdapter_js_1.formatHyperLiquidSize)({
6669
- size: finalPositionSize,
6670
- szDecimals: assetInfo.szDecimals,
6671
- });
6672
- // Everything below is checked here, before anything is signed: it needs
6673
- // `szDecimals`, which only arrives with the asset info above, and these are
6674
- // caller mistakes that must not cost a leverage change or a signing prompt
6675
- // first.
6676
- const ladder = params.orderType === 'scale'
6677
- ? __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_buildScaleLadder).call(this, {
6678
- params,
6679
- szDecimals: assetInfo.szDecimals,
6680
- finalPositionSize,
6681
- })
6682
- : undefined;
6683
- // `validateOrder` applied the venue minimum to the notional the caller
6684
- // asked for; this applies it to the size actually being submitted. The two
6685
- // differ whenever sizing floors onto the grid rather than rounding up to
6686
- // meet the requested USD — which is exactly what a reduce-only order does,
6687
- // since the venue rejects a close larger than the position. A boundary
6688
- // amount can therefore clear the check the caller sees and still arrive
6689
- // under the minimum the venue charges against what it receives.
6690
- if (params.orderType === 'twap' || params.orderType === 'chase') {
6691
- const submittedNotional = parseFloat(formattedSize) * effectivePrice;
6692
- const minimumNotional = params.orderType === 'twap'
6693
- ? perpsConfig_js_1.HYPERLIQUID_TWAP_LIMITS.MinNotionalUsd
6694
- : __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getMinimumOrderSize).call(this);
6695
- if (submittedNotional < minimumNotional) {
6696
- throw new Error(params.orderType === 'twap'
6697
- ? perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_TWAP_NOTIONAL_TOO_SMALL
6698
- : perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_SIZE_MIN);
6699
- }
6700
- }
6701
- // Kept after validation so an invalid strategy order never triggers the
6702
- // signature prompts in trading setup — same ordering as `placeOrder`.
6703
- await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureReadyForTrading).call(this);
6704
- const assetId = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getAssetIdWithRepair).call(this, {
6705
- symbol: params.symbol,
6706
- dexName,
6707
- meta,
6708
- });
6709
- await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_prepareAssetForTrading).call(this, {
6710
- symbol: params.symbol,
6711
- assetId,
6712
- leverage: params.leverage,
6713
- });
6714
- return {
6715
- assetId,
6716
- szDecimals: assetInfo.szDecimals,
6717
- finalPositionSize,
6718
- formattedSize,
6719
- ladder,
6720
- };
6721
- }, _HyperLiquidProvider_getMinimumOrderSize = function _HyperLiquidProvider_getMinimumOrderSize() {
6722
- return __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").isTestnetMode()
6723
- ? hyperLiquidConfig_js_1.TRADING_DEFAULTS.amount.testnet
6724
- : hyperLiquidConfig_js_1.TRADING_DEFAULTS.amount.mainnet;
6725
- }, _HyperLiquidProvider_buildScaleLadder = function _HyperLiquidProvider_buildScaleLadder(options) {
6726
- const { params, szDecimals, finalPositionSize } = options;
6727
- const count = params.scaleNumOrders;
6728
- const prices = (0, orderCalculations_js_1.computeScalePriceLadder)({
6729
- minPrice: parseFloat(params.scaleMinPrice),
6730
- maxPrice: parseFloat(params.scaleMaxPrice),
6731
- count,
6732
- }).map((price) => (0, hyperLiquidAdapter_js_1.formatHyperLiquidPrice)({ price, szDecimals }));
6733
- if (new Set(prices).size !== prices.length) {
6734
- throw new Error(perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_SCALE_RANGE_INVALID);
6735
- }
6736
- // Throws ORDER_SCALE_SIZE_TOO_SMALL when a rung would round to nothing.
6737
- const sizes = (0, orderCalculations_js_1.splitScaleSizes)({
6738
- totalSize: finalPositionSize,
6739
- count,
6740
- szDecimals,
6741
- });
6742
- const minimumOrderSize = __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getMinimumOrderSize).call(this);
6743
- const cheapestRungNotional = Math.min(...sizes.map((size, index) => parseFloat(size) * parseFloat(prices[index])));
6744
- if (cheapestRungNotional < minimumOrderSize) {
6745
- throw new Error(perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_SCALE_NOTIONAL_TOO_SMALL);
6746
- }
6747
- return { prices, sizes };
6748
- }, _HyperLiquidProvider_placeTwapOrder =
6749
- /**
6750
- * Submit a TWAP through HyperLiquid's dedicated TWAP action.
6751
- *
6752
- * A TWAP is not an order on the book, so it does not go through the `order`
6753
- * action, carries no builder fee, and comes back identified by a `twapId`
6754
- * rather than an `oid`. That ID is the handle `cancelOrder` needs.
6755
- *
6756
- * @param params - Order parameters.
6757
- * @param context - Prepared asset and sizing context.
6758
- * @returns A promise that resolves to the result.
6759
- */
6760
- async function _HyperLiquidProvider_placeTwapOrder(params, context) {
6761
- const { assetId, formattedSize } = context;
6762
- const exchangeClient = __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").getExchangeClient();
6763
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Submitting TWAP order', {
6764
- symbol: params.symbol,
6765
- assetId,
6766
- size: formattedSize,
6767
- durationMinutes: params.twapDuration,
6768
- randomize: params.twapRandomize ?? false,
6769
- });
6770
- const result = await exchangeClient.twapOrder({
6771
- twap: {
6772
- a: assetId,
6773
- b: params.isBuy,
6774
- s: formattedSize,
6775
- r: params.reduceOnly ?? false,
6776
- // Validation has already established this is a whole number of minutes
6777
- // inside the venue's bounds.
6778
- m: params.twapDuration,
6779
- t: params.twapRandomize ?? false,
6780
- },
6781
- });
6782
- if (result.status !== 'ok') {
6783
- throw new Error(`TWAP order failed: ${JSON.stringify(result)}`);
6784
- }
6785
- const status = result.response?.data?.status;
6786
- if (!isStatusObject(status) || !(0, utils_1.hasProperty)(status, 'running')) {
6787
- const rawError = status?.error ??
6788
- 'TWAP order rejected';
6789
- throw new Error(rawError);
6790
- }
6791
- const running = status.running;
6792
- return {
6793
- success: true,
6794
- orderId: running.twapId.toString(),
6795
- submittedSize: formattedSize,
6796
- };
6797
- }, _HyperLiquidProvider_placeScaleOrder =
6798
- /**
6799
- * Fan a scale placement out into one batch of resting limit orders.
6800
- *
6801
- * The whole ladder goes in a single `order` action, which is one round trip
6802
- * and one signature rather than one per rung. It is **not** atomic: an `na`
6803
- * grouping evaluates each entry independently, so the response can report
6804
- * some rungs resting and others rejected. A partial ladder is reported as
6805
- * such — `submittedSize` covers only the rungs that actually rested — rather
6806
- * than as a full submission.
6807
- *
6808
- * @param params - Order parameters.
6809
- * @param context - Prepared asset and sizing context.
6810
- * @returns A promise that resolves to the result.
6811
- */
6812
- async function _HyperLiquidProvider_placeScaleOrder(params, context) {
6813
- const { assetId, szDecimals, formattedSize, ladder } = context;
6814
- // Built and validated in `#prepareStrategyPlacement`, before anything was
6815
- // signed, so what is submitted here is exactly what the minimums were
6816
- // applied to.
6817
- const { prices, sizes } = ladder;
6818
- const count = prices.length;
6819
- const orders = prices.map((price, index) => ({
6820
- a: assetId,
6821
- b: params.isBuy,
6822
- p: price,
6823
- s: sizes[index],
6824
- r: params.reduceOnly ?? false,
6825
- t: { limit: { tif: 'Gtc' } },
6826
- }));
6827
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Submitting scale ladder', {
6828
- symbol: params.symbol,
6829
- assetId,
6830
- count,
6831
- prices: orders.map((order) => order.p),
6832
- sizes,
6833
- });
6834
- const exchangeClient = __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").getExchangeClient();
6835
- const result = await exchangeClient.order({
6836
- orders,
6837
- grouping: 'na',
6838
- builder: {
6839
- b: __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getBuilderAddress).call(this, __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").isTestnetMode()),
6840
- f: __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getDiscountedBuilderFee).call(this),
6841
- },
6842
- });
6843
- if (result.status !== 'ok') {
6844
- throw new Error(`Scale order failed: ${JSON.stringify(result)}`);
6845
- }
6846
- const statuses = result.response?.data?.statuses ?? [];
6847
- // Which rung each ID came from matters: `submittedSize` has to add up the
6848
- // slices that actually rested, not the total that was asked for.
6849
- const restedRungs = statuses
6850
- .map((status, index) => ({
6851
- orderId: __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_readOrderIdFromStatus).call(this, status),
6852
- size: sizes[index],
6853
- }))
6854
- .filter((rung) => rung.orderId !== undefined);
6855
- // A ladder that came back with no IDs at all rested nothing; reporting it
6856
- // as a success would hand the caller a handle that cancels nothing.
6857
- if (restedRungs.length === 0) {
6858
- throw new Error(`Scale order rejected: ${JSON.stringify(result.response?.data)}`);
6859
- }
6860
- const childOrderIds = restedRungs.map((rung) => rung.orderId);
6861
- const groupId = (0, idUtils_js_1.generatePerpsId)('scale');
6862
- __classPrivateFieldGet(this, _HyperLiquidProvider_scaleOrderGroups, "f").set(groupId, { assetId, orderIds: childOrderIds });
6863
- // The batch is not atomic, so a ladder can come back part-rested. Reporting
6864
- // the requested total as submitted would tell the caller they are exposed
6865
- // for more than they are.
6866
- const isPartial = restedRungs.length < count;
6867
- if (isPartial) {
6868
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Scale ladder only partly rested', {
6869
- groupId,
6870
- rested: restedRungs.length,
6871
- requested: count,
6872
- statuses,
6873
- });
6874
- }
6875
- return {
6876
- success: true,
6877
- orderId: groupId,
6878
- childOrderIds,
6879
- submittedSize: isPartial
6880
- ? (0, hyperLiquidAdapter_js_1.formatHyperLiquidSize)({
6881
- size: restedRungs.reduce((total, rung) => total + parseFloat(rung.size), 0),
6882
- szDecimals,
6883
- })
6884
- : formattedSize,
6885
- };
6886
- }, _HyperLiquidProvider_startChaseSession =
6887
- /**
6888
- * Place a chase's first order and register the session that follows it.
6889
- *
6890
- * Split from the routing above so the concurrency reservation there wraps
6891
- * every await in one `try`/`finally`.
6892
- *
6893
- * @param params - Order parameters.
6894
- * @param context - Prepared asset and sizing context.
6895
- * @param generation - Teardown generation captured before any await.
6896
- * @returns A promise that resolves to the result.
6897
- */
6898
- async function _HyperLiquidProvider_startChaseSession(params, context, generation) {
6899
- const { assetId, szDecimals, formattedSize } = context;
6900
- // The preamble is several round trips long. A disconnect during it has
6901
- // already torn down everything this session would run on, so the chase
6902
- // stops here rather than reading the book and putting a fresh order on it
6903
- // for a provider that no longer exists.
6904
- if (generation !== __classPrivateFieldGet(this, _HyperLiquidProvider_chaseGeneration, "f")) {
6905
- throw new Error(perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_CHASE_ABANDONED);
6906
- }
6907
- const quotePrice = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getChaseQuotePrice).call(this, {
6908
- symbol: params.symbol,
6909
- isBuy: params.isBuy,
6910
- szDecimals,
6911
- });
6912
- if (quotePrice === 'gone') {
6913
- // No own order to be gone on a first placement; narrows the union.
6914
- throw new Error(perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_CHASE_TOUCH_UNAVAILABLE);
6915
- }
6916
- // The book read is a round trip of its own, so the check above does not
6917
- // cover it. Re-checked here, immediately before the only statement that
6918
- // signs anything: every await on this path is now followed by a refusal
6919
- // before the next one, leaving one window that cannot be closed from here
6920
- // — a disconnect arriving while the submission itself is in flight, which
6921
- // the check after it handles.
6922
- if (generation !== __classPrivateFieldGet(this, _HyperLiquidProvider_chaseGeneration, "f")) {
6923
- throw new Error(perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_CHASE_ABANDONED);
6924
- }
6925
- // Read once, while the caller's discount context is still set.
6926
- const builderFee = __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getDiscountedBuilderFee).call(this);
6927
- // Held onto rather than looked up again after the submission returns.
6928
- // `disconnect` drops the service's client reference synchronously, so a
6929
- // retraction that asked for a client after the fact would be refused one
6930
- // and leave the order resting under the account that placed it. This
6931
- // instance signed the order and can still cancel it as that account.
6932
- const placingClient = __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").getExchangeClient();
6933
- const orderId = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_restChaseOrder).call(this, {
6934
- assetId,
6935
- isBuy: params.isBuy,
6936
- price: quotePrice,
6937
- size: formattedSize,
6938
- reduceOnly: params.reduceOnly ?? false,
6939
- builderFee,
6940
- exchangeClient: placingClient,
6941
- });
6942
- const intervalMs = params.chaseIntervalMs ?? perpsConfig_js_1.CHASE_ORDER_CONFIG.DefaultIntervalMs;
6943
- const sessionId = (0, idUtils_js_1.generatePerpsId)('chase');
6944
- const session = {
6945
- symbol: params.symbol,
6946
- assetId,
6947
- isBuy: params.isBuy,
6948
- size: formattedSize,
6949
- szDecimals,
6950
- reduceOnly: params.reduceOnly ?? false,
6951
- orderId,
6952
- pendingReplacement: null,
6953
- restingPrice: quotePrice,
6954
- intervalMs,
6955
- builderFee,
6956
- deadline: Date.now() +
6957
- (params.chaseMaxDurationMs ?? perpsConfig_js_1.CHASE_ORDER_CONFIG.DefaultMaxDurationMs),
6958
- maxRepricings: params.chaseMaxRepricings ?? perpsConfig_js_1.CHASE_ORDER_CONFIG.DefaultMaxRepricings,
6959
- repricings: 0,
6960
- timer: null,
6961
- active: true,
6962
- };
6963
- // A disconnect landed while the submission was in flight — the one window
6964
- // the checks above cannot close. The order rested, but no strategy is
6965
- // running behind it and no handle names it, so this placement is reported
6966
- // as a failure. That makes the resting order an orphan: the caller is told
6967
- // the chase failed, nothing refreshes the caches a successful placement
6968
- // would have invalidated, and the exchange id is only usable for as long as
6969
- // the provider stays pointed at the account that placed it — a disconnect
6970
- // is usually followed by an account or network switch, after which handing
6971
- // the id back is no remedy at all. So it is cancelled here, through the
6972
- // client that signed it — the account switch cannot reach that instance —
6973
- // and the failure is then true of the venue as well as of this provider.
6974
- // Best-effort still: the transport underneath that client may already be
6975
- // closing, so a cancel that does not land falls back to reporting the id.
6976
- if (generation !== __classPrivateFieldGet(this, _HyperLiquidProvider_chaseGeneration, "f")) {
6977
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase placement outlived its provider', {
6978
- orderId,
6979
- restingPrice: quotePrice,
6980
- });
6981
- const outcome = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_retractOrphanedChaseOrder).call(this, session, placingClient);
6982
- return (0, hyperLiquidValidation_js_1.createErrorResult)(new Error(perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_CHASE_ABANDONED), {
6983
- success: false,
6984
- // Reported only when the retraction did not take. Naming an order
6985
- // that is no longer on the book would send the caller to cancel
6986
- // something already gone; naming one that still rests is the only
6987
- // route left to it.
6988
- ...(outcome === 'refused' ? { childOrderIds: [orderId] } : {}),
6989
- submittedSize: formattedSize,
6990
- });
6991
- }
6992
- __classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").set(sessionId, session);
6993
- __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_scheduleChaseTick).call(this, sessionId);
6994
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase session started', {
6995
- sessionId,
6996
- symbol: params.symbol,
6997
- orderId,
6998
- restingPrice: quotePrice,
6999
- intervalMs,
7000
- });
7001
- return {
7002
- success: true,
7003
- orderId: sessionId,
7004
- childOrderIds: [orderId],
7005
- submittedSize: formattedSize,
7006
- };
7007
- }, _HyperLiquidProvider_getChaseQuotePrice =
7008
- /**
7009
- * Read the price a chase must rest at: the best bid for a buy, the best ask
7010
- * for a sell.
7011
- *
7012
- * The touch, not the mid: a post-only order priced at the mid would either
7013
- * cross or be rejected, and a chase that never rests at the front of the
7014
- * queue is not chasing anything.
7015
- *
7016
- * @param params - The lookup parameters.
7017
- * @param params.symbol - Market to read.
7018
- * @param params.isBuy - Which side the chase rests on.
7019
- * @param params.szDecimals - Asset size precision, for price formatting.
7020
- * @param params.own - The chase's own resting order, excluded from the book.
7021
- * @param params.own.orderId - Exchange ID of that order.
7022
- * @param params.own.price - Price that order rests at.
7023
- * @param params.own.size - Size it was last placed for.
7024
- * @returns The formatted price the chase should rest at, or `'gone'` when the
7025
- * order it was chasing is no longer live.
7026
- */
7027
- async function _HyperLiquidProvider_getChaseQuotePrice(params) {
7028
- const { symbol, isBuy, szDecimals, own } = params;
7029
- const book = await __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").getInfoClient().l2Book({
7030
- coin: symbol,
7031
- });
7032
- // `levels` is [bids, asks], each best-first.
7033
- const ownSide = book?.levels?.[isBuy ? 0 : 1];
7034
- const netting = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_resolveOwnRestingSizes).call(this, {
7035
- symbol,
7036
- isBuy,
7037
- callerOrderId: own?.orderId,
7038
- ownSide,
7039
- });
7040
- if (netting === 'gone') {
7041
- return 'gone';
7042
- }
7043
- const bestBid = readBestExternalPrice(book?.levels?.[0], netting);
7044
- const bestAsk = readBestExternalPrice(book?.levels?.[1], netting);
7045
- if (bestBid === null || bestAsk === null) {
7046
- throw new Error(perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_CHASE_TOUCH_UNAVAILABLE);
7047
- }
7048
- return (0, orderCalculations_js_1.computeChaseQuotePrice)({ bestBid, bestAsk, isBuy, szDecimals });
7049
- }, _HyperLiquidProvider_restChaseOrder =
7050
- /**
7051
- * Rest one post-only order for a chase and return its exchange ID.
7052
- *
7053
- * @param params - The placement parameters.
7054
- * @param params.assetId - Resolved asset ID.
7055
- * @param params.isBuy - Order side.
7056
- * @param params.price - Formatted limit price.
7057
- * @param params.size - Formatted size.
7058
- * @param params.reduceOnly - Whether the order may only reduce a position.
7059
- * @param params.builderFee - Builder fee, in tenths of a basis point, captured
7060
- * when the session started so replacements keep the rate they were quoted at.
7061
- * @param params.exchangeClient - Client to submit through. Passed in rather
7062
- * than looked up here so a first placement can keep the instance it signed
7063
- * with, which is the only one that can take the order back once `disconnect`
7064
- * has dropped the service's reference.
7065
- * @returns The resting order's exchange ID.
7066
- */
7067
- async function _HyperLiquidProvider_restChaseOrder(params) {
7068
- const result = await params.exchangeClient.order({
7069
- orders: [
7070
- {
7071
- a: params.assetId,
7072
- b: params.isBuy,
7073
- p: params.price,
7074
- s: params.size,
7075
- r: params.reduceOnly,
7076
- // Post-only: a chase adds liquidity at the touch. Crossing would end
7077
- // the chase on its first tick at a worse price than resting does.
7078
- t: { limit: { tif: 'Alo' } },
7079
- },
7080
- ],
7081
- grouping: 'na',
7082
- builder: {
7083
- b: __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getBuilderAddress).call(this, __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").isTestnetMode()),
7084
- f: params.builderFee,
7085
- },
7086
- });
7087
- if (result.status !== 'ok') {
7088
- throw new Error(`Chase order failed: ${JSON.stringify(result)}`);
7089
- }
7090
- const orderId = __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_readOrderIdFromStatus).call(this, result.response?.data?.statuses?.[0]);
7091
- if (!orderId) {
7092
- throw new Error(`Chase order rejected: ${JSON.stringify(result.response?.data)}`);
7093
- }
7094
- return orderId;
7095
- }, _HyperLiquidProvider_scheduleChaseTick = function _HyperLiquidProvider_scheduleChaseTick(sessionId) {
7096
- const session = __classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").get(sessionId);
7097
- if (!session?.active) {
7098
- return;
7099
- }
7100
- const timer = setTimeout(() => {
7101
- // A rejected tick must not stop the session from being cancellable, and
7102
- // must not surface as an unhandled rejection either.
7103
- __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_runChaseTick).call(this, sessionId).catch((error) => {
7104
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase tick failed', {
7105
- sessionId,
7106
- error: (0, errorUtils_js_1.ensureError)(error, 'HyperLiquidProvider.chaseTick').message,
7107
- });
7108
- __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_recoverFailedChaseTick).call(this, sessionId);
7109
- });
7110
- }, session.intervalMs);
7111
- // Node keeps the process alive for a pending timer; a background chase is
7112
- // not a reason to hold an exiting process open. React Native's timers have
7113
- // no `unref`, hence the guard.
7114
- timer.unref?.();
7115
- session.timer = timer;
7116
- }, _HyperLiquidProvider_recoverFailedChaseTick = function _HyperLiquidProvider_recoverFailedChaseTick(sessionId) {
7117
- const session = __classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").get(sessionId);
7118
- if (!session?.active) {
7119
- return;
7120
- }
7121
- if (session.orderId === null) {
7122
- session.active = false;
7123
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase ended with nothing resting', {
7124
- sessionId,
7125
- });
7126
- return;
7127
- }
7128
- __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_scheduleChaseTick).call(this, sessionId);
7129
- }, _HyperLiquidProvider_runChaseTick =
7130
- /**
7131
- * Advance one chase session: re-price if the touch has moved, stop if the
7132
- * window has closed.
7133
- *
7134
- * @param sessionId - Session to advance.
7135
- */
7136
- async function _HyperLiquidProvider_runChaseTick(sessionId) {
7137
- const session = __classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").get(sessionId);
7138
- if (!session?.active) {
7139
- return;
7140
- }
7141
- if (Date.now() >= session.deadline) {
7142
- // The window closed. The last order stays resting as an ordinary limit
7143
- // order and the session stays registered, so cancelling by its handle
7144
- // still reaches that order.
7145
- session.active = false;
7146
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase session window closed', { sessionId });
7147
- return;
7148
- }
7149
- const quotePrice = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getChaseQuotePrice).call(this, {
7150
- symbol: session.symbol,
7151
- isBuy: session.isBuy,
7152
- szDecimals: session.szDecimals,
7153
- own: session.orderId
7154
- ? {
7155
- orderId: session.orderId,
7156
- price: session.restingPrice,
7157
- size: session.size,
7158
- }
7159
- : undefined,
7160
- });
7161
- if (quotePrice === 'gone') {
7162
- // The order left the book without the loop seeing it — it filled. Ending
7163
- // here releases its slot against the venue's concurrency cap instead of
7164
- // holding one until the window closes.
7165
- session.orderId = null;
7166
- session.active = false;
7167
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase order filled between ticks', {
7168
- sessionId,
7169
- });
7170
- return;
7171
- }
7172
- // The book read is a round trip, and a cancel arriving during it stops the
7173
- // session. Without this re-check the tick would cancel and re-place the very
7174
- // order the caller just asked to be rid of.
7175
- if (!session.active) {
7176
- return;
7177
- }
7178
- if (quotePrice !== session.restingPrice && session.orderId) {
7179
- const outcome = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_cancelChaseChild).call(this, session);
7180
- // The cancel is a second round trip, and this is the window where a
7181
- // caller's `cancelOrder` does the most damage: it would cancel the order
7182
- // this tick has already cancelled, report the cancel incomplete, and then
7183
- // this tick would rest a replacement the caller has no idea exists.
7184
- // Stopping here leaves nothing on the book.
7185
- if (!session.active) {
7186
- // A refused cancel leaves the child resting. Preserve its ID so the
7187
- // caller that stopped this session can report an incomplete cancel and
7188
- // retry it instead of orphaning the order.
7189
- if (outcome !== 'refused') {
7190
- session.orderId = null;
7191
- }
7192
- return;
7193
- }
7194
- if (outcome === 'refused') {
7195
- // The exchange kept the order, so it is still resting at the old price.
7196
- // Placing the replacement anyway would double the position. Leave it
7197
- // alone and try again on the next tick, which is why this falls through
7198
- // to the reschedule below rather than ending the session.
7199
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase reprice cancel refused', {
7200
- sessionId,
7201
- orderId: session.orderId,
7202
- });
7203
- }
7204
- else if (outcome === 'gone') {
7205
- // The order left the book between ticks: it filled, or something else
7206
- // cancelled it. There is nothing left to chase.
7207
- session.orderId = null;
7208
- session.active = false;
7209
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase order no longer resting', {
7210
- sessionId,
7211
- });
7212
- return;
7213
- }
7214
- else {
7215
- // The cancel is confirmed, so the session owns nothing from here on.
7216
- // Recorded before the read rather than after it: a read that rejects
7217
- // would otherwise leave the session naming an order that is already off
7218
- // the book, and recovery would reschedule a chase with nothing resting.
7219
- const cancelledOrderId = session.orderId;
7220
- session.orderId = null;
7221
- // No further fills can reach a cancelled order, so what it did not fill
7222
- // is now fixed. Sampling before the cancel would have left a window in
7223
- // which a fill lands and is then re-placed.
7224
- const remaining = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_readOrderRemainder).call(this, cancelledOrderId);
7225
- // Another round trip, another window for a cancel to land. By now the
7226
- // old order is already off the book, so a cancel that arrived during it
7227
- // found nothing to cancel and reported success — resting a replacement
7228
- // after that would put an order on the book the caller believes is gone
7229
- // and has no handle for.
7230
- if (!session.active || !__classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").has(sessionId)) {
7231
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase cancelled mid-reprice', {
7232
- sessionId,
7233
- });
7234
- return;
7235
- }
7236
- if (remaining === null) {
7237
- // It filled completely between ticks; there is nothing left to chase.
7238
- session.active = false;
7239
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase order fully filled', { sessionId });
7240
- return;
7241
- }
7242
- // Published *before* the placement starts, not from the promise it
7243
- // returns: the window opens the moment `#restChaseOrder` is entered, so
7244
- // deriving the marker from its return value would leave the synchronous
7245
- // prefix of that call unguarded. A cancel arriving anywhere inside the
7246
- // round trip now waits for the replacement to land instead of reading
7247
- // the null `orderId` as "nothing rests", reporting success, and dropping
7248
- // the handle while this call is still putting an order on the book.
7249
- let settleReplacement;
7250
- session.pendingReplacement = new Promise((resolve) => {
7251
- settleReplacement = resolve;
7252
- });
7253
- try {
7254
- session.orderId = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_restChaseOrder).call(this, {
7255
- assetId: session.assetId,
7256
- isBuy: session.isBuy,
7257
- price: quotePrice,
7258
- size: remaining,
7259
- reduceOnly: session.reduceOnly,
7260
- builderFee: session.builderFee,
7261
- // A running session is on a live provider, so the current client is
7262
- // the right one; only the first placement has a teardown to survive.
7263
- exchangeClient: __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").getExchangeClient(),
7264
- });
7265
- session.size = remaining;
7266
- }
7267
- finally {
7268
- // Cleared before the waiters wake, so they see the settled session.
7269
- session.pendingReplacement = null;
7270
- settleReplacement?.();
7271
- }
7272
- session.restingPrice = quotePrice;
7273
- session.repricings += 1;
7274
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase re-priced', {
7275
- sessionId,
7276
- orderId: session.orderId,
7277
- restingPrice: quotePrice,
7278
- size: session.size,
7279
- repricings: session.repricings,
7280
- });
7281
- // A cancel that arrived during the round trip is now waiting on this
7282
- // session; it cancels the order just recorded above. A `disconnect`
7283
- // deregisters the session instead, and deliberately leaves resting
7284
- // orders alone — logged with its ID so it stays traceable.
7285
- if (!__classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").has(sessionId)) {
7286
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase replacement outlived its session', {
7287
- sessionId,
7288
- orderId: session.orderId,
7289
- });
7290
- return;
7291
- }
7292
- if (!session.active) {
7293
- return;
7294
- }
7295
- }
7296
- }
7297
- if (session.repricings >= session.maxRepricings) {
7298
- session.active = false;
7299
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase repricing cap reached', { sessionId });
7300
- return;
7301
- }
7302
- __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_scheduleChaseTick).call(this, sessionId);
7303
- }, _HyperLiquidProvider_resolveOwnRestingSizes =
7304
- /**
7305
- * Resolve how much of the chase's own order is really sitting on its level.
7306
- *
7307
- * The session tracks what its order was last *placed* for, which overstates
7308
- * the order once it partially fills. Over-subtracting only matters when it
7309
- * would net the level away entirely — while the level still shows more size
7310
- * than the order could possibly hold, the level has external liquidity either
7311
- * way and the stale figure is good enough.
7312
- *
7313
- * So the live size is fetched only in the ambiguous case, which keeps the
7314
- * common tick to a single book read rather than doubling the request rate
7315
- * against the venue for every chase on every interval.
7316
- *
7317
- * @param params - Netting parameters.
7318
- * @param params.symbol - Market being quoted.
7319
- * @param params.isBuy - Side being quoted.
7320
- * @param params.callerOrderId - The asking session's order, if it has one.
7321
- * @param params.ownSide - The side of the book those orders rest on.
7322
- * @returns Our resting size at each price, or `'gone'` when the asking
7323
- * session's own order is no longer live.
7324
- */
7325
- async function _HyperLiquidProvider_resolveOwnRestingSizes(params) {
7326
- const { symbol, isBuy, callerOrderId, ownSide } = params;
7327
- // Every chase this provider is running on this side, the caller included.
7328
- const ourOrders = [...__classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").values()]
7329
- .filter((session) => session.orderId !== null &&
7330
- session.symbol === symbol &&
7331
- session.isBuy === isBuy)
7332
- .map((session) => ({
7333
- orderId: session.orderId,
7334
- price: session.restingPrice,
7335
- size: session.size,
7336
- }));
7337
- if (ourOrders.length === 0) {
7338
- return new Map();
7339
- }
7340
- const recorded = new Map();
7341
- for (const order of ourOrders) {
7342
- recorded.set(order.price, (recorded.get(order.price) ?? 0) + parseFloat(order.size));
7343
- }
7344
- // A level holding more than we possibly could has external size regardless,
7345
- // so the recorded figures cannot change the answer there and are left as
7346
- // they are. Elsewhere the recorded sizes may overstate what is really
7347
- // resting — an order partially fills without the loop seeing it — and only
7348
- // then is a lookup worth a round trip.
7349
- const ambiguous = ourOrders.filter((order) => {
7350
- const level = ownSide?.find((entry) => entry.px === order.price);
7351
- return !level || parseFloat(level.sz) <= (recorded.get(order.price) ?? 0);
7352
- });
7353
- let callerIsGone = false;
7354
- for (const order of ambiguous) {
7355
- try {
7356
- const live = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_readOrderRemainder).call(this, order.orderId);
7357
- const delta = (live === null ? 0 : parseFloat(live)) - parseFloat(order.size);
7358
- recorded.set(order.price, Math.max(0, (recorded.get(order.price) ?? 0) + delta));
7359
- if (live === null && order.orderId === callerOrderId) {
7360
- callerIsGone = true;
7361
- }
7362
- }
7363
- catch (error) {
7364
- // A failed lookup must not stop the chase. Keeping the recorded size can
7365
- // only over-subtract, which quotes a level deeper rather than leaving
7366
- // the order stranded at a stale price.
7367
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase own-size lookup failed', {
7368
- orderId: order.orderId,
7369
- error: (0, errorUtils_js_1.ensureError)(error, 'HyperLiquidProvider.chaseOwnSize').message,
7370
- });
7371
- }
7372
- }
7373
- return callerIsGone ? 'gone' : recorded;
7374
- }, _HyperLiquidProvider_readOrderRemainder =
7375
- /**
7376
- * Read what a chase's just-cancelled order left unfilled.
7377
- *
7378
- * A chase re-prices by cancelling and re-placing, and the order it cancels
7379
- * may have partially filled first; re-placing the session's original size
7380
- * would execute more than the caller asked for.
7381
- *
7382
- * Read *after* the cancel on purpose. The order's status endpoint answers for
7383
- * an order that is no longer on the book, and once the cancel has landed no
7384
- * further fills can reach it — so the unfilled size it reports is final.
7385
- * Sampling the open-order book beforehand would instead leave a one-round-trip
7386
- * window in which a fill lands and is then re-placed on top.
7387
- *
7388
- * @param orderId - Exchange ID of the order that was just cancelled.
7389
- * @returns The unfilled size, or null when nothing is left to chase.
7390
- */
7391
- async function _HyperLiquidProvider_readOrderRemainder(orderId) {
7392
- const userAddress = await __classPrivateFieldGet(this, _HyperLiquidProvider_walletService, "f").getUserAddressWithDefault();
7393
- const status = await __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").getInfoClient().orderStatus({
7394
- user: userAddress,
7395
- oid: parseInt(orderId, 10),
7396
- });
7397
- if (status.status !== 'order') {
7398
- return null;
7399
- }
7400
- const remaining = String(status.order.order.sz);
7401
- return parseFloat(remaining) > 0 ? remaining : null;
7402
- }, _HyperLiquidProvider_cancelChaseChild =
7403
- /**
7404
- * Cancel the order a chase session currently has resting.
7405
- *
7406
- * @param session - The session whose child to cancel.
7407
- * @param placingClient - Client to cancel through. Omitted by every cancel on
7408
- * a live provider, which wants the current one; an abandoned placement passes
7409
- * the client it signed with, the only one still able to reach its order.
7410
- * @returns Whether the order was cancelled, was already gone, or still rests.
7411
- */
7412
- async function _HyperLiquidProvider_cancelChaseChild(session, placingClient) {
7413
- if (!session.orderId) {
7414
- return 'gone';
7415
- }
7416
- // Looked up only once there is something to cancel, so a session with
7417
- // nothing resting still answers on a provider whose client is already gone.
7418
- const exchangeClient = placingClient ?? __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").getExchangeClient();
7419
- const result = await exchangeClient.cancel({
7420
- cancels: [{ a: session.assetId, o: parseInt(session.orderId, 10) }],
7421
- });
7422
- return classifyCancelStatus(result.response?.data?.statuses?.[0]);
7423
- }, _HyperLiquidProvider_retractOrphanedChaseOrder =
7424
- /**
7425
- * Take back the order of a chase that was abandoned before it registered.
7426
- *
7427
- * Best-effort by construction: the provider is already being torn down, so a
7428
- * cancel that fails outright is reported rather than retried or thrown. The
7429
- * caller reports the placement as a failure either way — the outcome only
7430
- * decides whether an exchange id is worth handing back with it.
7431
- *
7432
- * @param session - The unregistered session holding the resting order.
7433
- * @param placingClient - The client the order was signed with. The service's
7434
- * own reference is already cleared by the time this runs, so asking it for a
7435
- * client here would fail before a cancel was ever sent.
7436
- * @returns Whether the order was cancelled, was already gone, or still rests.
7437
- */
7438
- async function _HyperLiquidProvider_retractOrphanedChaseOrder(session, placingClient) {
7439
- try {
7440
- const outcome = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_cancelChaseChild).call(this, session, placingClient);
7441
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Retracted abandoned chase order', {
7442
- orderId: session.orderId,
7443
- outcome,
7444
- });
7445
- return outcome;
7446
- }
7447
- catch (error) {
7448
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Could not retract abandoned chase order', {
7449
- orderId: session.orderId,
7450
- error: (0, errorUtils_js_1.ensureError)(error, 'HyperLiquidProvider.startChaseSession')
7451
- .message,
7452
- });
7453
- return 'refused';
7454
- }
7455
- }, _HyperLiquidProvider_stopChaseSession = function _HyperLiquidProvider_stopChaseSession(sessionId) {
7456
- const session = __classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").get(sessionId);
7457
- if (!session) {
7458
- return;
7459
- }
7460
- session.active = false;
7461
- if (session.timer) {
7462
- clearTimeout(session.timer);
7463
- session.timer = null;
7464
- }
7465
- }, _HyperLiquidProvider_cancelStrategyOrder =
7466
- /**
7467
- * Cancel a strategy placement by its handle.
7468
- *
7469
- * @param params - Cancellation parameters.
7470
- * @returns A promise that resolves to the result.
7471
- */
7472
- async function _HyperLiquidProvider_cancelStrategyOrder(params) {
7473
- try {
7474
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Canceling strategy order:', params);
7475
- if (params.orderType === 'twap') {
7476
- return await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_cancelTwapOrder).call(this, params);
7477
- }
7478
- if (params.orderType === 'scale') {
7479
- return await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_cancelScaleOrder).call(this, params);
7480
- }
7481
- return await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_cancelChaseOrder).call(this, params);
7482
- }
7483
- catch (error) {
7484
- const mappedError = __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_mapError).call(this, error);
7485
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").logger.error(mappedError, await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getTradingErrorContext).call(this, 'cancelOrder', mappedError, {
7486
- orderId: params.orderId,
7487
- coin: params.symbol,
7488
- orderType: params.orderType,
7489
- }));
7490
- return (0, hyperLiquidValidation_js_1.createErrorResult)(mappedError, {
7491
- success: false,
7492
- orderId: params.orderId,
7493
- });
7494
- }
7495
- }, _HyperLiquidProvider_cancelTwapOrder =
7496
- /**
7497
- * Cancel a running TWAP through the venue's TWAP cancel action.
7498
- *
7499
- * A TWAP never rested on the book, so the ordinary `cancel` action has no
7500
- * order ID to match and would reject it.
7501
- *
7502
- * @param params - Cancellation parameters, with `orderId` carrying the TWAP ID.
7503
- * @returns A promise that resolves to the result.
7504
- */
7505
- async function _HyperLiquidProvider_cancelTwapOrder(params) {
7506
- await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureReady).call(this);
7507
- const coinValidation = (0, hyperLiquidValidation_js_1.validateCoinExists)(params.symbol, __classPrivateFieldGet(this, _HyperLiquidProvider_symbolToAssetId, "f"));
7508
- if (!coinValidation.isValid) {
7509
- throw new Error(coinValidation.error);
7510
- }
7511
- await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureReadyForTrading).call(this);
7512
- const assetId = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getAssetIdWithRepair).call(this, {
7513
- symbol: params.symbol,
7514
- dexName: (0, hyperLiquidAdapter_js_1.parseAssetName)(params.symbol).dex,
7515
- });
7516
- const result = await __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").getExchangeClient().twapCancel({
7517
- a: assetId,
7518
- t: parseInt(params.orderId, 10),
7519
- });
7520
- const status = result.response?.data?.status;
7521
- if (status === 'success') {
7522
- return { success: true, orderId: params.orderId };
7523
- }
7524
- const rawError = status?.error ??
7525
- 'TWAP cancellation failed';
7526
- return (0, hyperLiquidValidation_js_1.createErrorResult)(__classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_mapError).call(this, new Error(rawError)), {
7527
- success: false,
7528
- orderId: params.orderId,
7529
- });
7530
- }, _HyperLiquidProvider_cancelScaleOrder =
7531
- /**
7532
- * Cancel every child of a scale ladder in one batch.
7533
- *
7534
- * @param params - Cancellation parameters, with `orderId` carrying the group handle.
7535
- * @returns A promise that resolves to the result.
7536
- */
7537
- async function _HyperLiquidProvider_cancelScaleOrder(params) {
7538
- const group = __classPrivateFieldGet(this, _HyperLiquidProvider_scaleOrderGroups, "f").get(params.orderId);
7539
- if (!group) {
7540
- throw new Error(perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_STRATEGY_HANDLE_UNKNOWN);
7541
- }
7542
- await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureReadyForTrading).call(this);
7543
- const result = await __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").getExchangeClient().cancel({
7544
- cancels: group.orderIds.map((orderId) => ({
7545
- a: group.assetId,
7546
- o: parseInt(orderId, 10),
7547
- })),
7548
- });
7549
- const statuses = result.response?.data?.statuses ?? [];
7550
- // A rung that filled or was cancelled individually comes back as a
7551
- // rejection, but nothing of it is resting — counting it as still live would
7552
- // pin the handle open for a ladder that is entirely off the book.
7553
- const remaining = group.orderIds.filter((_unused, index) => classifyCancelStatus(statuses[index]) === 'refused');
7554
- if (remaining.length === 0) {
7555
- __classPrivateFieldGet(this, _HyperLiquidProvider_scaleOrderGroups, "f").delete(params.orderId);
7556
- return { success: true, orderId: params.orderId };
7557
- }
7558
- // A rung the exchange refused to cancel may still be resting. Keeping the
7559
- // handle registered against what is left means the caller can retry the
7560
- // same cancel rather than being told the ladder is gone when it is not.
7561
- __classPrivateFieldGet(this, _HyperLiquidProvider_scaleOrderGroups, "f").set(params.orderId, {
7562
- assetId: group.assetId,
7563
- orderIds: remaining,
7564
- });
7565
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Scale group cancel left children resting', {
7566
- groupId: params.orderId,
7567
- remaining: remaining.length,
7568
- total: group.orderIds.length,
7569
- });
7570
- return (0, hyperLiquidValidation_js_1.createErrorResult)(new Error(perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_STRATEGY_CANCEL_INCOMPLETE), { success: false, orderId: params.orderId });
7571
- }, _HyperLiquidProvider_cancelChaseOrder =
7572
- /**
7573
- * Stop a chase session and cancel whatever it still has resting.
7574
- *
7575
- * @param params - Cancellation parameters, with `orderId` carrying the session handle.
7576
- * @returns A promise that resolves to the result.
7577
- */
7578
- async function _HyperLiquidProvider_cancelChaseOrder(params) {
7579
- const session = __classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").get(params.orderId);
7580
- if (!session) {
7581
- throw new Error(perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_STRATEGY_HANDLE_UNKNOWN);
7582
- }
7583
- // Stopped first: a tick that fired between here and the cancel below would
7584
- // otherwise re-place the very order being cancelled.
7585
- __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_stopChaseSession).call(this, params.orderId);
7586
- // A replacement already in flight cannot be called off, so the cancel waits
7587
- // for it and then cancels whatever it rested. Deciding without waiting would
7588
- // read the session's null `orderId` as "nothing rests" and report a clean
7589
- // cancellation over an order that was about to appear on the book.
7590
- if (session.pendingReplacement) {
7591
- await session.pendingReplacement;
7592
- }
7593
- // Nothing rests: the order filled, something else cancelled it, or a
7594
- // replacement failed to go up. Either way the session ends cleanly.
7595
- if (session.orderId === null) {
7596
- __classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").delete(params.orderId);
7597
- return { success: true, orderId: params.orderId };
7598
- }
7599
- await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureReadyForTrading).call(this);
7600
- // Only a refusal leaves an order behind. A child that had already filled or
7601
- // been cancelled is reported as a rejection too, but nothing of it is
7602
- // resting — treating that as a failure would pin the handle open forever on
7603
- // a chase that is entirely finished.
7604
- if ((await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_cancelChaseChild).call(this, session)) === 'refused') {
7605
- // The order is still resting. The session stays registered — stopped, but
7606
- // still cancellable — so the caller can retry with the same handle.
7607
- __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase cancel left its order resting', {
7608
- sessionId: params.orderId,
7609
- orderId: session.orderId,
7610
- });
7611
- return (0, hyperLiquidValidation_js_1.createErrorResult)(new Error(perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_STRATEGY_CANCEL_INCOMPLETE), { success: false, orderId: params.orderId });
7612
- }
7613
- __classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").delete(params.orderId);
7614
- return { success: true, orderId: params.orderId };
7615
- }, _HyperLiquidProvider_readOrderIdFromStatus = function _HyperLiquidProvider_readOrderIdFromStatus(status) {
7616
- if (!isStatusObject(status)) {
7617
- return undefined;
7618
- }
7619
- // `hasProperty` types the property as `unknown`, so each branch is cast to
7620
- // the only shape the exchange puts there.
7621
- const restingOrder = (0, utils_1.hasProperty)(status, 'resting')
7622
- ? status.resting
7623
- : undefined;
7624
- const filledOrder = (0, utils_1.hasProperty)(status, 'filled')
7625
- ? status.filled
7626
- : undefined;
7627
- return (restingOrder?.oid?.toString() ?? filledOrder?.oid?.toString() ?? undefined);
7628
- }, _HyperLiquidProvider_getDiscountedBuilderFee = function _HyperLiquidProvider_getDiscountedBuilderFee() {
7629
- if (__classPrivateFieldGet(this, _HyperLiquidProvider_userFeeDiscountBips, "f") === undefined) {
7630
- return hyperLiquidConfig_js_1.BUILDER_FEE_CONFIG.MaxFeeTenthsBps;
7631
- }
7632
- return Math.floor(hyperLiquidConfig_js_1.BUILDER_FEE_CONFIG.MaxFeeTenthsBps *
7633
- (1 - __classPrivateFieldGet(this, _HyperLiquidProvider_userFeeDiscountBips, "f") / hyperLiquidConfig_js_1.BASIS_POINTS_DIVISOR));
7634
6372
  }, _HyperLiquidProvider_fetchOpenOrders =
7635
6373
  /**
7636
6374
  * Read the account's currently resting orders.