@metamask-previews/perps-controller 12.2.0-preview-d23deb68f → 12.2.0-preview-4165cebcf
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.
- package/CHANGELOG.md +12 -0
- package/README.md +13 -2
- package/dist/PerpsController-method-action-types.cjs.map +1 -1
- package/dist/PerpsController-method-action-types.d.cts +23 -1
- package/dist/PerpsController-method-action-types.d.cts.map +1 -1
- package/dist/PerpsController-method-action-types.d.mts +23 -1
- package/dist/PerpsController-method-action-types.d.mts.map +1 -1
- package/dist/PerpsController-method-action-types.mjs.map +1 -1
- package/dist/PerpsController.cjs +26 -0
- package/dist/PerpsController.cjs.map +1 -1
- package/dist/PerpsController.d.cts +17 -1
- package/dist/PerpsController.d.cts.map +1 -1
- package/dist/PerpsController.d.mts +17 -1
- package/dist/PerpsController.d.mts.map +1 -1
- package/dist/PerpsController.mjs +26 -0
- package/dist/PerpsController.mjs.map +1 -1
- package/dist/constants/eventNames.cjs +5 -0
- package/dist/constants/eventNames.cjs.map +1 -1
- package/dist/constants/eventNames.d.cts +3 -0
- package/dist/constants/eventNames.d.cts.map +1 -1
- package/dist/constants/eventNames.d.mts +3 -0
- package/dist/constants/eventNames.d.mts.map +1 -1
- package/dist/constants/eventNames.mjs +5 -0
- package/dist/constants/eventNames.mjs.map +1 -1
- package/dist/constants/perpsConfig.cjs +22 -9
- package/dist/constants/perpsConfig.cjs.map +1 -1
- package/dist/constants/perpsConfig.d.cts +21 -8
- package/dist/constants/perpsConfig.d.cts.map +1 -1
- package/dist/constants/perpsConfig.d.mts +21 -8
- package/dist/constants/perpsConfig.d.mts.map +1 -1
- package/dist/constants/perpsConfig.mjs +21 -8
- package/dist/constants/perpsConfig.mjs.map +1 -1
- package/dist/index.cjs +5 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/perpsErrorCodes.cjs +1 -0
- package/dist/perpsErrorCodes.cjs.map +1 -1
- package/dist/perpsErrorCodes.d.cts +1 -0
- package/dist/perpsErrorCodes.d.cts.map +1 -1
- package/dist/perpsErrorCodes.d.mts +1 -0
- package/dist/perpsErrorCodes.d.mts.map +1 -1
- package/dist/perpsErrorCodes.mjs +1 -0
- package/dist/perpsErrorCodes.mjs.map +1 -1
- package/dist/providers/AggregatedPerpsProvider.cjs +41 -0
- package/dist/providers/AggregatedPerpsProvider.cjs.map +1 -1
- package/dist/providers/AggregatedPerpsProvider.d.cts +16 -1
- package/dist/providers/AggregatedPerpsProvider.d.cts.map +1 -1
- package/dist/providers/AggregatedPerpsProvider.d.mts +16 -1
- package/dist/providers/AggregatedPerpsProvider.d.mts.map +1 -1
- package/dist/providers/AggregatedPerpsProvider.mjs +41 -0
- package/dist/providers/AggregatedPerpsProvider.mjs.map +1 -1
- package/dist/providers/HyperLiquidProvider.cjs +374 -33
- package/dist/providers/HyperLiquidProvider.cjs.map +1 -1
- package/dist/providers/HyperLiquidProvider.d.cts +16 -1
- package/dist/providers/HyperLiquidProvider.d.cts.map +1 -1
- package/dist/providers/HyperLiquidProvider.d.mts +16 -1
- package/dist/providers/HyperLiquidProvider.d.mts.map +1 -1
- package/dist/providers/HyperLiquidProvider.mjs +376 -35
- package/dist/providers/HyperLiquidProvider.mjs.map +1 -1
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.cts +34 -0
- package/dist/types/index.d.cts.map +1 -1
- package/dist/types/index.d.mts +34 -0
- package/dist/types/index.d.mts.map +1 -1
- package/dist/types/index.mjs.map +1 -1
- package/dist/utils/hyperLiquidValidation.cjs +16 -4
- package/dist/utils/hyperLiquidValidation.cjs.map +1 -1
- package/dist/utils/hyperLiquidValidation.d.cts +1 -0
- package/dist/utils/hyperLiquidValidation.d.cts.map +1 -1
- package/dist/utils/hyperLiquidValidation.d.mts +1 -0
- package/dist/utils/hyperLiquidValidation.d.mts.map +1 -1
- package/dist/utils/hyperLiquidValidation.mjs +17 -5
- package/dist/utils/hyperLiquidValidation.mjs.map +1 -1
- package/package.json +2 -2
|
@@ -9,12 +9,12 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
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");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
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_subscriptionBuilderApprovalEpoch, _HyperLiquidProvider_approvedBuilderAddresses, _HyperLiquidProvider_compiledAllowlistPatterns, _HyperLiquidProvider_compiledBlocklistPatterns, _HyperLiquidProvider_userFeeDiscountBips, _HyperLiquidProvider_userFeeResolution, _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_subscriptionBuilderAddressTestnet, _HyperLiquidProvider_subscriptionBuilderAddressMainnet, _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_getApprovedBuilderKey, _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_getBuilderOrderContext, _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_getSubscriptionBuilderAddress, _HyperLiquidProvider_getReferralCode, _HyperLiquidProvider_ensureReferralSet, _HyperLiquidProvider_isReferralCodeReady, _HyperLiquidProvider_checkReferralSet, _HyperLiquidProvider_setReferralCode;
|
|
12
|
+
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_subscriptionBuilderApprovalEpoch, _HyperLiquidProvider_approvedBuilderAddresses, _HyperLiquidProvider_compiledAllowlistPatterns, _HyperLiquidProvider_compiledBlocklistPatterns, _HyperLiquidProvider_userFeeDiscountBips, _HyperLiquidProvider_userFeeResolution, _HyperLiquidProvider_hip3Enabled, _HyperLiquidProvider_allowlistMarkets, _HyperLiquidProvider_blocklistMarkets, _HyperLiquidProvider_useUnifiedAccount, _HyperLiquidProvider_dexDiscoveryComplete, _HyperLiquidProvider_unifiedAccountSetupNeedsRetry, _HyperLiquidProvider_pendingValidatedDexsPromise, _HyperLiquidProvider_cachedUsdcTokenId, _HyperLiquidProvider_errorMappings, _HyperLiquidProvider_scaleOrderGroups, _HyperLiquidProvider_chaseSessions, _HyperLiquidProvider_chaseTerminations, _HyperLiquidProvider_terminatedChaseHandles, _HyperLiquidProvider_chasePlacementsInFlight, _HyperLiquidProvider_chasePlacementWaiters, _HyperLiquidProvider_chaseTickQueue, _HyperLiquidProvider_chaseGeneration, _HyperLiquidProvider_chasePlacementBlockers, _HyperLiquidProvider_clientsInitialized, _HyperLiquidProvider_initializationPromise, _HyperLiquidProvider_messenger, _HyperLiquidProvider_builderAddressTestnet, _HyperLiquidProvider_builderAddressMainnet, _HyperLiquidProvider_subscriptionBuilderAddressTestnet, _HyperLiquidProvider_subscriptionBuilderAddressMainnet, _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_getApprovedBuilderKey, _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_pauseChaseTicksForPlacement, _HyperLiquidProvider_resumeChaseTicksAfterPlacement, _HyperLiquidProvider_recoverFailedChaseTick, _HyperLiquidProvider_runChaseTick, _HyperLiquidProvider_resolveOwnRestingSizes, _HyperLiquidProvider_readOrderRemainder, _HyperLiquidProvider_cancelChaseChild, _HyperLiquidProvider_retractOrphanedChaseOrder, _HyperLiquidProvider_stopChaseSession, _HyperLiquidProvider_cancelStrategyOrder, _HyperLiquidProvider_cancelTwapOrder, _HyperLiquidProvider_cancelScaleOrder, _HyperLiquidProvider_cancelChaseOrder, _HyperLiquidProvider_performChaseTermination, _HyperLiquidProvider_readOrderIdFromStatus, _HyperLiquidProvider_getDiscountedBuilderFee, _HyperLiquidProvider_getBuilderOrderContext, _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_getSubscriptionBuilderAddress, _HyperLiquidProvider_getReferralCode, _HyperLiquidProvider_ensureReferralSet, _HyperLiquidProvider_isReferralCodeReady, _HyperLiquidProvider_checkReferralSet, _HyperLiquidProvider_setReferralCode;
|
|
13
13
|
import { hasProperty } from "@metamask/utils";
|
|
14
14
|
import { v4 as uuidv4 } from "uuid";
|
|
15
15
|
import { PERPS_EVENT_PROPERTY, PERPS_EVENT_VALUE } from "../constants/eventNames.mjs";
|
|
16
16
|
import { BASIS_POINTS_DIVISOR, BUILDER_FEE_CONFIG, canonicalizeHyperLiquidDexes, FEE_RATES, getBridgeInfo, getChainId, HIP3_ASSET_MARKET_TYPES, HIP3_FEE_CONFIG, HIP3_MARGIN_CONFIG, HYPERLIQUID_ASSET_NAMES, HYPERLIQUID_CONFIG, HYPERLIQUID_WITHDRAWAL_MINUTES, REFERRAL_CONFIG, TRADING_DEFAULTS, USDC_DECIMALS, USDC_SYMBOL } from "../constants/hyperLiquidConfig.mjs";
|
|
17
|
-
import { CHASE_ORDER_CONFIG, HYPERLIQUID_TWAP_LIMITS, ORDER_SLIPPAGE_CONFIG, PERFORMANCE_CONFIG, PERPS_CONSTANTS, TP_SL_CONFIG, WITHDRAWAL_CONSTANTS } from "../constants/perpsConfig.mjs";
|
|
17
|
+
import { CHASE_ORDER_CONFIG, CHASE_ORDER_STATUS, HYPERLIQUID_TWAP_LIMITS, ORDER_SLIPPAGE_CONFIG, PERFORMANCE_CONFIG, PERPS_CONSTANTS, TP_SL_CONFIG, WITHDRAWAL_CONSTANTS } from "../constants/perpsConfig.mjs";
|
|
18
18
|
import { PERPS_TRANSACTIONS_HISTORY_CONSTANTS } from "../constants/transactionsHistoryConfig.mjs";
|
|
19
19
|
import { PERPS_ERROR_CODES } from "../perpsErrorCodes.mjs";
|
|
20
20
|
import { DexDiscoveryCacheManager } from "../services/DexDiscoveryCacheManager.mjs";
|
|
@@ -32,7 +32,7 @@ import { createErrorResult, getMaxOrderValue, getSupportedPaths, validateAssetSu
|
|
|
32
32
|
import { generatePerpsId } from "../utils/idUtils.mjs";
|
|
33
33
|
import { transformMarketData } from "../utils/marketDataTransform.mjs";
|
|
34
34
|
import { compileMarketPattern, shouldIncludeMarket } from "../utils/marketUtils.mjs";
|
|
35
|
-
import { buildOrdersArray, calculateFinalPositionSize, calculateOrderPriceAndSize, computeChaseQuotePrice, computeScalePriceLadder, floorToSizeDecimals, formatPartialTpslSize, splitScaleSizes, validateOrderPrecision } from "../utils/orderCalculations.mjs";
|
|
35
|
+
import { buildOrdersArray, calculateFinalPositionSize, calculateOrderPriceAndSize, computeChaseQuotePrice, computeScalePriceLadder, floorToSizeDecimals, formatPartialTpslSize, getPriceTick, splitScaleSizes, validateOrderPrecision } from "../utils/orderCalculations.mjs";
|
|
36
36
|
import { getTriggerExecution, isLimitExecutionOrderType, isStrategyOrderType, isTriggerOrderType, resolvePositionTriggerSummaryPrice, toSDKTimeInForce } from "../utils/orderTypes.mjs";
|
|
37
37
|
import { createStandaloneInfoClient, queryStandaloneClearinghouseStates, queryStandaloneOpenOrders } from "../utils/standaloneInfoClient.mjs";
|
|
38
38
|
// getStreamManagerInstance removed: use this.#deps.streamManager instead
|
|
@@ -60,6 +60,14 @@ const ALREADY_GONE_CANCEL_MARKERS = [
|
|
|
60
60
|
'already cancelled',
|
|
61
61
|
'order not found',
|
|
62
62
|
];
|
|
63
|
+
const RETRYABLE_CHASE_PLACEMENT_MARKERS = [
|
|
64
|
+
'post only order would have immediately matched',
|
|
65
|
+
'price too far from oracle',
|
|
66
|
+
];
|
|
67
|
+
const isRetryableChasePlacementError = (error) => {
|
|
68
|
+
const message = ensureError(error, 'HyperLiquidProvider.startChaseSession').message.toLowerCase();
|
|
69
|
+
return RETRYABLE_CHASE_PLACEMENT_MARKERS.some((marker) => message.includes(marker));
|
|
70
|
+
};
|
|
63
71
|
/**
|
|
64
72
|
* Classify one entry of a cancel response.
|
|
65
73
|
*
|
|
@@ -134,6 +142,7 @@ const pickStrategyParams = (params) => ({
|
|
|
134
142
|
chaseIntervalMs: params.chaseIntervalMs,
|
|
135
143
|
chaseMaxDurationMs: params.chaseMaxDurationMs,
|
|
136
144
|
chaseMaxRepricings: params.chaseMaxRepricings,
|
|
145
|
+
chaseMaxDistanceBps: params.chaseMaxDistanceBps,
|
|
137
146
|
});
|
|
138
147
|
/**
|
|
139
148
|
* Check a strategy placement's notional against the minimum the venue will
|
|
@@ -384,16 +393,34 @@ export class HyperLiquidProvider {
|
|
|
384
393
|
// Chase sessions running on this provider instance, keyed by session handle.
|
|
385
394
|
// Each owns a pending timer, so disconnect has to stop them.
|
|
386
395
|
_HyperLiquidProvider_chaseSessions.set(this, new Map());
|
|
396
|
+
// In-flight termination is keyed by stable strategy handle so retries share
|
|
397
|
+
// one venue mutation. Completed handles remain idempotent for this provider
|
|
398
|
+
// lifecycle and are cleared on disconnect.
|
|
399
|
+
_HyperLiquidProvider_chaseTerminations.set(this, new Map());
|
|
400
|
+
// Provider-lifetime tombstones make every later retry idempotent. Disconnect
|
|
401
|
+
// clears them with the rest of the account-scoped Chase registry.
|
|
402
|
+
_HyperLiquidProvider_terminatedChaseHandles.set(this, new Set());
|
|
387
403
|
// Chase placements that have reserved a slot against the venue's concurrency
|
|
388
404
|
// cap but have not registered their session yet. Two round trips separate the
|
|
389
405
|
// two, and a reservation is what keeps concurrent placements from both
|
|
390
406
|
// passing the check.
|
|
391
407
|
_HyperLiquidProvider_chasePlacementsInFlight.set(this, 0);
|
|
408
|
+
// Allows lifecycle teardown to wait until every placement has either
|
|
409
|
+
// registered a session or retracted its newly-rested child.
|
|
410
|
+
_HyperLiquidProvider_chasePlacementWaiters.set(this, new Set());
|
|
411
|
+
// Serialize background Chase mutations. Several sessions share one signer and
|
|
412
|
+
// transport, so simultaneous cancel/replace ticks would create avoidable
|
|
413
|
+
// signed traffic and can starve a foreground placement.
|
|
414
|
+
_HyperLiquidProvider_chaseTickQueue.set(this, Promise.resolve());
|
|
392
415
|
// Bumped by every teardown that clears the chase registry. A placement
|
|
393
416
|
// captures it before its round trips and refuses to register afterwards if it
|
|
394
417
|
// has moved: a session registered after a disconnect would schedule a
|
|
395
418
|
// background timer against a provider that has already been torn down.
|
|
396
419
|
_HyperLiquidProvider_chaseGeneration.set(this, 0);
|
|
420
|
+
// Reference-counted because suspension and disconnect may overlap. One
|
|
421
|
+
// lifecycle owner finishing must not reopen placement while another still
|
|
422
|
+
// drains or tears down the provider.
|
|
423
|
+
_HyperLiquidProvider_chasePlacementBlockers.set(this, 0);
|
|
397
424
|
// Track whether clients have been initialized (lazy initialization)
|
|
398
425
|
_HyperLiquidProvider_clientsInitialized.set(this, false);
|
|
399
426
|
// Promise-based lock to prevent race conditions in concurrent initialization
|
|
@@ -903,6 +930,101 @@ export class HyperLiquidProvider {
|
|
|
903
930
|
});
|
|
904
931
|
}
|
|
905
932
|
}
|
|
933
|
+
/**
|
|
934
|
+
* Return stable client-facing snapshots for every Chase session retained by
|
|
935
|
+
* this provider instance. A read may refresh the current child order's
|
|
936
|
+
* remaining size from the venue, throttled to the Chase interval.
|
|
937
|
+
*
|
|
938
|
+
* @returns Current Chase session snapshots.
|
|
939
|
+
*/
|
|
940
|
+
async getChaseOrders() {
|
|
941
|
+
return await Promise.all([...__classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").entries()].map(async ([handle, session]) => {
|
|
942
|
+
const now = Date.now();
|
|
943
|
+
let snapshotRemainingSize = session.size;
|
|
944
|
+
if (session.orderId !== null &&
|
|
945
|
+
session.pendingReplacement === null &&
|
|
946
|
+
now - session.lastSnapshotSizeRefreshAt >= session.intervalMs) {
|
|
947
|
+
session.lastSnapshotSizeRefreshAt = now;
|
|
948
|
+
const snapshotOrderId = session.orderId;
|
|
949
|
+
try {
|
|
950
|
+
const liveRemainder = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_readOrderRemainder).call(this, snapshotOrderId);
|
|
951
|
+
if (liveRemainder !== null &&
|
|
952
|
+
session.orderId === snapshotOrderId &&
|
|
953
|
+
session.pendingReplacement === null) {
|
|
954
|
+
Object.assign(session, { size: liveRemainder });
|
|
955
|
+
snapshotRemainingSize = liveRemainder;
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
catch (error) {
|
|
959
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase snapshot size refresh failed', {
|
|
960
|
+
orderId: snapshotOrderId,
|
|
961
|
+
error: ensureError(error, 'HyperLiquidProvider.getChaseOrders')
|
|
962
|
+
.message,
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
const arrival = Number.parseFloat(session.arrivalPrice);
|
|
967
|
+
const resting = Number.parseFloat(session.restingPrice);
|
|
968
|
+
const adverseDistance = session.isBuy
|
|
969
|
+
? resting - arrival
|
|
970
|
+
: arrival - resting;
|
|
971
|
+
const measuredDistance = Number.isFinite(arrival) &&
|
|
972
|
+
arrival > 0 &&
|
|
973
|
+
Number.isFinite(adverseDistance)
|
|
974
|
+
? Math.round((Math.max(0, adverseDistance) / arrival) * BASIS_POINTS_DIVISOR)
|
|
975
|
+
: 0;
|
|
976
|
+
return {
|
|
977
|
+
handle,
|
|
978
|
+
symbol: session.symbol,
|
|
979
|
+
side: session.isBuy ? 'buy' : 'sell',
|
|
980
|
+
originalSize: session.originalSize,
|
|
981
|
+
remainingSize: snapshotRemainingSize,
|
|
982
|
+
arrivalPrice: session.arrivalPrice,
|
|
983
|
+
restingPrice: session.restingPrice,
|
|
984
|
+
restingOrderId: session.orderId,
|
|
985
|
+
distanceChasedBps: measuredDistance,
|
|
986
|
+
...(session.maxDistanceBps === undefined
|
|
987
|
+
? {}
|
|
988
|
+
: { maxDistanceBps: session.maxDistanceBps }),
|
|
989
|
+
repricings: session.repricings,
|
|
990
|
+
startedAt: session.startedAt,
|
|
991
|
+
status: session.status,
|
|
992
|
+
};
|
|
993
|
+
}));
|
|
994
|
+
}
|
|
995
|
+
/**
|
|
996
|
+
* Stop all active Chase loops while deliberately leaving their current
|
|
997
|
+
* post-only children resting. Used when a client moves to the background.
|
|
998
|
+
*
|
|
999
|
+
* @returns Snapshots after every in-flight replacement has settled.
|
|
1000
|
+
*/
|
|
1001
|
+
async suspendChaseOrders() {
|
|
1002
|
+
__classPrivateFieldSet(this, _HyperLiquidProvider_chasePlacementBlockers, __classPrivateFieldGet(this, _HyperLiquidProvider_chasePlacementBlockers, "f") + 1, "f");
|
|
1003
|
+
// Abort a placement that passed the blocker check but has not completed
|
|
1004
|
+
// its final generation check; the waiter below then drains its cleanup.
|
|
1005
|
+
__classPrivateFieldSet(this, _HyperLiquidProvider_chaseGeneration, __classPrivateFieldGet(this, _HyperLiquidProvider_chaseGeneration, "f") + 1, "f");
|
|
1006
|
+
try {
|
|
1007
|
+
await Promise.all([...__classPrivateFieldGet(this, _HyperLiquidProvider_chasePlacementWaiters, "f")]);
|
|
1008
|
+
// Clear timers without deactivating sessions, then let any tick already
|
|
1009
|
+
// admitted to the shared queue finish its cancel/replace. Stopping first
|
|
1010
|
+
// can strand a session between children: the old order is cancelled, the
|
|
1011
|
+
// tick observes `active === false`, and suspension reports a resting
|
|
1012
|
+
// Chase that no longer owns an exchange order.
|
|
1013
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_pauseChaseTicksForPlacement).call(this);
|
|
1014
|
+
await __classPrivateFieldGet(this, _HyperLiquidProvider_chaseTickQueue, "f");
|
|
1015
|
+
for (const [sessionId, session] of __classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").entries()) {
|
|
1016
|
+
if (!session.active) {
|
|
1017
|
+
continue;
|
|
1018
|
+
}
|
|
1019
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_stopChaseSession).call(this, sessionId);
|
|
1020
|
+
session.status = CHASE_ORDER_STATUS.Backgrounded;
|
|
1021
|
+
}
|
|
1022
|
+
return await this.getChaseOrders();
|
|
1023
|
+
}
|
|
1024
|
+
finally {
|
|
1025
|
+
__classPrivateFieldSet(this, _HyperLiquidProvider_chasePlacementBlockers, __classPrivateFieldGet(this, _HyperLiquidProvider_chasePlacementBlockers, "f") - 1, "f");
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
906
1028
|
/**
|
|
907
1029
|
* Edit an existing order (pending/unfilled order)
|
|
908
1030
|
*
|
|
@@ -1121,7 +1243,22 @@ export class HyperLiquidProvider {
|
|
|
1121
1243
|
if (params.orderType && isStrategyOrderType(params.orderType)) {
|
|
1122
1244
|
return await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_cancelStrategyOrder).call(this, params);
|
|
1123
1245
|
}
|
|
1246
|
+
// Resolve ownership before the first await. A reprice can change the child
|
|
1247
|
+
// ID while an ordinary cancel is in flight; cancelling through the stable
|
|
1248
|
+
// session handle stops the loop, joins any replacement, and removes the
|
|
1249
|
+
// current child instead of leaving a replacement chasing behind the user.
|
|
1250
|
+
const owningChase = [...__classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").entries()].find(([, session]) => session.orderId === params.orderId ||
|
|
1251
|
+
session.replacingOrderId === params.orderId);
|
|
1124
1252
|
try {
|
|
1253
|
+
if (owningChase) {
|
|
1254
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_stopChaseSession).call(this, owningChase[0]);
|
|
1255
|
+
await __classPrivateFieldGet(this, _HyperLiquidProvider_chaseTickQueue, "f");
|
|
1256
|
+
return await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_cancelChaseOrder).call(this, {
|
|
1257
|
+
...params,
|
|
1258
|
+
orderId: owningChase[0],
|
|
1259
|
+
orderType: 'chase',
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1125
1262
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Canceling order:', params);
|
|
1126
1263
|
// Hydrate the asset map before coin validation so a cold start (e.g.
|
|
1127
1264
|
// service-worker restart with an empty prefetch map) can self-heal
|
|
@@ -4516,6 +4653,8 @@ export class HyperLiquidProvider {
|
|
|
4516
4653
|
* @returns A promise that resolves to the result.
|
|
4517
4654
|
*/
|
|
4518
4655
|
async disconnect() {
|
|
4656
|
+
__classPrivateFieldSet(this, _HyperLiquidProvider_chasePlacementBlockers, __classPrivateFieldGet(this, _HyperLiquidProvider_chasePlacementBlockers, "f") + 1, "f");
|
|
4657
|
+
__classPrivateFieldSet(this, _HyperLiquidProvider_chaseGeneration, __classPrivateFieldGet(this, _HyperLiquidProvider_chaseGeneration, "f") + 1, "f");
|
|
4519
4658
|
try {
|
|
4520
4659
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquid: Disconnecting provider', {
|
|
4521
4660
|
isTestnet: __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").isTestnetMode(),
|
|
@@ -4527,13 +4666,20 @@ export class HyperLiquidProvider {
|
|
|
4527
4666
|
// a disconnect would sign orders against a client that is being torn down.
|
|
4528
4667
|
// Orders already resting are deliberately left alone — disconnecting is
|
|
4529
4668
|
// not a request to cancel the user's positions or orders.
|
|
4530
|
-
|
|
4531
|
-
|
|
4669
|
+
// Invalidate placements first, then drain every mutation before clearing
|
|
4670
|
+
// the registry and tearing down the clients they use.
|
|
4671
|
+
for (const [sessionId, session] of __classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").entries()) {
|
|
4672
|
+
if (session.active) {
|
|
4673
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_stopChaseSession).call(this, sessionId);
|
|
4674
|
+
}
|
|
4532
4675
|
}
|
|
4676
|
+
await Promise.all([...__classPrivateFieldGet(this, _HyperLiquidProvider_chasePlacementWaiters, "f")]);
|
|
4677
|
+
await __classPrivateFieldGet(this, _HyperLiquidProvider_chaseTickQueue, "f");
|
|
4678
|
+
await Promise.allSettled([...__classPrivateFieldGet(this, _HyperLiquidProvider_chaseTerminations, "f").values()]);
|
|
4533
4679
|
__classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").clear();
|
|
4680
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_chaseTerminations, "f").clear();
|
|
4681
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_terminatedChaseHandles, "f").clear();
|
|
4534
4682
|
__classPrivateFieldGet(this, _HyperLiquidProvider_scaleOrderGroups, "f").clear();
|
|
4535
|
-
// Placements still mid-flight check this before registering.
|
|
4536
|
-
__classPrivateFieldSet(this, _HyperLiquidProvider_chaseGeneration, __classPrivateFieldGet(this, _HyperLiquidProvider_chaseGeneration, "f") + 1, "f");
|
|
4537
4683
|
// Clear fee cache
|
|
4538
4684
|
this.clearFeeCache();
|
|
4539
4685
|
// Clear session caches (ensures fresh state on reconnect/account switch)
|
|
@@ -4599,6 +4745,9 @@ export class HyperLiquidProvider {
|
|
|
4599
4745
|
catch (error) {
|
|
4600
4746
|
return createErrorResult(error, { success: false });
|
|
4601
4747
|
}
|
|
4748
|
+
finally {
|
|
4749
|
+
__classPrivateFieldSet(this, _HyperLiquidProvider_chasePlacementBlockers, __classPrivateFieldGet(this, _HyperLiquidProvider_chasePlacementBlockers, "f") - 1, "f");
|
|
4750
|
+
}
|
|
4602
4751
|
}
|
|
4603
4752
|
/**
|
|
4604
4753
|
* Lightweight WebSocket health check using SDK's built-in ready() method
|
|
@@ -4723,7 +4872,7 @@ export class HyperLiquidProvider {
|
|
|
4723
4872
|
return `${baseUrl}/explorer`;
|
|
4724
4873
|
}
|
|
4725
4874
|
}
|
|
4726
|
-
_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_subscriptionBuilderApprovalEpoch = new WeakMap(), _HyperLiquidProvider_approvedBuilderAddresses = new WeakMap(), _HyperLiquidProvider_compiledAllowlistPatterns = new WeakMap(), _HyperLiquidProvider_compiledBlocklistPatterns = new WeakMap(), _HyperLiquidProvider_userFeeDiscountBips = new WeakMap(), _HyperLiquidProvider_userFeeResolution = 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_subscriptionBuilderAddressTestnet = new WeakMap(), _HyperLiquidProvider_subscriptionBuilderAddressMainnet = 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) {
|
|
4875
|
+
_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_subscriptionBuilderApprovalEpoch = new WeakMap(), _HyperLiquidProvider_approvedBuilderAddresses = new WeakMap(), _HyperLiquidProvider_compiledAllowlistPatterns = new WeakMap(), _HyperLiquidProvider_compiledBlocklistPatterns = new WeakMap(), _HyperLiquidProvider_userFeeDiscountBips = new WeakMap(), _HyperLiquidProvider_userFeeResolution = 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_chaseTerminations = new WeakMap(), _HyperLiquidProvider_terminatedChaseHandles = new WeakMap(), _HyperLiquidProvider_chasePlacementsInFlight = new WeakMap(), _HyperLiquidProvider_chasePlacementWaiters = new WeakMap(), _HyperLiquidProvider_chaseTickQueue = new WeakMap(), _HyperLiquidProvider_chaseGeneration = new WeakMap(), _HyperLiquidProvider_chasePlacementBlockers = new WeakMap(), _HyperLiquidProvider_clientsInitialized = new WeakMap(), _HyperLiquidProvider_initializationPromise = new WeakMap(), _HyperLiquidProvider_messenger = new WeakMap(), _HyperLiquidProvider_builderAddressTestnet = new WeakMap(), _HyperLiquidProvider_builderAddressMainnet = new WeakMap(), _HyperLiquidProvider_subscriptionBuilderAddressTestnet = new WeakMap(), _HyperLiquidProvider_subscriptionBuilderAddressMainnet = 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) {
|
|
4727
4876
|
const compiled = [];
|
|
4728
4877
|
for (const pattern of patterns) {
|
|
4729
4878
|
try {
|
|
@@ -6843,13 +6992,16 @@ async function _HyperLiquidProvider_placeStrategyOrder(params, orderType) {
|
|
|
6843
6992
|
// asset info, validation, trading readiness and a leverage update, and a
|
|
6844
6993
|
// disconnect during any of them has to be seen by the chase registration
|
|
6845
6994
|
// at the end.
|
|
6846
|
-
const generation = __classPrivateFieldGet(this, _HyperLiquidProvider_chaseGeneration, "f");
|
|
6847
6995
|
if (orderType !== 'chase') {
|
|
6848
6996
|
const context = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_prepareStrategyPlacement).call(this, params);
|
|
6849
6997
|
return orderType === 'twap'
|
|
6850
6998
|
? await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_placeTwapOrder).call(this, params, context)
|
|
6851
6999
|
: await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_placeScaleOrder).call(this, params, context);
|
|
6852
7000
|
}
|
|
7001
|
+
if (__classPrivateFieldGet(this, _HyperLiquidProvider_chasePlacementBlockers, "f") > 0) {
|
|
7002
|
+
throw new Error(PERPS_ERROR_CODES.ORDER_CHASE_ABANDONED);
|
|
7003
|
+
}
|
|
7004
|
+
const generation = __classPrivateFieldGet(this, _HyperLiquidProvider_chaseGeneration, "f");
|
|
6853
7005
|
// The chase slot is claimed before the preamble, not after it: the preamble
|
|
6854
7006
|
// completes the signing setup and can change the asset's leverage, and a
|
|
6855
7007
|
// request that is going to be refused for exceeding the venue's cap must
|
|
@@ -6862,12 +7014,24 @@ async function _HyperLiquidProvider_placeStrategyOrder(params, orderType) {
|
|
|
6862
7014
|
throw new Error(PERPS_ERROR_CODES.ORDER_CHASE_LIMIT_REACHED);
|
|
6863
7015
|
}
|
|
6864
7016
|
__classPrivateFieldSet(this, _HyperLiquidProvider_chasePlacementsInFlight, __classPrivateFieldGet(this, _HyperLiquidProvider_chasePlacementsInFlight, "f") + 1, "f");
|
|
7017
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_pauseChaseTicksForPlacement).call(this);
|
|
7018
|
+
let settlePlacement;
|
|
7019
|
+
const placementWaiter = new Promise((resolve) => {
|
|
7020
|
+
settlePlacement = resolve;
|
|
7021
|
+
});
|
|
7022
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_chasePlacementWaiters, "f").add(placementWaiter);
|
|
6865
7023
|
try {
|
|
7024
|
+
await __classPrivateFieldGet(this, _HyperLiquidProvider_chaseTickQueue, "f");
|
|
6866
7025
|
const context = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_prepareStrategyPlacement).call(this, params);
|
|
6867
7026
|
return await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_startChaseSession).call(this, params, context, generation);
|
|
6868
7027
|
}
|
|
6869
7028
|
finally {
|
|
7029
|
+
settlePlacement?.();
|
|
7030
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_chasePlacementWaiters, "f").delete(placementWaiter);
|
|
6870
7031
|
__classPrivateFieldSet(this, _HyperLiquidProvider_chasePlacementsInFlight, __classPrivateFieldGet(this, _HyperLiquidProvider_chasePlacementsInFlight, "f") - 1, "f");
|
|
7032
|
+
if (__classPrivateFieldGet(this, _HyperLiquidProvider_chasePlacementsInFlight, "f") === 0) {
|
|
7033
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_resumeChaseTicksAfterPlacement).call(this);
|
|
7034
|
+
}
|
|
6871
7035
|
}
|
|
6872
7036
|
}, _HyperLiquidProvider_prepareStrategyPlacement =
|
|
6873
7037
|
/**
|
|
@@ -7152,7 +7316,7 @@ async function _HyperLiquidProvider_startChaseSession(params, context, generatio
|
|
|
7152
7316
|
if (generation !== __classPrivateFieldGet(this, _HyperLiquidProvider_chaseGeneration, "f")) {
|
|
7153
7317
|
throw new Error(PERPS_ERROR_CODES.ORDER_CHASE_ABANDONED);
|
|
7154
7318
|
}
|
|
7155
|
-
|
|
7319
|
+
let quotePrice = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getChaseQuotePrice).call(this, {
|
|
7156
7320
|
symbol: params.symbol,
|
|
7157
7321
|
isBuy: params.isBuy,
|
|
7158
7322
|
szDecimals,
|
|
@@ -7172,22 +7336,55 @@ async function _HyperLiquidProvider_startChaseSession(params, context, generatio
|
|
|
7172
7336
|
}
|
|
7173
7337
|
// Read once, while the caller's fee-source context is still set.
|
|
7174
7338
|
const builder = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getBuilderOrderContext).call(this);
|
|
7339
|
+
if (generation !== __classPrivateFieldGet(this, _HyperLiquidProvider_chaseGeneration, "f")) {
|
|
7340
|
+
throw new Error(PERPS_ERROR_CODES.ORDER_CHASE_ABANDONED);
|
|
7341
|
+
}
|
|
7175
7342
|
// Held onto rather than looked up again after the submission returns.
|
|
7176
7343
|
// `disconnect` drops the service's client reference synchronously, so a
|
|
7177
7344
|
// retraction that asked for a client after the fact would be refused one
|
|
7178
7345
|
// and leave the order resting under the account that placed it. This
|
|
7179
7346
|
// instance signed the order and can still cancel it as that account.
|
|
7180
7347
|
const placingClient = __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").getExchangeClient();
|
|
7181
|
-
|
|
7182
|
-
|
|
7183
|
-
|
|
7184
|
-
|
|
7185
|
-
|
|
7186
|
-
|
|
7187
|
-
|
|
7188
|
-
|
|
7189
|
-
|
|
7190
|
-
|
|
7348
|
+
let orderId;
|
|
7349
|
+
for (let attempt = 1; attempt <= CHASE_ORDER_CONFIG.InitialPlacementAttempts; attempt += 1) {
|
|
7350
|
+
try {
|
|
7351
|
+
orderId = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_restChaseOrder).call(this, {
|
|
7352
|
+
assetId,
|
|
7353
|
+
isBuy: params.isBuy,
|
|
7354
|
+
price: quotePrice,
|
|
7355
|
+
size: formattedSize,
|
|
7356
|
+
reduceOnly: params.reduceOnly ?? false,
|
|
7357
|
+
builderFee: builder.f,
|
|
7358
|
+
builderAddress: builder.b,
|
|
7359
|
+
exchangeClient: placingClient,
|
|
7360
|
+
});
|
|
7361
|
+
break;
|
|
7362
|
+
}
|
|
7363
|
+
catch (error) {
|
|
7364
|
+
if (attempt === CHASE_ORDER_CONFIG.InitialPlacementAttempts ||
|
|
7365
|
+
!isRetryableChasePlacementError(error)) {
|
|
7366
|
+
throw error;
|
|
7367
|
+
}
|
|
7368
|
+
if (generation !== __classPrivateFieldGet(this, _HyperLiquidProvider_chaseGeneration, "f")) {
|
|
7369
|
+
throw new Error(PERPS_ERROR_CODES.ORDER_CHASE_ABANDONED);
|
|
7370
|
+
}
|
|
7371
|
+
const refreshedQuote = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getChaseQuotePrice).call(this, {
|
|
7372
|
+
symbol: params.symbol,
|
|
7373
|
+
isBuy: params.isBuy,
|
|
7374
|
+
szDecimals,
|
|
7375
|
+
});
|
|
7376
|
+
if (refreshedQuote === 'gone') {
|
|
7377
|
+
throw new Error(PERPS_ERROR_CODES.ORDER_CHASE_TOUCH_UNAVAILABLE);
|
|
7378
|
+
}
|
|
7379
|
+
if (generation !== __classPrivateFieldGet(this, _HyperLiquidProvider_chaseGeneration, "f")) {
|
|
7380
|
+
throw new Error(PERPS_ERROR_CODES.ORDER_CHASE_ABANDONED);
|
|
7381
|
+
}
|
|
7382
|
+
quotePrice = refreshedQuote;
|
|
7383
|
+
}
|
|
7384
|
+
}
|
|
7385
|
+
if (!orderId) {
|
|
7386
|
+
throw new Error(PERPS_ERROR_CODES.ORDER_CHASE_TOUCH_UNAVAILABLE);
|
|
7387
|
+
}
|
|
7191
7388
|
const intervalMs = params.chaseIntervalMs ?? CHASE_ORDER_CONFIG.DefaultIntervalMs;
|
|
7192
7389
|
const sessionId = generatePerpsId('chase');
|
|
7193
7390
|
const session = {
|
|
@@ -7195,12 +7392,18 @@ async function _HyperLiquidProvider_startChaseSession(params, context, generatio
|
|
|
7195
7392
|
assetId,
|
|
7196
7393
|
isBuy: params.isBuy,
|
|
7197
7394
|
size: formattedSize,
|
|
7395
|
+
originalSize: formattedSize,
|
|
7198
7396
|
szDecimals,
|
|
7199
7397
|
reduceOnly: params.reduceOnly ?? false,
|
|
7200
7398
|
orderId,
|
|
7399
|
+
replacingOrderId: null,
|
|
7201
7400
|
pendingReplacement: null,
|
|
7202
7401
|
restingPrice: quotePrice,
|
|
7402
|
+
arrivalPrice: quotePrice,
|
|
7403
|
+
startedAt: Date.now(),
|
|
7404
|
+
maxDistanceBps: params.chaseMaxDistanceBps,
|
|
7203
7405
|
intervalMs,
|
|
7406
|
+
lastSnapshotSizeRefreshAt: 0,
|
|
7204
7407
|
builderFee: builder.f,
|
|
7205
7408
|
builderAddress: builder.b,
|
|
7206
7409
|
deadline: Date.now() +
|
|
@@ -7209,6 +7412,7 @@ async function _HyperLiquidProvider_startChaseSession(params, context, generatio
|
|
|
7209
7412
|
repricings: 0,
|
|
7210
7413
|
timer: null,
|
|
7211
7414
|
active: true,
|
|
7415
|
+
status: CHASE_ORDER_STATUS.Active,
|
|
7212
7416
|
};
|
|
7213
7417
|
// A disconnect landed while the submission was in flight — the one window
|
|
7214
7418
|
// the checks above cannot close. The order rested, but no strategy is
|
|
@@ -7349,21 +7553,41 @@ async function _HyperLiquidProvider_restChaseOrder(params) {
|
|
|
7349
7553
|
return;
|
|
7350
7554
|
}
|
|
7351
7555
|
const timer = setTimeout(() => {
|
|
7352
|
-
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
}
|
|
7359
|
-
|
|
7360
|
-
|
|
7556
|
+
session.timer = null;
|
|
7557
|
+
__classPrivateFieldSet(this, _HyperLiquidProvider_chaseTickQueue, __classPrivateFieldGet(this, _HyperLiquidProvider_chaseTickQueue, "f").then(async () => {
|
|
7558
|
+
// A rejected tick must not stop the session from being cancellable, and
|
|
7559
|
+
// must not surface as an unhandled rejection either.
|
|
7560
|
+
try {
|
|
7561
|
+
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_runChaseTick).call(this, sessionId);
|
|
7562
|
+
}
|
|
7563
|
+
catch (error) {
|
|
7564
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase tick failed', {
|
|
7565
|
+
sessionId,
|
|
7566
|
+
error: ensureError(error, 'HyperLiquidProvider.chaseTick').message,
|
|
7567
|
+
});
|
|
7568
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_recoverFailedChaseTick).call(this, sessionId);
|
|
7569
|
+
}
|
|
7570
|
+
return undefined;
|
|
7571
|
+
}), "f");
|
|
7361
7572
|
}, session.intervalMs);
|
|
7362
7573
|
// Node keeps the process alive for a pending timer; a background chase is
|
|
7363
7574
|
// not a reason to hold an exiting process open. React Native's timers have
|
|
7364
7575
|
// no `unref`, hence the guard.
|
|
7365
7576
|
timer.unref?.();
|
|
7366
7577
|
session.timer = timer;
|
|
7578
|
+
}, _HyperLiquidProvider_pauseChaseTicksForPlacement = function _HyperLiquidProvider_pauseChaseTicksForPlacement() {
|
|
7579
|
+
for (const session of __classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").values()) {
|
|
7580
|
+
if (session.timer) {
|
|
7581
|
+
clearTimeout(session.timer);
|
|
7582
|
+
session.timer = null;
|
|
7583
|
+
}
|
|
7584
|
+
}
|
|
7585
|
+
}, _HyperLiquidProvider_resumeChaseTicksAfterPlacement = function _HyperLiquidProvider_resumeChaseTicksAfterPlacement() {
|
|
7586
|
+
for (const [sessionId, session] of __classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f")) {
|
|
7587
|
+
if (session.active && !session.timer) {
|
|
7588
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_scheduleChaseTick).call(this, sessionId);
|
|
7589
|
+
}
|
|
7590
|
+
}
|
|
7367
7591
|
}, _HyperLiquidProvider_recoverFailedChaseTick = function _HyperLiquidProvider_recoverFailedChaseTick(sessionId) {
|
|
7368
7592
|
const session = __classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").get(sessionId);
|
|
7369
7593
|
if (!session?.active) {
|
|
@@ -7371,6 +7595,7 @@ async function _HyperLiquidProvider_restChaseOrder(params) {
|
|
|
7371
7595
|
}
|
|
7372
7596
|
if (session.orderId === null) {
|
|
7373
7597
|
session.active = false;
|
|
7598
|
+
session.status = CHASE_ORDER_STATUS.Failed;
|
|
7374
7599
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase ended with nothing resting', {
|
|
7375
7600
|
sessionId,
|
|
7376
7601
|
});
|
|
@@ -7389,15 +7614,27 @@ async function _HyperLiquidProvider_runChaseTick(sessionId) {
|
|
|
7389
7614
|
if (!session?.active) {
|
|
7390
7615
|
return;
|
|
7391
7616
|
}
|
|
7617
|
+
// Give a new Chase placement priority over background cancel/replace
|
|
7618
|
+
// traffic. With several active sessions, their signed mutations can
|
|
7619
|
+
// otherwise overlap the placement preamble and trip the SDK transport's
|
|
7620
|
+
// circuit breaker before the new order reaches the venue. Deferring one
|
|
7621
|
+
// polling interval leaves every existing child resting as a valid ALO and
|
|
7622
|
+
// preserves the venue's five-session limit without increasing request
|
|
7623
|
+
// churn.
|
|
7624
|
+
if (__classPrivateFieldGet(this, _HyperLiquidProvider_chasePlacementsInFlight, "f") > 0) {
|
|
7625
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_scheduleChaseTick).call(this, sessionId);
|
|
7626
|
+
return;
|
|
7627
|
+
}
|
|
7392
7628
|
if (Date.now() >= session.deadline) {
|
|
7393
7629
|
// The window closed. The last order stays resting as an ordinary limit
|
|
7394
7630
|
// order and the session stays registered, so cancelling by its handle
|
|
7395
7631
|
// still reaches that order.
|
|
7396
7632
|
session.active = false;
|
|
7633
|
+
session.status = CHASE_ORDER_STATUS.DurationReached;
|
|
7397
7634
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase session window closed', { sessionId });
|
|
7398
7635
|
return;
|
|
7399
7636
|
}
|
|
7400
|
-
const
|
|
7637
|
+
const rawQuotePrice = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getChaseQuotePrice).call(this, {
|
|
7401
7638
|
symbol: session.symbol,
|
|
7402
7639
|
isBuy: session.isBuy,
|
|
7403
7640
|
szDecimals: session.szDecimals,
|
|
@@ -7409,17 +7646,56 @@ async function _HyperLiquidProvider_runChaseTick(sessionId) {
|
|
|
7409
7646
|
}
|
|
7410
7647
|
: undefined,
|
|
7411
7648
|
});
|
|
7412
|
-
if (
|
|
7649
|
+
if (rawQuotePrice === 'gone') {
|
|
7413
7650
|
// The order left the book without the loop seeing it — it filled. Ending
|
|
7414
7651
|
// here releases its slot against the venue's concurrency cap instead of
|
|
7415
7652
|
// holding one until the window closes.
|
|
7416
7653
|
session.orderId = null;
|
|
7417
7654
|
session.active = false;
|
|
7655
|
+
session.status = CHASE_ORDER_STATUS.Filled;
|
|
7418
7656
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase order filled between ticks', {
|
|
7419
7657
|
sessionId,
|
|
7420
7658
|
});
|
|
7421
7659
|
return;
|
|
7422
7660
|
}
|
|
7661
|
+
const arrivalPrice = Number.parseFloat(session.arrivalPrice);
|
|
7662
|
+
const rawQuote = Number.parseFloat(rawQuotePrice);
|
|
7663
|
+
const adverseDistanceFromArrival = session.isBuy
|
|
7664
|
+
? (rawQuote - arrivalPrice) / arrivalPrice
|
|
7665
|
+
: (arrivalPrice - rawQuote) / arrivalPrice;
|
|
7666
|
+
const boundaryDirection = session.isBuy ? 1 : -1;
|
|
7667
|
+
const maxDistanceRatio = session.maxDistanceBps === undefined
|
|
7668
|
+
? undefined
|
|
7669
|
+
: session.maxDistanceBps / BASIS_POINTS_DIVISOR;
|
|
7670
|
+
const boundaryPrice = maxDistanceRatio === undefined
|
|
7671
|
+
? undefined
|
|
7672
|
+
: arrivalPrice * (1 + boundaryDirection * maxDistanceRatio);
|
|
7673
|
+
let reachedMaxDistance = boundaryPrice !== undefined &&
|
|
7674
|
+
maxDistanceRatio !== undefined &&
|
|
7675
|
+
adverseDistanceFromArrival >= maxDistanceRatio;
|
|
7676
|
+
let quotePrice = rawQuotePrice;
|
|
7677
|
+
if (reachedMaxDistance && boundaryPrice !== undefined) {
|
|
7678
|
+
quotePrice = formatHyperLiquidPrice({
|
|
7679
|
+
price: boundaryPrice,
|
|
7680
|
+
szDecimals: session.szDecimals,
|
|
7681
|
+
});
|
|
7682
|
+
const formattedBoundary = Number.parseFloat(quotePrice);
|
|
7683
|
+
const overshootsBoundary = session.isBuy
|
|
7684
|
+
? formattedBoundary > boundaryPrice
|
|
7685
|
+
: formattedBoundary < boundaryPrice;
|
|
7686
|
+
if (overshootsBoundary) {
|
|
7687
|
+
const tick = getPriceTick({
|
|
7688
|
+
price: boundaryPrice,
|
|
7689
|
+
szDecimals: session.szDecimals,
|
|
7690
|
+
});
|
|
7691
|
+
quotePrice = formatHyperLiquidPrice({
|
|
7692
|
+
price: session.isBuy
|
|
7693
|
+
? formattedBoundary - tick
|
|
7694
|
+
: formattedBoundary + tick,
|
|
7695
|
+
szDecimals: session.szDecimals,
|
|
7696
|
+
});
|
|
7697
|
+
}
|
|
7698
|
+
}
|
|
7423
7699
|
// The book read is a round trip, and a cancel arriving during it stops the
|
|
7424
7700
|
// session. Without this re-check the tick would cancel and re-place the very
|
|
7425
7701
|
// order the caller just asked to be rid of.
|
|
@@ -7451,14 +7727,26 @@ async function _HyperLiquidProvider_runChaseTick(sessionId) {
|
|
|
7451
7727
|
sessionId,
|
|
7452
7728
|
orderId: session.orderId,
|
|
7453
7729
|
});
|
|
7730
|
+
reachedMaxDistance = false;
|
|
7454
7731
|
}
|
|
7455
7732
|
else if (outcome === 'gone') {
|
|
7456
7733
|
// The order left the book between ticks: it filled, or something else
|
|
7457
7734
|
// cancelled it. There is nothing left to chase.
|
|
7735
|
+
const goneOrderId = session.orderId;
|
|
7736
|
+
const remaining = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_readOrderRemainder).call(this, goneOrderId);
|
|
7458
7737
|
session.orderId = null;
|
|
7459
7738
|
session.active = false;
|
|
7739
|
+
session.status =
|
|
7740
|
+
remaining === null
|
|
7741
|
+
? CHASE_ORDER_STATUS.Filled
|
|
7742
|
+
: CHASE_ORDER_STATUS.Failed;
|
|
7743
|
+
if (remaining !== null) {
|
|
7744
|
+
session.size = remaining;
|
|
7745
|
+
}
|
|
7460
7746
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase order no longer resting', {
|
|
7461
7747
|
sessionId,
|
|
7748
|
+
status: session.status,
|
|
7749
|
+
remainingSize: session.size,
|
|
7462
7750
|
});
|
|
7463
7751
|
return;
|
|
7464
7752
|
}
|
|
@@ -7468,6 +7756,7 @@ async function _HyperLiquidProvider_runChaseTick(sessionId) {
|
|
|
7468
7756
|
// would otherwise leave the session naming an order that is already off
|
|
7469
7757
|
// the book, and recovery would reschedule a chase with nothing resting.
|
|
7470
7758
|
const cancelledOrderId = session.orderId;
|
|
7759
|
+
session.replacingOrderId = cancelledOrderId;
|
|
7471
7760
|
session.orderId = null;
|
|
7472
7761
|
// No further fills can reach a cancelled order, so what it did not fill
|
|
7473
7762
|
// is now fixed. Sampling before the cancel would have left a window in
|
|
@@ -7487,6 +7776,7 @@ async function _HyperLiquidProvider_runChaseTick(sessionId) {
|
|
|
7487
7776
|
if (remaining === null) {
|
|
7488
7777
|
// It filled completely between ticks; there is nothing left to chase.
|
|
7489
7778
|
session.active = false;
|
|
7779
|
+
session.status = CHASE_ORDER_STATUS.Filled;
|
|
7490
7780
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase order fully filled', { sessionId });
|
|
7491
7781
|
return;
|
|
7492
7782
|
}
|
|
@@ -7518,6 +7808,7 @@ async function _HyperLiquidProvider_runChaseTick(sessionId) {
|
|
|
7518
7808
|
}
|
|
7519
7809
|
finally {
|
|
7520
7810
|
// Cleared before the waiters wake, so they see the settled session.
|
|
7811
|
+
session.replacingOrderId = null;
|
|
7521
7812
|
session.pendingReplacement = null;
|
|
7522
7813
|
settleReplacement?.();
|
|
7523
7814
|
}
|
|
@@ -7546,8 +7837,19 @@ async function _HyperLiquidProvider_runChaseTick(sessionId) {
|
|
|
7546
7837
|
}
|
|
7547
7838
|
}
|
|
7548
7839
|
}
|
|
7840
|
+
if (reachedMaxDistance) {
|
|
7841
|
+
session.active = false;
|
|
7842
|
+
session.status = CHASE_ORDER_STATUS.MaxDistanceReached;
|
|
7843
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase max distance reached', {
|
|
7844
|
+
sessionId,
|
|
7845
|
+
restingPrice: session.restingPrice,
|
|
7846
|
+
maxDistanceBps: session.maxDistanceBps,
|
|
7847
|
+
});
|
|
7848
|
+
return;
|
|
7849
|
+
}
|
|
7549
7850
|
if (session.repricings >= session.maxRepricings) {
|
|
7550
7851
|
session.active = false;
|
|
7852
|
+
session.status = CHASE_ORDER_STATUS.RepricingLimitReached;
|
|
7551
7853
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase repricing cap reached', { sessionId });
|
|
7552
7854
|
return;
|
|
7553
7855
|
}
|
|
@@ -7668,9 +7970,19 @@ async function _HyperLiquidProvider_cancelChaseChild(session, placingClient) {
|
|
|
7668
7970
|
// Looked up only once there is something to cancel, so a session with
|
|
7669
7971
|
// nothing resting still answers on a provider whose client is already gone.
|
|
7670
7972
|
const exchangeClient = placingClient ?? __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").getExchangeClient();
|
|
7671
|
-
|
|
7672
|
-
|
|
7673
|
-
|
|
7973
|
+
let result;
|
|
7974
|
+
try {
|
|
7975
|
+
result = await exchangeClient.cancel({
|
|
7976
|
+
cancels: [{ a: session.assetId, o: parseInt(session.orderId, 10) }],
|
|
7977
|
+
});
|
|
7978
|
+
}
|
|
7979
|
+
catch (error) {
|
|
7980
|
+
const message = ensureError(error, 'HyperLiquidProvider.cancelChaseChild').message.toLowerCase();
|
|
7981
|
+
if (ALREADY_GONE_CANCEL_MARKERS.some((marker) => message.includes(marker))) {
|
|
7982
|
+
return 'gone';
|
|
7983
|
+
}
|
|
7984
|
+
throw error;
|
|
7985
|
+
}
|
|
7674
7986
|
return classifyCancelStatus(result.response?.data?.statuses?.[0]);
|
|
7675
7987
|
}, _HyperLiquidProvider_retractOrphanedChaseOrder =
|
|
7676
7988
|
/**
|
|
@@ -7710,6 +8022,7 @@ async function _HyperLiquidProvider_retractOrphanedChaseOrder(session, placingCl
|
|
|
7710
8022
|
return;
|
|
7711
8023
|
}
|
|
7712
8024
|
session.active = false;
|
|
8025
|
+
session.status = CHASE_ORDER_STATUS.TerminationPending;
|
|
7713
8026
|
if (session.timer) {
|
|
7714
8027
|
clearTimeout(session.timer);
|
|
7715
8028
|
session.timer = null;
|
|
@@ -7828,6 +8141,33 @@ async function _HyperLiquidProvider_cancelScaleOrder(params) {
|
|
|
7828
8141
|
* @returns A promise that resolves to the result.
|
|
7829
8142
|
*/
|
|
7830
8143
|
async function _HyperLiquidProvider_cancelChaseOrder(params) {
|
|
8144
|
+
if (__classPrivateFieldGet(this, _HyperLiquidProvider_terminatedChaseHandles, "f").has(params.orderId)) {
|
|
8145
|
+
return { success: true, orderId: params.orderId };
|
|
8146
|
+
}
|
|
8147
|
+
const existingTermination = __classPrivateFieldGet(this, _HyperLiquidProvider_chaseTerminations, "f").get(params.orderId);
|
|
8148
|
+
if (existingTermination) {
|
|
8149
|
+
return await existingTermination;
|
|
8150
|
+
}
|
|
8151
|
+
const termination = __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_performChaseTermination).call(this, params);
|
|
8152
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_chaseTerminations, "f").set(params.orderId, termination);
|
|
8153
|
+
try {
|
|
8154
|
+
const result = await termination;
|
|
8155
|
+
if (result.success) {
|
|
8156
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_terminatedChaseHandles, "f").add(params.orderId);
|
|
8157
|
+
}
|
|
8158
|
+
return result;
|
|
8159
|
+
}
|
|
8160
|
+
finally {
|
|
8161
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_chaseTerminations, "f").delete(params.orderId);
|
|
8162
|
+
}
|
|
8163
|
+
}, _HyperLiquidProvider_performChaseTermination =
|
|
8164
|
+
/**
|
|
8165
|
+
* Own one Chase termination after concurrent callers have been deduplicated.
|
|
8166
|
+
*
|
|
8167
|
+
* @param params - Cancellation parameters with a stable Chase handle.
|
|
8168
|
+
* @returns The single underlying termination result.
|
|
8169
|
+
*/
|
|
8170
|
+
async function _HyperLiquidProvider_performChaseTermination(params) {
|
|
7831
8171
|
const session = __classPrivateFieldGet(this, _HyperLiquidProvider_chaseSessions, "f").get(params.orderId);
|
|
7832
8172
|
if (!session) {
|
|
7833
8173
|
throw new Error(PERPS_ERROR_CODES.ORDER_STRATEGY_HANDLE_UNKNOWN);
|
|
@@ -7853,7 +8193,8 @@ async function _HyperLiquidProvider_cancelChaseOrder(params) {
|
|
|
7853
8193
|
// been cancelled is reported as a rejection too, but nothing of it is
|
|
7854
8194
|
// resting — treating that as a failure would pin the handle open forever on
|
|
7855
8195
|
// a chase that is entirely finished.
|
|
7856
|
-
|
|
8196
|
+
const cancelOutcome = await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_cancelChaseChild).call(this, session);
|
|
8197
|
+
if (cancelOutcome === 'refused') {
|
|
7857
8198
|
// The order is still resting. The session stays registered — stopped, but
|
|
7858
8199
|
// still cancellable — so the caller can retry with the same handle.
|
|
7859
8200
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('Chase cancel left its order resting', {
|