@metamask-previews/perps-controller 3.1.0-preview-d6985be → 3.1.1-preview-9c8c0a0
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 +9 -1
- package/dist/PerpsController.cjs +5 -1
- package/dist/PerpsController.cjs.map +1 -1
- package/dist/PerpsController.d.cts.map +1 -1
- package/dist/PerpsController.d.mts.map +1 -1
- package/dist/PerpsController.mjs +5 -1
- package/dist/PerpsController.mjs.map +1 -1
- package/dist/providers/HyperLiquidProvider.cjs +63 -166
- package/dist/providers/HyperLiquidProvider.cjs.map +1 -1
- package/dist/providers/HyperLiquidProvider.d.cts.map +1 -1
- package/dist/providers/HyperLiquidProvider.d.mts.map +1 -1
- package/dist/providers/HyperLiquidProvider.mjs +64 -167
- package/dist/providers/HyperLiquidProvider.mjs.map +1 -1
- package/dist/services/DexDiscoveryCacheManager.cjs +147 -0
- package/dist/services/DexDiscoveryCacheManager.cjs.map +1 -0
- package/dist/services/DexDiscoveryCacheManager.d.cts +52 -0
- package/dist/services/DexDiscoveryCacheManager.d.cts.map +1 -0
- package/dist/services/DexDiscoveryCacheManager.d.mts +52 -0
- package/dist/services/DexDiscoveryCacheManager.d.mts.map +1 -0
- package/dist/services/DexDiscoveryCacheManager.mjs +143 -0
- package/dist/services/DexDiscoveryCacheManager.mjs.map +1 -0
- package/dist/services/HyperLiquidClientService.cjs +4 -3
- package/dist/services/HyperLiquidClientService.cjs.map +1 -1
- package/dist/services/HyperLiquidClientService.d.cts.map +1 -1
- package/dist/services/HyperLiquidClientService.d.mts.map +1 -1
- package/dist/services/HyperLiquidClientService.mjs +4 -3
- package/dist/services/HyperLiquidClientService.mjs.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.cjs +34 -2
- package/dist/services/HyperLiquidSubscriptionService.cjs.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.d.cts.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.d.mts.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.mjs +34 -2
- package/dist/services/HyperLiquidSubscriptionService.mjs.map +1 -1
- package/dist/types/perps-types.cjs.map +1 -1
- package/dist/types/perps-types.d.cts +13 -0
- package/dist/types/perps-types.d.cts.map +1 -1
- package/dist/types/perps-types.d.mts +13 -0
- package/dist/types/perps-types.d.mts.map +1 -1
- package/dist/types/perps-types.mjs.map +1 -1
- package/package.json +4 -4
|
@@ -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,
|
|
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_useDexAbstraction, _HyperLiquidProvider_dexDiscoveryComplete, _HyperLiquidProvider_pendingValidatedDexsPromise, _HyperLiquidProvider_cachedUsdcTokenId, _HyperLiquidProvider_errorMappings, _HyperLiquidProvider_clientsInitialized, _HyperLiquidProvider_initializationPromise, _HyperLiquidProvider_messenger, _HyperLiquidProvider_builderAddressTestnet, _HyperLiquidProvider_builderAddressMainnet, _HyperLiquidProvider_compilePatternsSafely, _HyperLiquidProvider_ensureClientsInitialized, _HyperLiquidProvider_ensureDexAbstractionEnabled, _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_isUsdhCollateralDex, _HyperLiquidProvider_getSpotUsdhBalance, _HyperLiquidProvider_getSpotUsdcBalance, _HyperLiquidProvider_transferUsdcToSpot, _HyperLiquidProvider_swapUsdcToUsdh, _HyperLiquidProvider_ensureUsdhCollateralForOrder, _HyperLiquidProvider_buildAssetMapping, _HyperLiquidProvider_queryUserDataAcrossDexs, _HyperLiquidProvider_mapError, _HyperLiquidProvider_getErrorContext, _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_getStandaloneValidatedDexs, _HyperLiquidProvider_getAllMids, _HyperLiquidProvider_fetchSingleDexFresh, _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");
|
|
@@ -19,6 +19,7 @@ const hyperLiquidConfig_1 = require("../constants/hyperLiquidConfig.cjs");
|
|
|
19
19
|
const perpsConfig_1 = require("../constants/perpsConfig.cjs");
|
|
20
20
|
const transactionsHistoryConfig_1 = require("../constants/transactionsHistoryConfig.cjs");
|
|
21
21
|
const perpsErrorCodes_1 = require("../perpsErrorCodes.cjs");
|
|
22
|
+
const DexDiscoveryCacheManager_1 = require("../services/DexDiscoveryCacheManager.cjs");
|
|
22
23
|
const HyperLiquidClientService_1 = require("../services/HyperLiquidClientService.cjs");
|
|
23
24
|
const HyperLiquidSubscriptionService_1 = require("../services/HyperLiquidSubscriptionService.cjs");
|
|
24
25
|
const HyperLiquidWalletService_1 = require("../services/HyperLiquidWalletService.cjs");
|
|
@@ -75,9 +76,10 @@ class HyperLiquidProvider {
|
|
|
75
76
|
// Session cache for spot metadata (contains USDC/USDH token info for HIP-3 collateral checks)
|
|
76
77
|
// Pre-fetched in ensureReadyForTrading() to avoid API failures during order placement
|
|
77
78
|
_HyperLiquidProvider_cachedSpotMeta.set(this, null);
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
|
|
79
|
+
// Unified DEX discovery cache — single source of truth for all perpDexs() derivatives.
|
|
80
|
+
// Replaces three separate caches to eliminate desync bugs by construction.
|
|
81
|
+
// All writes go through #dexDiscoveryCache.update(); readers use .state.
|
|
82
|
+
_HyperLiquidProvider_dexDiscoveryCache.set(this, void 0);
|
|
81
83
|
// Session cache for referral state (cleared on disconnect/reconnect)
|
|
82
84
|
// Key: `network:userAddress`, Value: true if referral is set
|
|
83
85
|
_HyperLiquidProvider_referralCheckCache.set(this, new Map());
|
|
@@ -98,9 +100,6 @@ class HyperLiquidProvider {
|
|
|
98
100
|
_HyperLiquidProvider_allowlistMarkets.set(this, void 0);
|
|
99
101
|
_HyperLiquidProvider_blocklistMarkets.set(this, void 0);
|
|
100
102
|
_HyperLiquidProvider_useDexAbstraction.set(this, void 0);
|
|
101
|
-
// Cache for validated DEXs to avoid redundant perpDexs() API calls
|
|
102
|
-
_HyperLiquidProvider_cachedValidatedDexs.set(this, null);
|
|
103
|
-
_HyperLiquidProvider_cachedAllPerpDexs.set(this, null);
|
|
104
103
|
// True once DEX discovery has succeeded with real data (not a fallback).
|
|
105
104
|
// When false, #ensureReadyPromise is reset after each init so the next
|
|
106
105
|
// caller retries DEX discovery instead of reusing a degraded mapping.
|
|
@@ -151,6 +150,11 @@ class HyperLiquidProvider {
|
|
|
151
150
|
__classPrivateFieldSet(this, _HyperLiquidProvider_clientService, new HyperLiquidClientService_1.HyperLiquidClientService(__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f"), {
|
|
152
151
|
isTestnet,
|
|
153
152
|
}), "f");
|
|
153
|
+
__classPrivateFieldSet(this, _HyperLiquidProvider_dexDiscoveryCache, new DexDiscoveryCacheManager_1.DexDiscoveryCacheManager({
|
|
154
|
+
isTestnetMode: () => __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").isTestnetMode(),
|
|
155
|
+
debugLogger: __classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger,
|
|
156
|
+
getAllowlistMarkets: () => __classPrivateFieldGet(this, _HyperLiquidProvider_allowlistMarkets, "f"),
|
|
157
|
+
}), "f");
|
|
154
158
|
__classPrivateFieldSet(this, _HyperLiquidProvider_walletService, new HyperLiquidWalletService_1.HyperLiquidWalletService(__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f"), __classPrivateFieldGet(this, _HyperLiquidProvider_messenger, "f"), {
|
|
155
159
|
isTestnet,
|
|
156
160
|
}), "f");
|
|
@@ -3472,7 +3476,7 @@ class HyperLiquidProvider {
|
|
|
3472
3476
|
// to prevent repeated signing requests across reconnections
|
|
3473
3477
|
__classPrivateFieldGet(this, _HyperLiquidProvider_cachedMetaByDex, "f").clear();
|
|
3474
3478
|
__classPrivateFieldSet(this, _HyperLiquidProvider_cachedSpotMeta, null, "f");
|
|
3475
|
-
|
|
3479
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").reset();
|
|
3476
3480
|
__classPrivateFieldSet(this, _HyperLiquidProvider_dexDiscoveryComplete, false, "f");
|
|
3477
3481
|
// Await pending initialization before clearing to prevent the IIFE from
|
|
3478
3482
|
// setting clientsInitialized = true after disconnect completes
|
|
@@ -3649,7 +3653,7 @@ class HyperLiquidProvider {
|
|
|
3649
3653
|
}
|
|
3650
3654
|
}
|
|
3651
3655
|
exports.HyperLiquidProvider = HyperLiquidProvider;
|
|
3652
|
-
_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(),
|
|
3656
|
+
_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_useDexAbstraction = new WeakMap(), _HyperLiquidProvider_dexDiscoveryComplete = 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_tradingSetupPromise = new WeakMap(), _HyperLiquidProvider_tradingSetupComplete = new WeakMap(), _HyperLiquidProvider_instances = new WeakSet(), _HyperLiquidProvider_compilePatternsSafely = function _HyperLiquidProvider_compilePatternsSafely(patterns, listName) {
|
|
3653
3657
|
const compiled = [];
|
|
3654
3658
|
for (const pattern of patterns) {
|
|
3655
3659
|
try {
|
|
@@ -3981,27 +3985,26 @@ async function _HyperLiquidProvider_getOrFetchPrice(params) {
|
|
|
3981
3985
|
* @returns Array of all DEX names (null for main DEX, strings for HIP-3 DEXs)
|
|
3982
3986
|
*/
|
|
3983
3987
|
async function _HyperLiquidProvider_getAllAvailableDexs() {
|
|
3984
|
-
//
|
|
3985
|
-
if (__classPrivateFieldGet(this,
|
|
3986
|
-
Array.isArray(__classPrivateFieldGet(this, _HyperLiquidProvider_cachedAllPerpDexs, "f"))) {
|
|
3988
|
+
// Use unified state if available
|
|
3989
|
+
if (__classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").state) {
|
|
3987
3990
|
const availableHip3Dexs = [];
|
|
3988
|
-
__classPrivateFieldGet(this,
|
|
3991
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").state.raw.forEach((dex) => {
|
|
3989
3992
|
if (dex !== null) {
|
|
3990
3993
|
availableHip3Dexs.push(dex.name);
|
|
3991
3994
|
}
|
|
3992
3995
|
});
|
|
3993
3996
|
return [null, ...availableHip3Dexs];
|
|
3994
3997
|
}
|
|
3995
|
-
// Fetch fresh from API
|
|
3998
|
+
// Fetch fresh from API and update unified state
|
|
3996
3999
|
const infoClient = __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").getInfoClient();
|
|
3997
4000
|
try {
|
|
3998
4001
|
const allDexs = await infoClient.perpDexs();
|
|
3999
4002
|
if (!allDexs || !Array.isArray(allDexs)) {
|
|
4000
4003
|
return [null]; // Fallback to main DEX only
|
|
4001
4004
|
}
|
|
4002
|
-
|
|
4005
|
+
const state = __classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").update(allDexs);
|
|
4003
4006
|
const availableHip3Dexs = [];
|
|
4004
|
-
|
|
4007
|
+
state.raw.forEach((dex) => {
|
|
4005
4008
|
if (dex !== null) {
|
|
4006
4009
|
availableHip3Dexs.push(dex.name);
|
|
4007
4010
|
}
|
|
@@ -4028,9 +4031,15 @@ async function _HyperLiquidProvider_getAllAvailableDexs() {
|
|
|
4028
4031
|
* @returns Array of DEX names to use (null = main DEX, strings = HIP-3 DEXs)
|
|
4029
4032
|
*/
|
|
4030
4033
|
async function _HyperLiquidProvider_getValidatedDexs() {
|
|
4034
|
+
// Kill switch: HIP-3 disabled, return main DEX only
|
|
4035
|
+
// Must check before cache — #getAllAvailableDexs() can populate
|
|
4036
|
+
// state.validated without the hip3Enabled gate
|
|
4037
|
+
if (!__classPrivateFieldGet(this, _HyperLiquidProvider_hip3Enabled, "f")) {
|
|
4038
|
+
return [null];
|
|
4039
|
+
}
|
|
4031
4040
|
// Return cached result if available
|
|
4032
|
-
if (__classPrivateFieldGet(this,
|
|
4033
|
-
return __classPrivateFieldGet(this,
|
|
4041
|
+
if (__classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").state?.validated) {
|
|
4042
|
+
return __classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").state.validated;
|
|
4034
4043
|
}
|
|
4035
4044
|
// If a fetch is already in progress, reuse the pending promise
|
|
4036
4045
|
// This prevents duplicate perpDexs() API calls from concurrent callers
|
|
@@ -4059,9 +4068,8 @@ async function _HyperLiquidProvider_fetchValidatedDexsInternal() {
|
|
|
4059
4068
|
// Kill switch: HIP-3 disabled, return main DEX only
|
|
4060
4069
|
if (!__classPrivateFieldGet(this, _HyperLiquidProvider_hip3Enabled, "f")) {
|
|
4061
4070
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: HIP-3 disabled via hip3Enabled flag');
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
return __classPrivateFieldGet(this, _HyperLiquidProvider_cachedValidatedDexs, "f");
|
|
4071
|
+
const state = __classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").update([null]);
|
|
4072
|
+
return state.validated;
|
|
4065
4073
|
}
|
|
4066
4074
|
// Fetch all available DEXs from HyperLiquid
|
|
4067
4075
|
const infoClient = __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").getInfoClient();
|
|
@@ -4085,110 +4093,13 @@ async function _HyperLiquidProvider_fetchValidatedDexsInternal() {
|
|
|
4085
4093
|
// Do not cache — may be transient, allow retry on next call
|
|
4086
4094
|
return [null];
|
|
4087
4095
|
}
|
|
4088
|
-
//
|
|
4089
|
-
|
|
4090
|
-
// Extract HIP-3 DEX names (filter out null which represents main DEX)
|
|
4091
|
-
const availableHip3Dexs = [];
|
|
4092
|
-
allDexs.forEach((dex) => {
|
|
4093
|
-
if (dex !== null) {
|
|
4094
|
-
availableHip3Dexs.push(dex.name);
|
|
4095
|
-
}
|
|
4096
|
-
});
|
|
4096
|
+
// Atomically update unified state (raw + validated + timestamp)
|
|
4097
|
+
const state = __classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").update(allDexs);
|
|
4097
4098
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Available DEXs (market filtering applied at data layer)', {
|
|
4098
|
-
count:
|
|
4099
|
-
dexNames:
|
|
4099
|
+
count: state.validated.filter((dex) => dex !== null).length,
|
|
4100
|
+
dexNames: state.validated.filter((dex) => dex !== null),
|
|
4100
4101
|
});
|
|
4101
|
-
|
|
4102
|
-
// On testnet, there are many HIP-3 DEXs (test deployments) that cause instability
|
|
4103
|
-
if (__classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").isTestnetMode()) {
|
|
4104
|
-
const { EnabledDexs, AutoDiscoverAll } = hyperLiquidConfig_1.TESTNET_HIP3_CONFIG;
|
|
4105
|
-
if (!AutoDiscoverAll) {
|
|
4106
|
-
if (EnabledDexs.length === 0) {
|
|
4107
|
-
// Main DEX only - no HIP-3 DEXs on testnet
|
|
4108
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Testnet - using main DEX only (HIP-3 DEXs filtered)', {
|
|
4109
|
-
availableHip3Dexs: availableHip3Dexs.length,
|
|
4110
|
-
reason: 'TESTNET_HIP3_CONFIG.EnabledDexs is empty',
|
|
4111
|
-
});
|
|
4112
|
-
__classPrivateFieldSet(this, _HyperLiquidProvider_cachedValidatedDexs, [null], "f");
|
|
4113
|
-
return __classPrivateFieldGet(this, _HyperLiquidProvider_cachedValidatedDexs, "f");
|
|
4114
|
-
}
|
|
4115
|
-
// Filter to specific allowed DEXs on testnet
|
|
4116
|
-
const filteredDexs = availableHip3Dexs.filter((dex) => EnabledDexs.includes(dex));
|
|
4117
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Testnet - filtered to allowed DEXs', {
|
|
4118
|
-
allowedDexs: EnabledDexs,
|
|
4119
|
-
filteredDexs,
|
|
4120
|
-
availableHip3Dexs: availableHip3Dexs.length,
|
|
4121
|
-
});
|
|
4122
|
-
__classPrivateFieldSet(this, _HyperLiquidProvider_cachedValidatedDexs, [null, ...filteredDexs], "f");
|
|
4123
|
-
return __classPrivateFieldGet(this, _HyperLiquidProvider_cachedValidatedDexs, "f");
|
|
4124
|
-
}
|
|
4125
|
-
// AUTO_DISCOVER_ALL is true - proceed with all DEXs (not recommended for testnet)
|
|
4126
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Testnet - AUTO_DISCOVER_ALL enabled, using all DEXs', { totalDexCount: availableHip3Dexs.length + 1 });
|
|
4127
|
-
}
|
|
4128
|
-
else {
|
|
4129
|
-
// Mainnet-specific filtering: Extract allowed DEXs from the allowlist patterns
|
|
4130
|
-
// This reduces WebSocket subscription overhead dynamically based on feature flags
|
|
4131
|
-
const { AutoDiscoverAll } = hyperLiquidConfig_1.MAINNET_HIP3_CONFIG;
|
|
4132
|
-
if (!AutoDiscoverAll) {
|
|
4133
|
-
// Extract unique DEX names from allowlist patterns
|
|
4134
|
-
// Patterns like "xyz:*", "xyz:TSLA", or "xyz" all indicate DEX "xyz"
|
|
4135
|
-
const allowedDexsFromAllowlist = __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_extractDexsFromAllowlist).call(this);
|
|
4136
|
-
if (allowedDexsFromAllowlist.length === 0) {
|
|
4137
|
-
// No HIP-3 DEXs in allowlist - main DEX only
|
|
4138
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Mainnet - using main DEX only (no HIP-3 DEXs in allowlist)', {
|
|
4139
|
-
availableHip3Dexs: availableHip3Dexs.length,
|
|
4140
|
-
allowlistMarkets: __classPrivateFieldGet(this, _HyperLiquidProvider_allowlistMarkets, "f"),
|
|
4141
|
-
});
|
|
4142
|
-
__classPrivateFieldSet(this, _HyperLiquidProvider_cachedValidatedDexs, [null], "f");
|
|
4143
|
-
return __classPrivateFieldGet(this, _HyperLiquidProvider_cachedValidatedDexs, "f");
|
|
4144
|
-
}
|
|
4145
|
-
// Filter to DEXs that are both available AND in the allowlist
|
|
4146
|
-
const filteredDexs = availableHip3Dexs.filter((dex) => allowedDexsFromAllowlist.includes(dex));
|
|
4147
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Mainnet - filtered to allowlist DEXs', {
|
|
4148
|
-
allowedDexsFromAllowlist,
|
|
4149
|
-
filteredDexs,
|
|
4150
|
-
availableHip3Dexs: availableHip3Dexs.length,
|
|
4151
|
-
});
|
|
4152
|
-
__classPrivateFieldSet(this, _HyperLiquidProvider_cachedValidatedDexs, [null, ...filteredDexs], "f");
|
|
4153
|
-
return __classPrivateFieldGet(this, _HyperLiquidProvider_cachedValidatedDexs, "f");
|
|
4154
|
-
}
|
|
4155
|
-
// AUTO_DISCOVER_ALL is true - proceed with all DEXs
|
|
4156
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Mainnet - AUTO_DISCOVER_ALL enabled, using all DEXs', { totalDexCount: availableHip3Dexs.length + 1 });
|
|
4157
|
-
}
|
|
4158
|
-
// Fallback: Return all DEXs (when AUTO_DISCOVER_ALL is true)
|
|
4159
|
-
// Market filtering is applied at subscription data layer
|
|
4160
|
-
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: All DEXs enabled (market filtering at data layer)', {
|
|
4161
|
-
mainDex: true,
|
|
4162
|
-
hip3Dexs: availableHip3Dexs,
|
|
4163
|
-
totalDexCount: availableHip3Dexs.length + 1,
|
|
4164
|
-
});
|
|
4165
|
-
__classPrivateFieldSet(this, _HyperLiquidProvider_cachedValidatedDexs, [null, ...availableHip3Dexs], "f");
|
|
4166
|
-
return __classPrivateFieldGet(this, _HyperLiquidProvider_cachedValidatedDexs, "f");
|
|
4167
|
-
}, _HyperLiquidProvider_extractDexsFromAllowlist = function _HyperLiquidProvider_extractDexsFromAllowlist() {
|
|
4168
|
-
if (__classPrivateFieldGet(this, _HyperLiquidProvider_allowlistMarkets, "f").length === 0) {
|
|
4169
|
-
return [];
|
|
4170
|
-
}
|
|
4171
|
-
const dexNames = new Set();
|
|
4172
|
-
for (const pattern of __classPrivateFieldGet(this, _HyperLiquidProvider_allowlistMarkets, "f")) {
|
|
4173
|
-
// Pattern formats:
|
|
4174
|
-
// - "xyz:*" -> DEX "xyz" (wildcard)
|
|
4175
|
-
// - "xyz:TSLA" -> DEX "xyz" (exact match)
|
|
4176
|
-
// - "xyz" -> DEX "xyz" (shorthand)
|
|
4177
|
-
const colonIndex = pattern.indexOf(':');
|
|
4178
|
-
if (colonIndex > 0) {
|
|
4179
|
-
// Has colon - extract DEX prefix
|
|
4180
|
-
const dex = pattern.substring(0, colonIndex);
|
|
4181
|
-
dexNames.add(dex);
|
|
4182
|
-
}
|
|
4183
|
-
else if (pattern.length > 0 && !pattern.includes('*')) {
|
|
4184
|
-
// No colon and not a wildcard - could be DEX shorthand
|
|
4185
|
-
// Only add if it looks like a valid DEX name (lowercase alphanumeric)
|
|
4186
|
-
if (/^[a-z][a-z0-9]*$/iu.test(pattern)) {
|
|
4187
|
-
dexNames.add(pattern.toLowerCase());
|
|
4188
|
-
}
|
|
4189
|
-
}
|
|
4190
|
-
}
|
|
4191
|
-
return Array.from(dexNames);
|
|
4102
|
+
return state.validated;
|
|
4192
4103
|
}, _HyperLiquidProvider_getCachedMeta =
|
|
4193
4104
|
/**
|
|
4194
4105
|
* Get cached meta response for a DEX, fetching from API if not cached
|
|
@@ -4247,7 +4158,7 @@ async function _HyperLiquidProvider_backfillAssetMapForDex(dex, meta) {
|
|
|
4247
4158
|
if (!meta?.universe || !Array.isArray(meta.universe)) {
|
|
4248
4159
|
return false;
|
|
4249
4160
|
}
|
|
4250
|
-
if (!__classPrivateFieldGet(this,
|
|
4161
|
+
if (!__classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").state) {
|
|
4251
4162
|
try {
|
|
4252
4163
|
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_getValidatedDexs).call(this);
|
|
4253
4164
|
}
|
|
@@ -4258,7 +4169,7 @@ async function _HyperLiquidProvider_backfillAssetMapForDex(dex, meta) {
|
|
|
4258
4169
|
});
|
|
4259
4170
|
}
|
|
4260
4171
|
}
|
|
4261
|
-
const allPerpDexs = __classPrivateFieldGet(this,
|
|
4172
|
+
const allPerpDexs = __classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").state?.raw ?? [null];
|
|
4262
4173
|
const perpDexIndex = allPerpDexs.findIndex((entry) => {
|
|
4263
4174
|
if (dex === null) {
|
|
4264
4175
|
return entry === null;
|
|
@@ -4350,22 +4261,24 @@ async function _HyperLiquidProvider_getCachedSpotMeta() {
|
|
|
4350
4261
|
*/
|
|
4351
4262
|
async function _HyperLiquidProvider_getCachedPerpDexs() {
|
|
4352
4263
|
const now = Date.now();
|
|
4353
|
-
// Return cached data if still valid
|
|
4354
|
-
if (__classPrivateFieldGet(this,
|
|
4355
|
-
now - __classPrivateFieldGet(this,
|
|
4264
|
+
// Return cached data if still valid (uses unified state timestamp for TTL)
|
|
4265
|
+
if (__classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").state &&
|
|
4266
|
+
now - __classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").state.timestamp <
|
|
4267
|
+
hyperLiquidConfig_1.HIP3_FEE_CONFIG.PerpDexsCacheTtlMs) {
|
|
4268
|
+
const raw = __classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").state.raw;
|
|
4356
4269
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('[getCachedPerpDexs] Using cached perpDexs data', {
|
|
4357
|
-
age: `${Math.round((now - __classPrivateFieldGet(this,
|
|
4358
|
-
count:
|
|
4270
|
+
age: `${Math.round((now - __classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").state.timestamp) / 1000)}s`,
|
|
4271
|
+
count: raw.length,
|
|
4359
4272
|
});
|
|
4360
|
-
return
|
|
4273
|
+
return raw;
|
|
4361
4274
|
}
|
|
4362
4275
|
// Fetch fresh data from API
|
|
4363
4276
|
// Note: SDK types are incomplete, but API returns deployerFeeScale
|
|
4364
4277
|
await __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_ensureClientsInitialized).call(this);
|
|
4365
4278
|
const infoClient = __classPrivateFieldGet(this, _HyperLiquidProvider_clientService, "f").getInfoClient();
|
|
4366
4279
|
const perpDexs = (await infoClient.perpDexs());
|
|
4367
|
-
//
|
|
4368
|
-
|
|
4280
|
+
// Atomically update unified state (raw + validated + timestamp)
|
|
4281
|
+
__classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").update(perpDexs);
|
|
4369
4282
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('[getCachedPerpDexs] Fetched and cached perpDexs data', {
|
|
4370
4283
|
count: perpDexs.length,
|
|
4371
4284
|
dexes: perpDexs
|
|
@@ -4796,15 +4709,15 @@ async function _HyperLiquidProvider_buildAssetMapping() {
|
|
|
4796
4709
|
// If getValidatedDexs fails, fall back to main DEX only to keep the provider
|
|
4797
4710
|
// functional. Without this, a transient perpDexs() failure would permanently
|
|
4798
4711
|
// brick #ensureReady via the cached rejected promise.
|
|
4799
|
-
// Do not
|
|
4712
|
+
// Do not update #dexDiscoveryCache here — leave state null
|
|
4800
4713
|
// so #getValidatedDexs retries on the next call (same as #fetchValidatedDexsInternal).
|
|
4801
4714
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('[buildAssetMapping] getValidatedDexs failed, falling back to main DEX', { error: String(dexError) });
|
|
4802
4715
|
dexsToMap = [null];
|
|
4803
4716
|
}
|
|
4804
|
-
// Local fallback only — never write [null] into #
|
|
4805
|
-
// That
|
|
4717
|
+
// Local fallback only — never write [null] into #dexDiscoveryCache here.
|
|
4718
|
+
// That state is owned exclusively by #dexDiscoveryCache.update(); writing a
|
|
4806
4719
|
// fallback here would prevent subsequent callers from retrying perpDexs().
|
|
4807
|
-
const allPerpDexs = __classPrivateFieldGet(this,
|
|
4720
|
+
const allPerpDexs = __classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").state?.raw ?? [null];
|
|
4808
4721
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: Starting asset mapping rebuild', {
|
|
4809
4722
|
dexs: dexsToMap,
|
|
4810
4723
|
previousMapSize: __classPrivateFieldGet(this, _HyperLiquidProvider_symbolToAssetId, "f").size,
|
|
@@ -4857,7 +4770,7 @@ async function _HyperLiquidProvider_buildAssetMapping() {
|
|
|
4857
4770
|
}));
|
|
4858
4771
|
// Build mapping with DEX prefixes for HIP-3 DEXs using the utility function
|
|
4859
4772
|
__classPrivateFieldGet(this, _HyperLiquidProvider_symbolToAssetId, "f").clear();
|
|
4860
|
-
let dexDiscoveryComplete = __classPrivateFieldGet(this,
|
|
4773
|
+
let dexDiscoveryComplete = __classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").state !== null;
|
|
4861
4774
|
allMetas.forEach((result) => {
|
|
4862
4775
|
if (result.status === 'fulfilled' &&
|
|
4863
4776
|
result.value.success &&
|
|
@@ -5148,8 +5061,7 @@ async function _HyperLiquidProvider_findSourceDexWithBalance(params) {
|
|
|
5148
5061
|
}
|
|
5149
5062
|
// Try other HIP-3 DEXs
|
|
5150
5063
|
// Get all available DEXs from cache (includes all HIP-3 DEXs since we no longer filter)
|
|
5151
|
-
const availableDexs = __classPrivateFieldGet(this,
|
|
5152
|
-
[];
|
|
5064
|
+
const availableDexs = __classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").state?.validated?.filter((dex) => dex !== null) ?? [];
|
|
5153
5065
|
for (const dex of availableDexs) {
|
|
5154
5066
|
if (dex === targetDex) {
|
|
5155
5067
|
continue;
|
|
@@ -5733,14 +5645,14 @@ async function _HyperLiquidProvider_submitOrderWithRollback(params) {
|
|
|
5733
5645
|
* @returns A promise that resolves to the result.
|
|
5734
5646
|
*/
|
|
5735
5647
|
async function _HyperLiquidProvider_getStandaloneValidatedDexs() {
|
|
5736
|
-
// Return cached result if available
|
|
5737
|
-
if (__classPrivateFieldGet(this,
|
|
5738
|
-
return __classPrivateFieldGet(this,
|
|
5648
|
+
// Return cached result if available (unified state)
|
|
5649
|
+
if (__classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").state?.validated) {
|
|
5650
|
+
return __classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").state.validated;
|
|
5739
5651
|
}
|
|
5740
5652
|
// Kill switch: HIP-3 disabled, return main DEX only
|
|
5741
5653
|
if (!__classPrivateFieldGet(this, _HyperLiquidProvider_hip3Enabled, "f")) {
|
|
5742
|
-
|
|
5743
|
-
return
|
|
5654
|
+
const state = __classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").update([null]);
|
|
5655
|
+
return state.validated;
|
|
5744
5656
|
}
|
|
5745
5657
|
// Fetch available DEXs via standalone client
|
|
5746
5658
|
const standaloneInfoClient = (0, standaloneInfoClient_1.createStandaloneInfoClient)({
|
|
@@ -5752,33 +5664,18 @@ async function _HyperLiquidProvider_getStandaloneValidatedDexs() {
|
|
|
5752
5664
|
}
|
|
5753
5665
|
catch {
|
|
5754
5666
|
__classPrivateFieldGet(this, _HyperLiquidProvider_deps, "f").debugLogger.log('HyperLiquidProvider: standalone perpDexs() failed, falling back to main DEX only');
|
|
5667
|
+
// Do not cache — transient error, allow retry on next call
|
|
5755
5668
|
return [null];
|
|
5756
5669
|
}
|
|
5757
5670
|
// Validate response
|
|
5758
5671
|
if (!allDexs || !Array.isArray(allDexs)) {
|
|
5672
|
+
// Do not cache — may be transient, allow retry on next call
|
|
5759
5673
|
return [null];
|
|
5760
5674
|
}
|
|
5761
|
-
//
|
|
5762
|
-
//
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
__classPrivateFieldSet(this, _HyperLiquidProvider_cachedAllPerpDexs, allDexs, "f");
|
|
5766
|
-
// Extract HIP-3 DEX names (filter out null which represents main DEX)
|
|
5767
|
-
const availableHip3Dexs = [];
|
|
5768
|
-
allDexs.forEach((dex) => {
|
|
5769
|
-
if (dex !== null) {
|
|
5770
|
-
availableHip3Dexs.push(dex.name);
|
|
5771
|
-
}
|
|
5772
|
-
});
|
|
5773
|
-
// Filter by allowlist patterns (same logic as fetchValidatedDexsInternal)
|
|
5774
|
-
const allowedDexsFromAllowlist = __classPrivateFieldGet(this, _HyperLiquidProvider_instances, "m", _HyperLiquidProvider_extractDexsFromAllowlist).call(this);
|
|
5775
|
-
if (allowedDexsFromAllowlist.length === 0) {
|
|
5776
|
-
__classPrivateFieldSet(this, _HyperLiquidProvider_cachedValidatedDexs, [null], "f");
|
|
5777
|
-
return __classPrivateFieldGet(this, _HyperLiquidProvider_cachedValidatedDexs, "f");
|
|
5778
|
-
}
|
|
5779
|
-
const filteredDexs = availableHip3Dexs.filter((dex) => allowedDexsFromAllowlist.includes(dex));
|
|
5780
|
-
__classPrivateFieldSet(this, _HyperLiquidProvider_cachedValidatedDexs, [null, ...filteredDexs], "f");
|
|
5781
|
-
return __classPrivateFieldGet(this, _HyperLiquidProvider_cachedValidatedDexs, "f");
|
|
5675
|
+
// Atomically update unified state (raw + validated + timestamp).
|
|
5676
|
+
// buildAssetMapping uses state.raw for perpDexIndex computation.
|
|
5677
|
+
const state = __classPrivateFieldGet(this, _HyperLiquidProvider_dexDiscoveryCache, "f").update(allDexs);
|
|
5678
|
+
return state.validated;
|
|
5782
5679
|
}, _HyperLiquidProvider_getAllMids =
|
|
5783
5680
|
/**
|
|
5784
5681
|
* Get allMids for a DEX — uses WS snapshot as primary source, REST as fallback.
|