@metamask-previews/perps-controller 11.0.0-preview-9efd0b754 → 11.0.0-preview-ea8763e0c
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 +8 -0
- package/dist/PerpsController-method-action-types.cjs.map +1 -1
- package/dist/PerpsController-method-action-types.d.cts +12 -1
- package/dist/PerpsController-method-action-types.d.cts.map +1 -1
- package/dist/PerpsController-method-action-types.d.mts +12 -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 +519 -99
- package/dist/PerpsController.cjs.map +1 -1
- package/dist/PerpsController.d.cts +17 -4
- package/dist/PerpsController.d.cts.map +1 -1
- package/dist/PerpsController.d.mts +17 -4
- package/dist/PerpsController.d.mts.map +1 -1
- package/dist/PerpsController.mjs +522 -102
- package/dist/PerpsController.mjs.map +1 -1
- package/dist/constants/eventNames.cjs +3 -0
- package/dist/constants/eventNames.cjs.map +1 -1
- package/dist/constants/eventNames.d.cts +1 -0
- package/dist/constants/eventNames.d.cts.map +1 -1
- package/dist/constants/eventNames.d.mts +1 -0
- package/dist/constants/eventNames.d.mts.map +1 -1
- package/dist/constants/eventNames.mjs +3 -0
- package/dist/constants/eventNames.mjs.map +1 -1
- package/dist/constants/hyperLiquidConfig.cjs +14 -2
- package/dist/constants/hyperLiquidConfig.cjs.map +1 -1
- package/dist/constants/hyperLiquidConfig.d.cts +7 -0
- package/dist/constants/hyperLiquidConfig.d.cts.map +1 -1
- package/dist/constants/hyperLiquidConfig.d.mts +7 -0
- package/dist/constants/hyperLiquidConfig.d.mts.map +1 -1
- package/dist/constants/hyperLiquidConfig.mjs +11 -0
- package/dist/constants/hyperLiquidConfig.mjs.map +1 -1
- package/dist/constants/perpsConfig.cjs +4 -1
- package/dist/constants/perpsConfig.cjs.map +1 -1
- package/dist/constants/perpsConfig.d.cts +25 -7
- package/dist/constants/perpsConfig.d.cts.map +1 -1
- package/dist/constants/perpsConfig.d.mts +25 -7
- package/dist/constants/perpsConfig.d.mts.map +1 -1
- package/dist/constants/perpsConfig.mjs +4 -1
- package/dist/constants/perpsConfig.mjs.map +1 -1
- 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.map +1 -1
- package/dist/providers/HyperLiquidProvider.cjs +148 -1
- package/dist/providers/HyperLiquidProvider.cjs.map +1 -1
- package/dist/providers/HyperLiquidProvider.d.cts +11 -1
- package/dist/providers/HyperLiquidProvider.d.cts.map +1 -1
- package/dist/providers/HyperLiquidProvider.d.mts +11 -1
- package/dist/providers/HyperLiquidProvider.d.mts.map +1 -1
- package/dist/providers/HyperLiquidProvider.mjs +149 -2
- package/dist/providers/HyperLiquidProvider.mjs.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.cjs +15 -4
- package/dist/services/HyperLiquidSubscriptionService.cjs.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.d.cts +1 -1
- package/dist/services/HyperLiquidSubscriptionService.d.cts.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.d.mts +1 -1
- package/dist/services/HyperLiquidSubscriptionService.d.mts.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.mjs +15 -4
- package/dist/services/HyperLiquidSubscriptionService.mjs.map +1 -1
- package/dist/services/MarketDataService.cjs +41 -3
- package/dist/services/MarketDataService.cjs.map +1 -1
- package/dist/services/MarketDataService.d.cts +2 -2
- package/dist/services/MarketDataService.d.cts.map +1 -1
- package/dist/services/MarketDataService.d.mts +2 -2
- package/dist/services/MarketDataService.d.mts.map +1 -1
- package/dist/services/MarketDataService.mjs +41 -3
- package/dist/services/MarketDataService.mjs.map +1 -1
- package/dist/services/ServiceContext.cjs.map +1 -1
- package/dist/services/ServiceContext.d.cts +10 -1
- package/dist/services/ServiceContext.d.cts.map +1 -1
- package/dist/services/ServiceContext.d.mts +10 -1
- package/dist/services/ServiceContext.d.mts.map +1 -1
- package/dist/services/ServiceContext.mjs.map +1 -1
- package/dist/services/TerminalMarketService.cjs +422 -7
- package/dist/services/TerminalMarketService.cjs.map +1 -1
- package/dist/services/TerminalMarketService.d.cts +10 -1
- package/dist/services/TerminalMarketService.d.cts.map +1 -1
- package/dist/services/TerminalMarketService.d.mts +10 -1
- package/dist/services/TerminalMarketService.d.mts.map +1 -1
- package/dist/services/TerminalMarketService.mjs +423 -8
- package/dist/services/TerminalMarketService.mjs.map +1 -1
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.cts +43 -7
- package/dist/types/index.d.cts.map +1 -1
- package/dist/types/index.d.mts +43 -7
- package/dist/types/index.d.mts.map +1 -1
- package/dist/types/index.mjs.map +1 -1
- package/dist/utils/marketUtils.cjs +16 -1
- package/dist/utils/marketUtils.cjs.map +1 -1
- package/dist/utils/marketUtils.d.cts +1 -0
- package/dist/utils/marketUtils.d.cts.map +1 -1
- package/dist/utils/marketUtils.d.mts +1 -0
- package/dist/utils/marketUtils.d.mts.map +1 -1
- package/dist/utils/marketUtils.mjs +14 -0
- package/dist/utils/marketUtils.mjs.map +1 -1
- package/dist/utils/perpsDiskPersistence.cjs +19 -12
- package/dist/utils/perpsDiskPersistence.cjs.map +1 -1
- package/dist/utils/perpsDiskPersistence.d.cts +5 -1
- package/dist/utils/perpsDiskPersistence.d.cts.map +1 -1
- package/dist/utils/perpsDiskPersistence.d.mts +5 -1
- package/dist/utils/perpsDiskPersistence.d.mts.map +1 -1
- package/dist/utils/perpsDiskPersistence.mjs +19 -12
- package/dist/utils/perpsDiskPersistence.mjs.map +1 -1
- package/package.json +1 -1
package/dist/PerpsController.cjs
CHANGED
|
@@ -10,7 +10,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
11
11
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
12
12
|
};
|
|
13
|
-
var _PerpsController_instances, _a, _PerpsController_initializationPromise, _PerpsController_isReinitializing, _PerpsController_myxRegistrationPromise, _PerpsController_blockedRegionListVersion, _PerpsController_hip3Enabled, _PerpsController_hip3AllowlistMarkets, _PerpsController_hip3BlocklistMarkets, _PerpsController_hip3ConfigSource, _PerpsController_priceDeviationLimit, _PerpsController_attributionContext, _PerpsController_isMYXProviderEnabled, _PerpsController_standaloneProvider, _PerpsController_handlersRegistered, _PerpsController_standaloneProviderIsTestnet, _PerpsController_standaloneProviderHip3Version, _PerpsController_eligibilityCheckDeferred, _PerpsController_ausQueue, _PerpsController_options, _PerpsController_tradingService, _PerpsController_marketDataService, _PerpsController_accountService, _PerpsController_eligibilityService, _PerpsController_dataLakeService, _PerpsController_depositService, _PerpsController_featureFlagConfigurationService, _PerpsController_rewardsIntegrationService, _PerpsController_logError, _PerpsController_debugLog, _PerpsController_getAggregatedCacheProviderIds, _PerpsController_getOrCreateStandaloneProvider, _PerpsController_cleanupStandaloneProvider, _PerpsController_getMetrics, _PerpsController_findNetworkClientIdForChain, _PerpsController_submitTransaction, _PerpsController_migrateRequestsIfNeeded, _PerpsController_withStreamPause, _PerpsController_performInitialization, _PerpsController_createProviders, _PerpsController_assignActiveProvider, _PerpsController_getErrorContext, _PerpsController_getControllerState, _PerpsController_buildMarketAllowedFilter, _PerpsController_compilePatternsSafely, _PerpsController_createServiceContext, _PerpsController_ensureTradingServiceDeps, _PerpsController_preloadWatchedPaths, _PerpsController_preloadTimer, _PerpsController_isPreloading, _PerpsController_isPreloadingUserData, _PerpsController_preloadStateUnsubscribe, _PerpsController_accountChangeUnsubscribe, _PerpsController_previousIsTestnet, _PerpsController_previousHip3ConfigVersion, _PerpsController_preloadRefreshMs, _PerpsController_preloadGuardMs, _PerpsController_hydrateCacheFromDiskSync, _PerpsController_performMarketDataPreload, _PerpsController_performUserDataPreload, _PerpsController_persistWatchlistToRemote, _PerpsController_syncWatchlistFromRemote;
|
|
13
|
+
var _PerpsController_instances, _a, _PerpsController_initializationPromise, _PerpsController_isReinitializing, _PerpsController_myxRegistrationPromise, _PerpsController_blockedRegionListVersion, _PerpsController_hip3Enabled, _PerpsController_hip3AllowlistMarkets, _PerpsController_hip3BlocklistMarkets, _PerpsController_hip3ConfigSource, _PerpsController_priceDeviationLimit, _PerpsController_attributionContext, _PerpsController_isMYXProviderEnabled, _PerpsController_standaloneProvider, _PerpsController_handlersRegistered, _PerpsController_standaloneProviderIsTestnet, _PerpsController_standaloneProviderHip3Version, _PerpsController_standaloneProviderOperations, _PerpsController_eligibilityCheckDeferred, _PerpsController_ausQueue, _PerpsController_userDiskWrite, _PerpsController_options, _PerpsController_tradingService, _PerpsController_marketDataService, _PerpsController_accountService, _PerpsController_eligibilityService, _PerpsController_dataLakeService, _PerpsController_depositService, _PerpsController_featureFlagConfigurationService, _PerpsController_rewardsIntegrationService, _PerpsController_logError, _PerpsController_debugLog, _PerpsController_getAggregatedCacheProviderIds, _PerpsController_isMarketCacheEntryCurrent, _PerpsController_isUserCacheIdentityCurrent, _PerpsController_fetchAndCacheUserDataSnapshot, _PerpsController_getOrCreateStandaloneProvider, _PerpsController_trackStandaloneProviderOperation, _PerpsController_retireStandaloneProvider, _PerpsController_cleanupStandaloneProvider, _PerpsController_getMetrics, _PerpsController_findNetworkClientIdForChain, _PerpsController_submitTransaction, _PerpsController_migrateRequestsIfNeeded, _PerpsController_withStreamPause, _PerpsController_performInitialization, _PerpsController_createProviders, _PerpsController_assignActiveProvider, _PerpsController_getErrorContext, _PerpsController_getControllerState, _PerpsController_buildMarketAllowedFilter, _PerpsController_compilePatternsSafely, _PerpsController_createServiceContext, _PerpsController_ensureTradingServiceDeps, _PerpsController_buildGlobalSnapshotContext, _PerpsController_getStaticSnapshotDexes, _PerpsController_preloadWatchedPaths, _PerpsController_preloadTimer, _PerpsController_isPreloading, _PerpsController_marketPreloadQueued, _PerpsController_isPreloadingUserData, _PerpsController_userPreloadQueued, _PerpsController_userSnapshotRequests, _PerpsController_preloadStateUnsubscribe, _PerpsController_accountChangeUnsubscribe, _PerpsController_previousIsTestnet, _PerpsController_previousHip3ConfigVersion, _PerpsController_preloadRefreshMs, _PerpsController_preloadGuardMs, _PerpsController_hydrateCacheFromDiskSync, _PerpsController_persistUserCacheToDisk, _PerpsController_performMarketDataPreload, _PerpsController_performUserDataPreload, _PerpsController_persistWatchlistToRemote, _PerpsController_syncWatchlistFromRemote;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.PerpsController = exports.getDefaultPerpsControllerState = exports.DEFAULT_PRO_LAYOUT_PREFERENCES = exports.DEFAULT_PERPS_MODE = exports.PerpsMode = exports.InitializationState = exports.PERPS_ERROR_CODES = exports.resolveMyxAuthConfig = exports.resolveWatchlistExchangeKey = exports.firstNonEmpty = void 0;
|
|
16
16
|
const base_controller_1 = require("@metamask/base-controller");
|
|
@@ -41,6 +41,36 @@ const hyperLiquidAdapter_js_1 = require("./utils/hyperLiquidAdapter.cjs");
|
|
|
41
41
|
const marketUtils_js_1 = require("./utils/marketUtils.cjs");
|
|
42
42
|
const perpsDiskPersistence_js_1 = require("./utils/perpsDiskPersistence.cjs");
|
|
43
43
|
const wait_js_1 = require("./utils/wait.cjs");
|
|
44
|
+
function cloneUserDataSnapshot(snapshot) {
|
|
45
|
+
return {
|
|
46
|
+
positions: snapshot.positions.map((position) => ({
|
|
47
|
+
...position,
|
|
48
|
+
leverage: { ...position.leverage },
|
|
49
|
+
cumulativeFunding: { ...position.cumulativeFunding },
|
|
50
|
+
...(position.takeProfitOrders && {
|
|
51
|
+
takeProfitOrders: position.takeProfitOrders.map((order) => ({
|
|
52
|
+
...order,
|
|
53
|
+
})),
|
|
54
|
+
}),
|
|
55
|
+
...(position.stopLossOrders && {
|
|
56
|
+
stopLossOrders: position.stopLossOrders.map((order) => ({
|
|
57
|
+
...order,
|
|
58
|
+
})),
|
|
59
|
+
}),
|
|
60
|
+
})),
|
|
61
|
+
orders: snapshot.orders.map((order) => ({ ...order })),
|
|
62
|
+
accountState: {
|
|
63
|
+
...snapshot.accountState,
|
|
64
|
+
...(snapshot.accountState.subAccountBreakdown && {
|
|
65
|
+
subAccountBreakdown: Object.fromEntries(Object.entries(snapshot.accountState.subAccountBreakdown).map(([dex, balances]) => [dex, { ...balances }])),
|
|
66
|
+
}),
|
|
67
|
+
},
|
|
68
|
+
identity: {
|
|
69
|
+
...snapshot.identity,
|
|
70
|
+
dexes: [...snapshot.identity.dexes],
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
44
74
|
/**
|
|
45
75
|
* Returns the first non-empty string from the given values.
|
|
46
76
|
* Env vars default to '' (not null/undefined), so ?? wouldn't fall through.
|
|
@@ -411,6 +441,7 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
411
441
|
'getBlockExplorerUrl',
|
|
412
442
|
'getCachedMarketDataForActiveProvider',
|
|
413
443
|
'getCachedUserDataForActiveProvider',
|
|
444
|
+
'getUserDataSnapshot',
|
|
414
445
|
'getCurrentNetwork',
|
|
415
446
|
'getFunding',
|
|
416
447
|
'getHistoricalPortfolio',
|
|
@@ -543,6 +574,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
543
574
|
_PerpsController_handlersRegistered.set(this, false);
|
|
544
575
|
_PerpsController_standaloneProviderIsTestnet.set(this, null);
|
|
545
576
|
_PerpsController_standaloneProviderHip3Version.set(this, null);
|
|
577
|
+
_PerpsController_standaloneProviderOperations.set(this, new Map());
|
|
546
578
|
_PerpsController_eligibilityCheckDeferred.set(this, void 0);
|
|
547
579
|
/**
|
|
548
580
|
* Serial promise queue for all AUS watchlist operations (hydration and
|
|
@@ -558,6 +590,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
558
590
|
* a failed operation does not stall subsequent ones.
|
|
559
591
|
*/
|
|
560
592
|
_PerpsController_ausQueue.set(this, Promise.resolve());
|
|
593
|
+
_PerpsController_userDiskWrite.set(this, Promise.resolve());
|
|
561
594
|
// Store options for dependency injection (allows core package to inject platform-specific services)
|
|
562
595
|
_PerpsController_options.set(this, void 0);
|
|
563
596
|
// Service instances (instantiated with platform dependencies)
|
|
@@ -571,7 +604,10 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
571
604
|
_PerpsController_rewardsIntegrationService.set(this, void 0);
|
|
572
605
|
_PerpsController_preloadTimer.set(this, null);
|
|
573
606
|
_PerpsController_isPreloading.set(this, false);
|
|
607
|
+
_PerpsController_marketPreloadQueued.set(this, false);
|
|
574
608
|
_PerpsController_isPreloadingUserData.set(this, false);
|
|
609
|
+
_PerpsController_userPreloadQueued.set(this, false);
|
|
610
|
+
_PerpsController_userSnapshotRequests.set(this, new Map());
|
|
575
611
|
_PerpsController_preloadStateUnsubscribe.set(this, null);
|
|
576
612
|
_PerpsController_accountChangeUnsubscribe.set(this, null);
|
|
577
613
|
_PerpsController_previousIsTestnet.set(this, null);
|
|
@@ -590,7 +626,9 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
590
626
|
__classPrivateFieldSet(this, _PerpsController_marketDataService, new MarketDataService_js_1.MarketDataService({
|
|
591
627
|
...infrastructure,
|
|
592
628
|
terminalMarketService: infrastructure.terminalMarketService ??
|
|
593
|
-
(infrastructure.
|
|
629
|
+
(infrastructure.terminalApi?.marketDataUrl ||
|
|
630
|
+
infrastructure.terminalApiUrl ||
|
|
631
|
+
infrastructure.terminalApi?.globalSnapshotUrl
|
|
594
632
|
? new TerminalMarketService_js_1.TerminalMarketService(infrastructure)
|
|
595
633
|
: undefined),
|
|
596
634
|
}), "f");
|
|
@@ -657,24 +695,20 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
657
695
|
if (activeProvider === 'aggregated') {
|
|
658
696
|
// Assemble from all registered provider entries
|
|
659
697
|
const assembled = [];
|
|
660
|
-
let oldestTimestamp = Infinity;
|
|
661
698
|
for (const providerId of __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getAggregatedCacheProviderIds).call(this, Object.keys(cache))) {
|
|
662
699
|
const key = (0, perpsConfig_js_1.buildProviderCacheKey)(providerId, this.state.isTestnet);
|
|
663
700
|
const entry = cache[key];
|
|
664
701
|
if (!entry || entry.data.length === 0) {
|
|
665
702
|
continue;
|
|
666
703
|
}
|
|
667
|
-
|
|
668
|
-
|
|
704
|
+
if (!__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_isMarketCacheEntryCurrent).call(this, providerId, entry, options)) {
|
|
705
|
+
continue;
|
|
706
|
+
}
|
|
707
|
+
assembled.push(...(0, marketUtils_js_1.clonePerpsMarketData)(entry.data));
|
|
669
708
|
}
|
|
670
709
|
if (assembled.length === 0) {
|
|
671
710
|
return null;
|
|
672
711
|
}
|
|
673
|
-
// Check TTL against the oldest entry
|
|
674
|
-
if (!options?.skipTTL &&
|
|
675
|
-
Date.now() - oldestTimestamp > __classPrivateFieldGet(_a, _a, "f", _PerpsController_preloadGuardMs) * 10) {
|
|
676
|
-
return null;
|
|
677
|
-
}
|
|
678
712
|
return assembled;
|
|
679
713
|
}
|
|
680
714
|
// Single provider mode
|
|
@@ -683,11 +717,10 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
683
717
|
if (!entry || entry.data.length === 0) {
|
|
684
718
|
return null;
|
|
685
719
|
}
|
|
686
|
-
if (!options
|
|
687
|
-
Date.now() - entry.timestamp > __classPrivateFieldGet(_a, _a, "f", _PerpsController_preloadGuardMs) * 10) {
|
|
720
|
+
if (!__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_isMarketCacheEntryCurrent).call(this, activeProvider, entry, options)) {
|
|
688
721
|
return null;
|
|
689
722
|
}
|
|
690
|
-
return entry.data;
|
|
723
|
+
return (0, marketUtils_js_1.clonePerpsMarketData)(entry.data);
|
|
691
724
|
}
|
|
692
725
|
/**
|
|
693
726
|
* Read cached user data for the currently active provider (or aggregated).
|
|
@@ -711,18 +744,21 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
711
744
|
currentAddress = evmAccount?.address ?? null;
|
|
712
745
|
}
|
|
713
746
|
catch {
|
|
714
|
-
//
|
|
747
|
+
// Account identity is required before account-scoped data can be trusted.
|
|
715
748
|
}
|
|
749
|
+
if (!currentAddress) {
|
|
750
|
+
return null;
|
|
751
|
+
}
|
|
752
|
+
const selectedAddress = currentAddress;
|
|
716
753
|
const skipTTL = options?.skipTTL ?? false;
|
|
717
|
-
const isValidEntry = (entry) => {
|
|
754
|
+
const isValidEntry = (providerId, entry) => {
|
|
718
755
|
if (!entry) {
|
|
719
756
|
return false;
|
|
720
757
|
}
|
|
721
758
|
if (!skipTTL && Date.now() - entry.timestamp >= staleCutoff) {
|
|
722
759
|
return false;
|
|
723
760
|
}
|
|
724
|
-
if (
|
|
725
|
-
entry.address.toLowerCase() !== currentAddress.toLowerCase()) {
|
|
761
|
+
if (!__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_isUserCacheIdentityCurrent).call(this, providerId, entry, selectedAddress)) {
|
|
726
762
|
return false;
|
|
727
763
|
}
|
|
728
764
|
return true;
|
|
@@ -734,9 +770,9 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
734
770
|
let defaultAccountState = null;
|
|
735
771
|
let hasValidEntry = false;
|
|
736
772
|
for (const providerId of __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getAggregatedCacheProviderIds).call(this, Object.keys(cache))) {
|
|
737
|
-
const
|
|
738
|
-
const entry = cache[
|
|
739
|
-
if (!isValidEntry(entry)) {
|
|
773
|
+
const providerNetworkKey = (0, perpsConfig_js_1.buildProviderCacheKey)(providerId, this.state.isTestnet);
|
|
774
|
+
const entry = cache[providerNetworkKey];
|
|
775
|
+
if (!isValidEntry(providerId, entry)) {
|
|
740
776
|
continue;
|
|
741
777
|
}
|
|
742
778
|
hasValidEntry = true;
|
|
@@ -757,9 +793,9 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
757
793
|
};
|
|
758
794
|
}
|
|
759
795
|
// Single provider mode
|
|
760
|
-
const
|
|
761
|
-
const entry = cache[
|
|
762
|
-
if (!entry || !isValidEntry(entry)) {
|
|
796
|
+
const providerNetworkKey = (0, perpsConfig_js_1.buildProviderCacheKey)(activeProvider, this.state.isTestnet);
|
|
797
|
+
const entry = cache[providerNetworkKey];
|
|
798
|
+
if (!entry || !isValidEntry(activeProvider, entry)) {
|
|
763
799
|
return null;
|
|
764
800
|
}
|
|
765
801
|
return {
|
|
@@ -768,6 +804,82 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
768
804
|
accountState: entry.accountState,
|
|
769
805
|
};
|
|
770
806
|
}
|
|
807
|
+
/**
|
|
808
|
+
* Fetch, validate, and atomically cache a complete user-data snapshot.
|
|
809
|
+
* This remains callable after mount so consumers can seed their live channel
|
|
810
|
+
* from one coherent positions/orders/account result.
|
|
811
|
+
*
|
|
812
|
+
* @returns The accepted user-data snapshot.
|
|
813
|
+
*/
|
|
814
|
+
async getUserDataSnapshot() {
|
|
815
|
+
const evmAccount = (0, accountUtils_js_1.getSelectedEvmAccountFromMessenger)(this.messenger);
|
|
816
|
+
if (!evmAccount?.address) {
|
|
817
|
+
throw new Error('Cannot fetch user data snapshot without an EVM account');
|
|
818
|
+
}
|
|
819
|
+
if (this.state.activeProvider !== 'hyperliquid') {
|
|
820
|
+
throw new Error('User data snapshots require Hyperliquid provider mode');
|
|
821
|
+
}
|
|
822
|
+
const capturedActiveProvider = this.activeProviderInstance;
|
|
823
|
+
const standaloneProvider = capturedActiveProvider
|
|
824
|
+
? null
|
|
825
|
+
: __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getOrCreateStandaloneProvider).call(this);
|
|
826
|
+
const provider = capturedActiveProvider ?? standaloneProvider;
|
|
827
|
+
if (!provider) {
|
|
828
|
+
throw new Error('Cannot create standalone Hyperliquid provider');
|
|
829
|
+
}
|
|
830
|
+
const { address } = evmAccount;
|
|
831
|
+
const { isTestnet, hip3ConfigVersion } = this.state;
|
|
832
|
+
const network = isTestnet ? 'testnet' : 'mainnet';
|
|
833
|
+
const expectedDexes = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getStaticSnapshotDexes).call(this);
|
|
834
|
+
if (!expectedDexes) {
|
|
835
|
+
throw new Error('User data snapshot DEX identity is not static');
|
|
836
|
+
}
|
|
837
|
+
const isCurrent = () => {
|
|
838
|
+
let currentAddress;
|
|
839
|
+
try {
|
|
840
|
+
currentAddress = (0, accountUtils_js_1.getSelectedEvmAccountFromMessenger)(this.messenger)?.address;
|
|
841
|
+
}
|
|
842
|
+
catch {
|
|
843
|
+
return false;
|
|
844
|
+
}
|
|
845
|
+
return (this.state.activeProvider === 'hyperliquid' &&
|
|
846
|
+
(!capturedActiveProvider ||
|
|
847
|
+
this.activeProviderInstance === capturedActiveProvider) &&
|
|
848
|
+
this.state.isTestnet === isTestnet &&
|
|
849
|
+
this.state.hip3ConfigVersion === hip3ConfigVersion &&
|
|
850
|
+
currentAddress?.toLowerCase() === address.toLowerCase());
|
|
851
|
+
};
|
|
852
|
+
const context = {
|
|
853
|
+
provider,
|
|
854
|
+
standaloneProvider,
|
|
855
|
+
address,
|
|
856
|
+
isTestnet,
|
|
857
|
+
hip3ConfigVersion,
|
|
858
|
+
expectedDexes,
|
|
859
|
+
isCurrent,
|
|
860
|
+
};
|
|
861
|
+
const requestKey = [
|
|
862
|
+
'hyperliquid',
|
|
863
|
+
network,
|
|
864
|
+
address.toLowerCase(),
|
|
865
|
+
hip3ConfigVersion,
|
|
866
|
+
...expectedDexes,
|
|
867
|
+
].join('|');
|
|
868
|
+
const existingRequest = __classPrivateFieldGet(this, _PerpsController_userSnapshotRequests, "f").get(requestKey);
|
|
869
|
+
if (existingRequest?.provider === provider) {
|
|
870
|
+
return existingRequest.promise;
|
|
871
|
+
}
|
|
872
|
+
const request = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_fetchAndCacheUserDataSnapshot).call(this, context);
|
|
873
|
+
__classPrivateFieldGet(this, _PerpsController_userSnapshotRequests, "f").set(requestKey, { provider, promise: request });
|
|
874
|
+
try {
|
|
875
|
+
return await request;
|
|
876
|
+
}
|
|
877
|
+
finally {
|
|
878
|
+
if (__classPrivateFieldGet(this, _PerpsController_userSnapshotRequests, "f").get(requestKey)?.promise === request) {
|
|
879
|
+
__classPrivateFieldGet(this, _PerpsController_userSnapshotRequests, "f").delete(requestKey);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
}
|
|
771
883
|
/**
|
|
772
884
|
* Test-observable accessor for whether a standalone provider is cached.
|
|
773
885
|
*
|
|
@@ -1543,7 +1655,10 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1543
1655
|
// Fallback to cached standalone provider for pre-initialization discovery
|
|
1544
1656
|
// TODO: When adding new providers (MYX), consider a provider factory pattern
|
|
1545
1657
|
const provider = this.activeProviderInstance ?? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getOrCreateStandaloneProvider).call(this);
|
|
1546
|
-
|
|
1658
|
+
const operation = provider.getPositions(params);
|
|
1659
|
+
return provider === __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f")
|
|
1660
|
+
? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_trackStandaloneProviderOperation).call(this, provider, operation)
|
|
1661
|
+
: operation;
|
|
1547
1662
|
}
|
|
1548
1663
|
const provider = this.getActiveProvider();
|
|
1549
1664
|
return __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getPositions({
|
|
@@ -1604,7 +1719,10 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1604
1719
|
// For standalone mode, access provider directly without initialization check
|
|
1605
1720
|
if (params?.standalone && params.userAddress) {
|
|
1606
1721
|
const provider = this.activeProviderInstance ?? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getOrCreateStandaloneProvider).call(this);
|
|
1607
|
-
|
|
1722
|
+
const operation = provider.getOpenOrders(params);
|
|
1723
|
+
return provider === __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f")
|
|
1724
|
+
? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_trackStandaloneProviderOperation).call(this, provider, operation)
|
|
1725
|
+
: operation;
|
|
1608
1726
|
}
|
|
1609
1727
|
const provider = this.getActiveProvider();
|
|
1610
1728
|
return __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getOpenOrders({
|
|
@@ -1649,7 +1767,10 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1649
1767
|
// Use activeProviderInstance if available (respects provider abstraction)
|
|
1650
1768
|
// Fallback to cached standalone provider for pre-initialization discovery
|
|
1651
1769
|
const provider = this.activeProviderInstance ?? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getOrCreateStandaloneProvider).call(this);
|
|
1652
|
-
|
|
1770
|
+
const operation = provider.getAccountState(params);
|
|
1771
|
+
return provider === __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f")
|
|
1772
|
+
? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_trackStandaloneProviderOperation).call(this, provider, operation)
|
|
1773
|
+
: operation;
|
|
1653
1774
|
}
|
|
1654
1775
|
const provider = this.getActiveProvider();
|
|
1655
1776
|
return __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getAccountState({
|
|
@@ -1687,12 +1808,15 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1687
1808
|
const isMarketAllowed = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_buildMarketAllowedFilter).call(this);
|
|
1688
1809
|
if (params?.standalone) {
|
|
1689
1810
|
const provider = this.activeProviderInstance ?? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getOrCreateStandaloneProvider).call(this);
|
|
1690
|
-
|
|
1811
|
+
const operation = __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getMarkets({
|
|
1691
1812
|
provider,
|
|
1692
1813
|
params,
|
|
1693
1814
|
context: __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_createServiceContext).call(this, 'getMarkets'),
|
|
1694
1815
|
isMarketAllowed,
|
|
1695
1816
|
});
|
|
1817
|
+
return provider === __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f")
|
|
1818
|
+
? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_trackStandaloneProviderOperation).call(this, provider, operation)
|
|
1819
|
+
: operation;
|
|
1696
1820
|
}
|
|
1697
1821
|
const provider = this.getActiveProvider();
|
|
1698
1822
|
return __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getMarkets({
|
|
@@ -1718,19 +1842,26 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1718
1842
|
* @returns A promise that resolves to the market data.
|
|
1719
1843
|
*/
|
|
1720
1844
|
async getMarketDataWithPrices(params) {
|
|
1845
|
+
const globalSnapshot = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_buildGlobalSnapshotContext).call(this);
|
|
1846
|
+
const context = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_createServiceContext).call(this, 'getMarketDataWithPrices', {
|
|
1847
|
+
...(globalSnapshot && { globalSnapshot }),
|
|
1848
|
+
});
|
|
1721
1849
|
if (params?.standalone) {
|
|
1722
1850
|
const provider = this.activeProviderInstance ?? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getOrCreateStandaloneProvider).call(this);
|
|
1723
|
-
|
|
1851
|
+
const operation = __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getMarketDataWithPrices({
|
|
1724
1852
|
provider,
|
|
1725
1853
|
params,
|
|
1726
|
-
context
|
|
1854
|
+
context,
|
|
1727
1855
|
});
|
|
1856
|
+
return provider === __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f")
|
|
1857
|
+
? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_trackStandaloneProviderOperation).call(this, provider, operation)
|
|
1858
|
+
: operation;
|
|
1728
1859
|
}
|
|
1729
1860
|
const provider = this.getActiveProvider();
|
|
1730
1861
|
return __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getMarketDataWithPrices({
|
|
1731
1862
|
provider,
|
|
1732
1863
|
params,
|
|
1733
|
-
context
|
|
1864
|
+
context,
|
|
1734
1865
|
});
|
|
1735
1866
|
}
|
|
1736
1867
|
/**
|
|
@@ -1751,11 +1882,17 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1751
1882
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performMarketDataPreload).call(this).catch(() => {
|
|
1752
1883
|
/* fire-and-forget */
|
|
1753
1884
|
});
|
|
1885
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
|
|
1886
|
+
/* fire-and-forget */
|
|
1887
|
+
});
|
|
1754
1888
|
// Periodic refresh
|
|
1755
1889
|
__classPrivateFieldSet(this, _PerpsController_preloadTimer, setInterval(() => {
|
|
1756
1890
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performMarketDataPreload).call(this).catch(() => {
|
|
1757
1891
|
/* fire-and-forget */
|
|
1758
1892
|
});
|
|
1893
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
|
|
1894
|
+
/* fire-and-forget */
|
|
1895
|
+
});
|
|
1759
1896
|
}, __classPrivateFieldGet(_a, _a, "f", _PerpsController_preloadRefreshMs)), "f");
|
|
1760
1897
|
// Watch for isTestnet / hip3ConfigVersion changes
|
|
1761
1898
|
const handler = (_state, patches) => {
|
|
@@ -1784,36 +1921,29 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1784
1921
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performMarketDataPreload).call(this).catch(() => {
|
|
1785
1922
|
/* fire-and-forget */
|
|
1786
1923
|
});
|
|
1924
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
|
|
1925
|
+
/* fire-and-forget */
|
|
1926
|
+
});
|
|
1787
1927
|
}
|
|
1788
1928
|
};
|
|
1789
|
-
this.messenger.subscribe('PerpsController:
|
|
1929
|
+
this.messenger.subscribe('PerpsController:stateChanged', handler);
|
|
1790
1930
|
__classPrivateFieldSet(this, _PerpsController_preloadStateUnsubscribe, () => {
|
|
1791
|
-
this.messenger.unsubscribe('PerpsController:
|
|
1931
|
+
this.messenger.unsubscribe('PerpsController:stateChanged', handler);
|
|
1792
1932
|
}, "f");
|
|
1793
1933
|
// Watch for selected account changes and selected account group changes.
|
|
1794
1934
|
const accountChangeHandler = () => {
|
|
1795
1935
|
const evmAccount = (0, accountUtils_js_1.getSelectedEvmAccountFromMessenger)(this.messenger);
|
|
1796
1936
|
const currentAddress = evmAccount?.address ?? null;
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
// Invalidate disk-cached user data for the old account
|
|
1806
|
-
__classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.diskCache
|
|
1807
|
-
.removeItem(perpsConfig_js_1.PERPS_DISK_CACHE_USER_DATA)
|
|
1808
|
-
.catch(() => {
|
|
1937
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: account cache selection', {
|
|
1938
|
+
address: currentAddress?.toLowerCase() ?? null,
|
|
1939
|
+
availableKeys: Object.keys(this.state.cachedUserDataByProvider).sort(),
|
|
1940
|
+
});
|
|
1941
|
+
// The address guard makes the previous entry unreadable immediately;
|
|
1942
|
+
// refresh replaces it under the existing provider/network key.
|
|
1943
|
+
if (currentAddress) {
|
|
1944
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
|
|
1809
1945
|
/* fire-and-forget */
|
|
1810
1946
|
});
|
|
1811
|
-
// Only preload if the new account is an EVM account
|
|
1812
|
-
if (currentAddress) {
|
|
1813
|
-
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
|
|
1814
|
-
/* fire-and-forget */
|
|
1815
|
-
});
|
|
1816
|
-
}
|
|
1817
1947
|
}
|
|
1818
1948
|
};
|
|
1819
1949
|
this.messenger.subscribe('AccountsController:selectedAccountChange', accountChangeHandler);
|
|
@@ -1842,6 +1972,8 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1842
1972
|
}
|
|
1843
1973
|
__classPrivateFieldSet(this, _PerpsController_previousIsTestnet, null, "f");
|
|
1844
1974
|
__classPrivateFieldSet(this, _PerpsController_previousHip3ConfigVersion, null, "f");
|
|
1975
|
+
__classPrivateFieldSet(this, _PerpsController_marketPreloadQueued, false, "f");
|
|
1976
|
+
__classPrivateFieldSet(this, _PerpsController_userPreloadQueued, false, "f");
|
|
1845
1977
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_cleanupStandaloneProvider).call(this).catch(() => {
|
|
1846
1978
|
/* fire-and-forget to preserve sync signature */
|
|
1847
1979
|
});
|
|
@@ -2102,6 +2234,9 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2102
2234
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performMarketDataPreload).call(this).catch(() => {
|
|
2103
2235
|
/* fire-and-forget */
|
|
2104
2236
|
});
|
|
2237
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
|
|
2238
|
+
/* fire-and-forget */
|
|
2239
|
+
});
|
|
2105
2240
|
}
|
|
2106
2241
|
}
|
|
2107
2242
|
}
|
|
@@ -2211,6 +2346,9 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2211
2346
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performMarketDataPreload).call(this).catch(() => {
|
|
2212
2347
|
/* fire-and-forget */
|
|
2213
2348
|
});
|
|
2349
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
|
|
2350
|
+
/* fire-and-forget */
|
|
2351
|
+
});
|
|
2214
2352
|
}
|
|
2215
2353
|
}
|
|
2216
2354
|
}
|
|
@@ -3274,7 +3412,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
3274
3412
|
}
|
|
3275
3413
|
}
|
|
3276
3414
|
exports.PerpsController = PerpsController;
|
|
3277
|
-
_a = PerpsController, _PerpsController_initializationPromise = new WeakMap(), _PerpsController_isReinitializing = new WeakMap(), _PerpsController_myxRegistrationPromise = new WeakMap(), _PerpsController_blockedRegionListVersion = new WeakMap(), _PerpsController_hip3Enabled = new WeakMap(), _PerpsController_hip3AllowlistMarkets = new WeakMap(), _PerpsController_hip3BlocklistMarkets = new WeakMap(), _PerpsController_hip3ConfigSource = new WeakMap(), _PerpsController_priceDeviationLimit = new WeakMap(), _PerpsController_attributionContext = new WeakMap(), _PerpsController_standaloneProvider = new WeakMap(), _PerpsController_handlersRegistered = new WeakMap(), _PerpsController_standaloneProviderIsTestnet = new WeakMap(), _PerpsController_standaloneProviderHip3Version = new WeakMap(), _PerpsController_eligibilityCheckDeferred = new WeakMap(), _PerpsController_ausQueue = new WeakMap(), _PerpsController_options = new WeakMap(), _PerpsController_tradingService = new WeakMap(), _PerpsController_marketDataService = new WeakMap(), _PerpsController_accountService = new WeakMap(), _PerpsController_eligibilityService = new WeakMap(), _PerpsController_dataLakeService = new WeakMap(), _PerpsController_depositService = new WeakMap(), _PerpsController_featureFlagConfigurationService = new WeakMap(), _PerpsController_rewardsIntegrationService = new WeakMap(), _PerpsController_preloadTimer = new WeakMap(), _PerpsController_isPreloading = new WeakMap(), _PerpsController_isPreloadingUserData = new WeakMap(), _PerpsController_preloadStateUnsubscribe = new WeakMap(), _PerpsController_accountChangeUnsubscribe = new WeakMap(), _PerpsController_previousIsTestnet = new WeakMap(), _PerpsController_previousHip3ConfigVersion = new WeakMap(), _PerpsController_instances = new WeakSet(), _PerpsController_isMYXProviderEnabled = function _PerpsController_isMYXProviderEnabled() {
|
|
3415
|
+
_a = PerpsController, _PerpsController_initializationPromise = new WeakMap(), _PerpsController_isReinitializing = new WeakMap(), _PerpsController_myxRegistrationPromise = new WeakMap(), _PerpsController_blockedRegionListVersion = new WeakMap(), _PerpsController_hip3Enabled = new WeakMap(), _PerpsController_hip3AllowlistMarkets = new WeakMap(), _PerpsController_hip3BlocklistMarkets = new WeakMap(), _PerpsController_hip3ConfigSource = new WeakMap(), _PerpsController_priceDeviationLimit = new WeakMap(), _PerpsController_attributionContext = new WeakMap(), _PerpsController_standaloneProvider = new WeakMap(), _PerpsController_handlersRegistered = new WeakMap(), _PerpsController_standaloneProviderIsTestnet = new WeakMap(), _PerpsController_standaloneProviderHip3Version = new WeakMap(), _PerpsController_standaloneProviderOperations = new WeakMap(), _PerpsController_eligibilityCheckDeferred = new WeakMap(), _PerpsController_ausQueue = new WeakMap(), _PerpsController_userDiskWrite = new WeakMap(), _PerpsController_options = new WeakMap(), _PerpsController_tradingService = new WeakMap(), _PerpsController_marketDataService = new WeakMap(), _PerpsController_accountService = new WeakMap(), _PerpsController_eligibilityService = new WeakMap(), _PerpsController_dataLakeService = new WeakMap(), _PerpsController_depositService = new WeakMap(), _PerpsController_featureFlagConfigurationService = new WeakMap(), _PerpsController_rewardsIntegrationService = new WeakMap(), _PerpsController_preloadTimer = new WeakMap(), _PerpsController_isPreloading = new WeakMap(), _PerpsController_marketPreloadQueued = new WeakMap(), _PerpsController_isPreloadingUserData = new WeakMap(), _PerpsController_userPreloadQueued = new WeakMap(), _PerpsController_userSnapshotRequests = new WeakMap(), _PerpsController_preloadStateUnsubscribe = new WeakMap(), _PerpsController_accountChangeUnsubscribe = new WeakMap(), _PerpsController_previousIsTestnet = new WeakMap(), _PerpsController_previousHip3ConfigVersion = new WeakMap(), _PerpsController_instances = new WeakSet(), _PerpsController_isMYXProviderEnabled = function _PerpsController_isMYXProviderEnabled() {
|
|
3278
3416
|
const myx = __classPrivateFieldGet(this, _PerpsController_options, "f").clientConfig?.providerCredentials?.myx;
|
|
3279
3417
|
// Local env-var override (MM_PERPS_MYX_PROVIDER_ENABLED) always wins —
|
|
3280
3418
|
// matches the UI selector (resolvePerpsMyxProviderEnabled) so controller
|
|
@@ -3327,6 +3465,96 @@ _a = PerpsController, _PerpsController_initializationPromise = new WeakMap(), _P
|
|
|
3327
3465
|
}
|
|
3328
3466
|
}
|
|
3329
3467
|
return Array.from(providerIds);
|
|
3468
|
+
}, _PerpsController_isMarketCacheEntryCurrent = function _PerpsController_isMarketCacheEntryCurrent(providerId, entry, options) {
|
|
3469
|
+
if (entry.sourceExpiresAt !== undefined) {
|
|
3470
|
+
const expectedDexes = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getStaticSnapshotDexes).call(this);
|
|
3471
|
+
return (providerId === 'hyperliquid' &&
|
|
3472
|
+
Date.now() < entry.sourceExpiresAt &&
|
|
3473
|
+
entry.hip3ConfigVersion === this.state.hip3ConfigVersion &&
|
|
3474
|
+
expectedDexes !== undefined &&
|
|
3475
|
+
Array.isArray(entry.dexes) &&
|
|
3476
|
+
entry.dexes.length === expectedDexes.length &&
|
|
3477
|
+
entry.dexes.every((dex, index) => dex === expectedDexes[index]));
|
|
3478
|
+
}
|
|
3479
|
+
return (options?.skipTTL === true ||
|
|
3480
|
+
Date.now() - entry.timestamp <= __classPrivateFieldGet(_a, _a, "f", _PerpsController_preloadGuardMs) * 10);
|
|
3481
|
+
}, _PerpsController_isUserCacheIdentityCurrent = function _PerpsController_isUserCacheIdentityCurrent(providerId, entry, address) {
|
|
3482
|
+
if (entry.address.toLowerCase() !== address.toLowerCase()) {
|
|
3483
|
+
return false;
|
|
3484
|
+
}
|
|
3485
|
+
if (providerId !== 'hyperliquid') {
|
|
3486
|
+
return true;
|
|
3487
|
+
}
|
|
3488
|
+
const expectedDexes = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getStaticSnapshotDexes).call(this);
|
|
3489
|
+
return (entry.hip3ConfigVersion === this.state.hip3ConfigVersion &&
|
|
3490
|
+
expectedDexes !== undefined &&
|
|
3491
|
+
Array.isArray(entry.dexes) &&
|
|
3492
|
+
entry.dexes.length === expectedDexes.length &&
|
|
3493
|
+
entry.dexes.every((dex, index) => dex === expectedDexes[index]));
|
|
3494
|
+
}, _PerpsController_fetchAndCacheUserDataSnapshot = async function _PerpsController_fetchAndCacheUserDataSnapshot(context) {
|
|
3495
|
+
const { provider, standaloneProvider, address, isTestnet, hip3ConfigVersion, expectedDexes, isCurrent, } = context;
|
|
3496
|
+
if (!isCurrent()) {
|
|
3497
|
+
throw new Error('User data snapshot context changed');
|
|
3498
|
+
}
|
|
3499
|
+
if (!provider.getUserDataSnapshot) {
|
|
3500
|
+
throw new Error('Provider has no atomic snapshot API');
|
|
3501
|
+
}
|
|
3502
|
+
const identity = {
|
|
3503
|
+
provider: 'hyperliquid',
|
|
3504
|
+
network: isTestnet ? 'testnet' : 'mainnet',
|
|
3505
|
+
hip3ConfigVersion,
|
|
3506
|
+
dexes: expectedDexes,
|
|
3507
|
+
};
|
|
3508
|
+
const snapshotRequest = provider.getUserDataSnapshot({
|
|
3509
|
+
userAddress: address,
|
|
3510
|
+
identity,
|
|
3511
|
+
});
|
|
3512
|
+
const snapshot = standaloneProvider
|
|
3513
|
+
? await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_trackStandaloneProviderOperation).call(this, standaloneProvider, snapshotRequest)
|
|
3514
|
+
: await snapshotRequest;
|
|
3515
|
+
if (!isCurrent()) {
|
|
3516
|
+
throw new Error('User data snapshot context changed');
|
|
3517
|
+
}
|
|
3518
|
+
const snapshotIdentity = snapshot.identity;
|
|
3519
|
+
const hasCompleteBundle = Array.isArray(snapshot.positions) &&
|
|
3520
|
+
Array.isArray(snapshot.orders) &&
|
|
3521
|
+
snapshot.accountState !== null &&
|
|
3522
|
+
typeof snapshot.accountState === 'object';
|
|
3523
|
+
const hasExactIdentity = snapshotIdentity.provider === identity.provider &&
|
|
3524
|
+
snapshotIdentity.network === identity.network &&
|
|
3525
|
+
snapshotIdentity.hip3ConfigVersion === identity.hip3ConfigVersion &&
|
|
3526
|
+
snapshotIdentity.address.toLowerCase() === address.toLowerCase() &&
|
|
3527
|
+
snapshotIdentity.dexes.length === expectedDexes.length &&
|
|
3528
|
+
snapshotIdentity.dexes.every((dex, index) => dex === expectedDexes[index]);
|
|
3529
|
+
if (!hasCompleteBundle || !hasExactIdentity) {
|
|
3530
|
+
throw new Error('User data snapshot is incomplete or mismatched');
|
|
3531
|
+
}
|
|
3532
|
+
if (!isCurrent()) {
|
|
3533
|
+
throw new Error('User data snapshot context changed');
|
|
3534
|
+
}
|
|
3535
|
+
const cachedSnapshot = cloneUserDataSnapshot(snapshot);
|
|
3536
|
+
const result = cloneUserDataSnapshot(snapshot);
|
|
3537
|
+
const timestamp = Date.now();
|
|
3538
|
+
const providerNetworkKey = (0, perpsConfig_js_1.buildProviderCacheKey)('hyperliquid', isTestnet);
|
|
3539
|
+
this.update((state) => {
|
|
3540
|
+
state.cachedUserDataByProvider[providerNetworkKey] = {
|
|
3541
|
+
positions: cachedSnapshot.positions,
|
|
3542
|
+
orders: cachedSnapshot.orders,
|
|
3543
|
+
accountState: cachedSnapshot.accountState,
|
|
3544
|
+
timestamp,
|
|
3545
|
+
address,
|
|
3546
|
+
hip3ConfigVersion,
|
|
3547
|
+
dexes: expectedDexes,
|
|
3548
|
+
};
|
|
3549
|
+
});
|
|
3550
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_persistUserCacheToDisk).call(this);
|
|
3551
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: user cache snapshot written', {
|
|
3552
|
+
writtenKey: providerNetworkKey,
|
|
3553
|
+
availableKeys: Object.keys(this.state.cachedUserDataByProvider).sort(),
|
|
3554
|
+
positionCount: cachedSnapshot.positions.length,
|
|
3555
|
+
orderCount: cachedSnapshot.orders.length,
|
|
3556
|
+
});
|
|
3557
|
+
return result;
|
|
3330
3558
|
}, _PerpsController_getOrCreateStandaloneProvider = function _PerpsController_getOrCreateStandaloneProvider() {
|
|
3331
3559
|
const currentIsTestnet = this.state.isTestnet;
|
|
3332
3560
|
const currentHip3Version = this.state.hip3ConfigVersion ?? 0;
|
|
@@ -3335,10 +3563,13 @@ _a = PerpsController, _PerpsController_initializationPromise = new WeakMap(), _P
|
|
|
3335
3563
|
__classPrivateFieldGet(this, _PerpsController_standaloneProviderHip3Version, "f") === currentHip3Version) {
|
|
3336
3564
|
return __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f");
|
|
3337
3565
|
}
|
|
3338
|
-
// Stale or missing —
|
|
3566
|
+
// Stale or missing — retire the old provider after active operations finish.
|
|
3339
3567
|
if (__classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f")) {
|
|
3340
3568
|
const old = __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f");
|
|
3341
|
-
|
|
3569
|
+
__classPrivateFieldSet(this, _PerpsController_standaloneProvider, null, "f");
|
|
3570
|
+
__classPrivateFieldSet(this, _PerpsController_standaloneProviderIsTestnet, null, "f");
|
|
3571
|
+
__classPrivateFieldSet(this, _PerpsController_standaloneProviderHip3Version, null, "f");
|
|
3572
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_retireStandaloneProvider).call(this, old).catch(() => {
|
|
3342
3573
|
/* best-effort */
|
|
3343
3574
|
});
|
|
3344
3575
|
}
|
|
@@ -3358,24 +3589,45 @@ _a = PerpsController, _PerpsController_initializationPromise = new WeakMap(), _P
|
|
|
3358
3589
|
__classPrivateFieldSet(this, _PerpsController_standaloneProviderIsTestnet, currentIsTestnet, "f");
|
|
3359
3590
|
__classPrivateFieldSet(this, _PerpsController_standaloneProviderHip3Version, currentHip3Version, "f");
|
|
3360
3591
|
return __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f");
|
|
3592
|
+
}, _PerpsController_trackStandaloneProviderOperation = function _PerpsController_trackStandaloneProviderOperation(provider, operation) {
|
|
3593
|
+
const operations = __classPrivateFieldGet(this, _PerpsController_standaloneProviderOperations, "f").get(provider) ?? new Set();
|
|
3594
|
+
__classPrivateFieldGet(this, _PerpsController_standaloneProviderOperations, "f").set(provider, operations);
|
|
3595
|
+
const trackedOperation = operation.finally(() => {
|
|
3596
|
+
operations.delete(trackedOperation);
|
|
3597
|
+
if (operations.size === 0) {
|
|
3598
|
+
__classPrivateFieldGet(this, _PerpsController_standaloneProviderOperations, "f").delete(provider);
|
|
3599
|
+
}
|
|
3600
|
+
});
|
|
3601
|
+
operations.add(trackedOperation);
|
|
3602
|
+
return trackedOperation;
|
|
3603
|
+
}, _PerpsController_retireStandaloneProvider = async function _PerpsController_retireStandaloneProvider(provider) {
|
|
3604
|
+
const operations = __classPrivateFieldGet(this, _PerpsController_standaloneProviderOperations, "f").get(provider);
|
|
3605
|
+
if (operations?.size) {
|
|
3606
|
+
await Promise.allSettled([...operations]);
|
|
3607
|
+
}
|
|
3608
|
+
try {
|
|
3609
|
+
await provider.disconnect();
|
|
3610
|
+
}
|
|
3611
|
+
catch {
|
|
3612
|
+
/* best-effort */
|
|
3613
|
+
}
|
|
3614
|
+
finally {
|
|
3615
|
+
__classPrivateFieldGet(this, _PerpsController_standaloneProviderOperations, "f").delete(provider);
|
|
3616
|
+
}
|
|
3361
3617
|
}, _PerpsController_cleanupStandaloneProvider =
|
|
3362
3618
|
/**
|
|
3363
3619
|
* Disconnect and discard the cached standalone provider (if any).
|
|
3364
3620
|
* Best-effort — errors are silently caught.
|
|
3365
3621
|
*/
|
|
3366
3622
|
async function _PerpsController_cleanupStandaloneProvider() {
|
|
3367
|
-
|
|
3623
|
+
const provider = __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f");
|
|
3624
|
+
if (!provider) {
|
|
3368
3625
|
return;
|
|
3369
3626
|
}
|
|
3370
|
-
try {
|
|
3371
|
-
await __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f").disconnect();
|
|
3372
|
-
}
|
|
3373
|
-
catch {
|
|
3374
|
-
/* best-effort */
|
|
3375
|
-
}
|
|
3376
3627
|
__classPrivateFieldSet(this, _PerpsController_standaloneProvider, null, "f");
|
|
3377
3628
|
__classPrivateFieldSet(this, _PerpsController_standaloneProviderIsTestnet, null, "f");
|
|
3378
3629
|
__classPrivateFieldSet(this, _PerpsController_standaloneProviderHip3Version, null, "f");
|
|
3630
|
+
await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_retireStandaloneProvider).call(this, provider);
|
|
3379
3631
|
}, _PerpsController_getMetrics = function _PerpsController_getMetrics() {
|
|
3380
3632
|
return __classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.metrics;
|
|
3381
3633
|
}, _PerpsController_findNetworkClientIdForChain = function _PerpsController_findNetworkClientIdForChain(chainId) {
|
|
@@ -3709,6 +3961,60 @@ async function _PerpsController_performInitialization() {
|
|
|
3709
3961
|
__classPrivateFieldGet(this, _PerpsController_tradingService, "f").setControllerDependencies({
|
|
3710
3962
|
rewardsIntegrationService: __classPrivateFieldGet(this, _PerpsController_rewardsIntegrationService, "f"),
|
|
3711
3963
|
});
|
|
3964
|
+
}, _PerpsController_buildGlobalSnapshotContext = function _PerpsController_buildGlobalSnapshotContext() {
|
|
3965
|
+
const snapshotConfigured = Boolean(__classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.terminalApi?.globalSnapshotUrl) ||
|
|
3966
|
+
typeof __classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.terminalMarketService
|
|
3967
|
+
?.fetchGlobalSnapshot === 'function';
|
|
3968
|
+
if (!snapshotConfigured || this.state.activeProvider !== 'hyperliquid') {
|
|
3969
|
+
return undefined;
|
|
3970
|
+
}
|
|
3971
|
+
const enabledDexes = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getStaticSnapshotDexes).call(this);
|
|
3972
|
+
if (!enabledDexes) {
|
|
3973
|
+
return undefined;
|
|
3974
|
+
}
|
|
3975
|
+
const { isTestnet, hip3ConfigVersion } = this.state;
|
|
3976
|
+
return {
|
|
3977
|
+
request: {
|
|
3978
|
+
provider: 'hyperliquid',
|
|
3979
|
+
network: isTestnet ? 'testnet' : 'mainnet',
|
|
3980
|
+
enabledDexes,
|
|
3981
|
+
},
|
|
3982
|
+
isCurrent: () => this.state.activeProvider === 'hyperliquid' &&
|
|
3983
|
+
this.state.isTestnet === isTestnet &&
|
|
3984
|
+
this.state.hip3ConfigVersion === hip3ConfigVersion,
|
|
3985
|
+
isMarketAllowed: __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_buildMarketAllowedFilter).call(this),
|
|
3986
|
+
};
|
|
3987
|
+
}, _PerpsController_getStaticSnapshotDexes = function _PerpsController_getStaticSnapshotDexes() {
|
|
3988
|
+
if (!__classPrivateFieldGet(this, _PerpsController_hip3Enabled, "f")) {
|
|
3989
|
+
return ['main'];
|
|
3990
|
+
}
|
|
3991
|
+
if (this.state.isTestnet) {
|
|
3992
|
+
return hyperLiquidConfig_js_1.TESTNET_HIP3_CONFIG.AutoDiscoverAll
|
|
3993
|
+
? undefined
|
|
3994
|
+
: (0, hyperLiquidConfig_js_1.canonicalizeHyperLiquidDexes)(hyperLiquidConfig_js_1.TESTNET_HIP3_CONFIG.EnabledDexs);
|
|
3995
|
+
}
|
|
3996
|
+
if (hyperLiquidConfig_js_1.MAINNET_HIP3_CONFIG.AutoDiscoverAll) {
|
|
3997
|
+
return undefined;
|
|
3998
|
+
}
|
|
3999
|
+
const dexes = new Set();
|
|
4000
|
+
for (const pattern of __classPrivateFieldGet(this, _PerpsController_hip3AllowlistMarkets, "f")) {
|
|
4001
|
+
const colonIndex = pattern.indexOf(':');
|
|
4002
|
+
if (colonIndex <= 0) {
|
|
4003
|
+
if (/^[a-z][a-z0-9]*$/iu.test(pattern)) {
|
|
4004
|
+
dexes.add(pattern.toLowerCase());
|
|
4005
|
+
continue;
|
|
4006
|
+
}
|
|
4007
|
+
return undefined;
|
|
4008
|
+
}
|
|
4009
|
+
const dex = pattern.slice(0, colonIndex);
|
|
4010
|
+
if (dex && /^[a-z0-9][a-z0-9-]*$/u.test(dex)) {
|
|
4011
|
+
dexes.add(dex);
|
|
4012
|
+
}
|
|
4013
|
+
else {
|
|
4014
|
+
return undefined;
|
|
4015
|
+
}
|
|
4016
|
+
}
|
|
4017
|
+
return (0, hyperLiquidConfig_js_1.canonicalizeHyperLiquidDexes)(dexes);
|
|
3712
4018
|
}, _PerpsController_hydrateCacheFromDiskSync = function _PerpsController_hydrateCacheFromDiskSync() {
|
|
3713
4019
|
const { marketUpdates, userUpdates, stats } = (0, perpsDiskPersistence_js_1.hydrateFromDiskSync)(__classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.diskCache, this.state.cachedMarketDataByProvider, this.state.cachedUserDataByProvider, __classPrivateFieldGet(_a, _a, "f", _PerpsController_preloadGuardMs));
|
|
3714
4020
|
const hasMarketUpdates = Object.keys(marketUpdates).length > 0;
|
|
@@ -3729,12 +4035,40 @@ async function _PerpsController_performInitialization() {
|
|
|
3729
4035
|
orders: stats.userOrders,
|
|
3730
4036
|
duration_ms: stats.durationMs,
|
|
3731
4037
|
});
|
|
4038
|
+
}, _PerpsController_persistUserCacheToDisk = function _PerpsController_persistUserCacheToDisk() {
|
|
4039
|
+
const entries = [];
|
|
4040
|
+
for (const [cacheKey, entry] of Object.entries(this.state.cachedUserDataByProvider)) {
|
|
4041
|
+
const [providerId, network] = cacheKey.split(':');
|
|
4042
|
+
if (!providerId ||
|
|
4043
|
+
(network !== 'mainnet' && network !== 'testnet') ||
|
|
4044
|
+
providerId === 'aggregated') {
|
|
4045
|
+
continue;
|
|
4046
|
+
}
|
|
4047
|
+
entries.push({
|
|
4048
|
+
providerNetworkKey: `${providerId}:${network}`,
|
|
4049
|
+
address: entry.address,
|
|
4050
|
+
positions: entry.positions,
|
|
4051
|
+
orders: entry.orders,
|
|
4052
|
+
accountState: entry.accountState,
|
|
4053
|
+
timestamp: entry.timestamp,
|
|
4054
|
+
...(entry.hip3ConfigVersion !== undefined && {
|
|
4055
|
+
hip3ConfigVersion: entry.hip3ConfigVersion,
|
|
4056
|
+
}),
|
|
4057
|
+
...(entry.dexes !== undefined && { dexes: entry.dexes }),
|
|
4058
|
+
});
|
|
4059
|
+
}
|
|
4060
|
+
__classPrivateFieldSet(this, _PerpsController_userDiskWrite, __classPrivateFieldGet(this, _PerpsController_userDiskWrite, "f")
|
|
4061
|
+
.then(() => (0, perpsDiskPersistence_js_1.persistUserEntriesToDisk)(__classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.diskCache, entries))
|
|
4062
|
+
.catch(() => {
|
|
4063
|
+
// Disk persistence is best-effort and must not block live data.
|
|
4064
|
+
}), "f");
|
|
3732
4065
|
}, _PerpsController_performMarketDataPreload =
|
|
3733
4066
|
/**
|
|
3734
4067
|
* Perform a single market data preload (best-effort, no throw).
|
|
3735
4068
|
*/
|
|
3736
4069
|
async function _PerpsController_performMarketDataPreload() {
|
|
3737
4070
|
if (__classPrivateFieldGet(this, _PerpsController_isPreloading, "f")) {
|
|
4071
|
+
__classPrivateFieldSet(this, _PerpsController_marketPreloadQueued, true, "f");
|
|
3738
4072
|
return;
|
|
3739
4073
|
}
|
|
3740
4074
|
// Skip preloading during provider/network reinitialisation.
|
|
@@ -3749,9 +4083,16 @@ async function _PerpsController_performMarketDataPreload() {
|
|
|
3749
4083
|
? this.state.activeProvider // includes 'aggregated'
|
|
3750
4084
|
: 'hyperliquid';
|
|
3751
4085
|
const cacheKey = (0, perpsConfig_js_1.buildProviderCacheKey)(actualProviderId, this.state.isTestnet);
|
|
4086
|
+
const preloadContext = {
|
|
4087
|
+
activeProvider: this.state.activeProvider,
|
|
4088
|
+
isTestnet: this.state.isTestnet,
|
|
4089
|
+
hip3ConfigVersion: this.state.hip3ConfigVersion,
|
|
4090
|
+
};
|
|
4091
|
+
const staticSnapshotDexes = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getStaticSnapshotDexes).call(this);
|
|
3752
4092
|
const now = Date.now();
|
|
3753
4093
|
const existingEntry = this.state.cachedMarketDataByProvider[cacheKey];
|
|
3754
4094
|
if (existingEntry &&
|
|
4095
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_isMarketCacheEntryCurrent).call(this, actualProviderId, existingEntry) &&
|
|
3755
4096
|
now - existingEntry.timestamp < __classPrivateFieldGet(_a, _a, "f", _PerpsController_preloadGuardMs)) {
|
|
3756
4097
|
return;
|
|
3757
4098
|
}
|
|
@@ -3776,8 +4117,32 @@ async function _PerpsController_performMarketDataPreload() {
|
|
|
3776
4117
|
duration_ms: Math.round(performance.now() - preloadStart),
|
|
3777
4118
|
markets: data.length,
|
|
3778
4119
|
});
|
|
4120
|
+
if (this.state.activeProvider !== preloadContext.activeProvider ||
|
|
4121
|
+
this.state.isTestnet !== preloadContext.isTestnet ||
|
|
4122
|
+
this.state.hip3ConfigVersion !== preloadContext.hip3ConfigVersion) {
|
|
4123
|
+
traceData = {
|
|
4124
|
+
success: false,
|
|
4125
|
+
error: 'Global snapshot preload context changed',
|
|
4126
|
+
};
|
|
4127
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Discarding stale global snapshot preload');
|
|
4128
|
+
return;
|
|
4129
|
+
}
|
|
3779
4130
|
// Store under per-provider key(s)
|
|
3780
4131
|
const ts = Date.now();
|
|
4132
|
+
const sourceExpiries = data.flatMap((market) => market.dataSource === 'terminal-global-snapshot-mark' &&
|
|
4133
|
+
typeof market.sourceExpiresAt === 'number'
|
|
4134
|
+
? [market.sourceExpiresAt]
|
|
4135
|
+
: []);
|
|
4136
|
+
const sourceExpiresAt = data.length > 0 && sourceExpiries.length === data.length
|
|
4137
|
+
? Math.min(...sourceExpiries)
|
|
4138
|
+
: undefined;
|
|
4139
|
+
const snapshotCacheIdentity = sourceExpiresAt !== undefined && staticSnapshotDexes
|
|
4140
|
+
? {
|
|
4141
|
+
sourceExpiresAt,
|
|
4142
|
+
hip3ConfigVersion: preloadContext.hip3ConfigVersion,
|
|
4143
|
+
dexes: staticSnapshotDexes,
|
|
4144
|
+
}
|
|
4145
|
+
: {};
|
|
3781
4146
|
const marketDiskEntries = [];
|
|
3782
4147
|
if (this.state.activeProvider === 'aggregated' &&
|
|
3783
4148
|
this.activeProviderInstance) {
|
|
@@ -3824,6 +4189,7 @@ async function _PerpsController_performMarketDataPreload() {
|
|
|
3824
4189
|
state.cachedMarketDataByProvider[cacheKey] = {
|
|
3825
4190
|
data,
|
|
3826
4191
|
timestamp: ts,
|
|
4192
|
+
...snapshotCacheIdentity,
|
|
3827
4193
|
};
|
|
3828
4194
|
});
|
|
3829
4195
|
}
|
|
@@ -3833,10 +4199,6 @@ async function _PerpsController_performMarketDataPreload() {
|
|
|
3833
4199
|
});
|
|
3834
4200
|
traceData = { success: true, marketCount: data.length };
|
|
3835
4201
|
__classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.tracer.setMeasurement(performanceMetrics_js_1.PerpsMeasurementName.PerpsMarketDataPreload, performance.now() - preloadStart, 'millisecond');
|
|
3836
|
-
// Also preload user data (fire-and-forget, non-blocking)
|
|
3837
|
-
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
|
|
3838
|
-
/* fire-and-forget */
|
|
3839
|
-
});
|
|
3840
4202
|
}
|
|
3841
4203
|
catch (error) {
|
|
3842
4204
|
traceData = {
|
|
@@ -3855,6 +4217,12 @@ async function _PerpsController_performMarketDataPreload() {
|
|
|
3855
4217
|
data: traceData,
|
|
3856
4218
|
});
|
|
3857
4219
|
__classPrivateFieldSet(this, _PerpsController_isPreloading, false, "f");
|
|
4220
|
+
if (__classPrivateFieldGet(this, _PerpsController_marketPreloadQueued, "f") && __classPrivateFieldGet(this, _PerpsController_preloadTimer, "f")) {
|
|
4221
|
+
__classPrivateFieldSet(this, _PerpsController_marketPreloadQueued, false, "f");
|
|
4222
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performMarketDataPreload).call(this).catch(() => {
|
|
4223
|
+
// Background preload is best-effort.
|
|
4224
|
+
});
|
|
4225
|
+
}
|
|
3858
4226
|
}
|
|
3859
4227
|
}, _PerpsController_performUserDataPreload =
|
|
3860
4228
|
/**
|
|
@@ -3863,6 +4231,10 @@ async function _PerpsController_performMarketDataPreload() {
|
|
|
3863
4231
|
*/
|
|
3864
4232
|
async function _PerpsController_performUserDataPreload() {
|
|
3865
4233
|
if (__classPrivateFieldGet(this, _PerpsController_isPreloadingUserData, "f")) {
|
|
4234
|
+
__classPrivateFieldSet(this, _PerpsController_userPreloadQueued, true, "f");
|
|
4235
|
+
return;
|
|
4236
|
+
}
|
|
4237
|
+
if (__classPrivateFieldGet(this, _PerpsController_isReinitializing, "f")) {
|
|
3866
4238
|
return;
|
|
3867
4239
|
}
|
|
3868
4240
|
// Get current user address
|
|
@@ -3871,21 +4243,54 @@ async function _PerpsController_performUserDataPreload() {
|
|
|
3871
4243
|
return;
|
|
3872
4244
|
}
|
|
3873
4245
|
const userAddress = evmAccount.address;
|
|
4246
|
+
const { activeProvider, isTestnet, hip3ConfigVersion } = this.state;
|
|
4247
|
+
const { activeProviderInstance } = this;
|
|
4248
|
+
const hyperliquidDexes = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getStaticSnapshotDexes).call(this);
|
|
4249
|
+
const isCurrent = () => {
|
|
4250
|
+
let currentAddress;
|
|
4251
|
+
try {
|
|
4252
|
+
currentAddress = (0, accountUtils_js_1.getSelectedEvmAccountFromMessenger)(this.messenger)?.address;
|
|
4253
|
+
}
|
|
4254
|
+
catch {
|
|
4255
|
+
return false;
|
|
4256
|
+
}
|
|
4257
|
+
return (this.state.activeProvider === activeProvider &&
|
|
4258
|
+
this.activeProviderInstance === activeProviderInstance &&
|
|
4259
|
+
this.state.isTestnet === isTestnet &&
|
|
4260
|
+
this.state.hip3ConfigVersion === hip3ConfigVersion &&
|
|
4261
|
+
currentAddress?.toLowerCase() === userAddress.toLowerCase());
|
|
4262
|
+
};
|
|
3874
4263
|
// Determine actual provider (same logic as market preload)
|
|
3875
|
-
const actualProviderId =
|
|
3876
|
-
?
|
|
4264
|
+
const actualProviderId = activeProviderInstance
|
|
4265
|
+
? activeProvider // includes 'aggregated'
|
|
3877
4266
|
: 'hyperliquid';
|
|
3878
|
-
const
|
|
4267
|
+
const providerNetworkKey = (0, perpsConfig_js_1.buildProviderCacheKey)(actualProviderId, isTestnet);
|
|
3879
4268
|
// Skip if cache is fresh and for same account
|
|
3880
4269
|
const now = Date.now();
|
|
3881
|
-
const existingEntry = this.state.cachedUserDataByProvider[
|
|
3882
|
-
|
|
4270
|
+
const existingEntry = this.state.cachedUserDataByProvider[providerNetworkKey];
|
|
4271
|
+
const hasMatchingCache = existingEntry !== undefined &&
|
|
4272
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_isUserCacheIdentityCurrent).call(this, actualProviderId, existingEntry, userAddress);
|
|
4273
|
+
const cacheAgeMs = existingEntry ? now - existingEntry.timestamp : null;
|
|
4274
|
+
const websocketState = this.getWebSocketConnectionState();
|
|
4275
|
+
let selectedEntryKey = null;
|
|
4276
|
+
if (this.state.cachedUserDataByProvider[providerNetworkKey]) {
|
|
4277
|
+
selectedEntryKey = providerNetworkKey;
|
|
4278
|
+
}
|
|
4279
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: user cache preload decision', {
|
|
4280
|
+
requestedKey: providerNetworkKey,
|
|
4281
|
+
selectedEntryKey,
|
|
4282
|
+
availableKeys: Object.keys(this.state.cachedUserDataByProvider).sort(),
|
|
4283
|
+
hasMatchingCache,
|
|
4284
|
+
cacheAgeMs,
|
|
4285
|
+
websocketState,
|
|
4286
|
+
});
|
|
4287
|
+
if (existingEntry &&
|
|
4288
|
+
hasMatchingCache &&
|
|
3883
4289
|
now - existingEntry.timestamp < __classPrivateFieldGet(_a, _a, "f", _PerpsController_preloadGuardMs)) {
|
|
3884
4290
|
return;
|
|
3885
4291
|
}
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Skipping user data preload — WebSocket connected');
|
|
4292
|
+
if (hasMatchingCache &&
|
|
4293
|
+
this.getWebSocketConnectionState() === index_js_1.WebSocketConnectionState.Connected) {
|
|
3889
4294
|
return;
|
|
3890
4295
|
}
|
|
3891
4296
|
__classPrivateFieldSet(this, _PerpsController_isPreloadingUserData, true, "f");
|
|
@@ -3898,21 +4303,38 @@ async function _PerpsController_performUserDataPreload() {
|
|
|
3898
4303
|
id: traceId,
|
|
3899
4304
|
op: index_js_1.PerpsTraceOperations.Operation,
|
|
3900
4305
|
tags: {
|
|
3901
|
-
provider:
|
|
3902
|
-
isTestnet
|
|
4306
|
+
provider: activeProvider,
|
|
4307
|
+
isTestnet,
|
|
3903
4308
|
},
|
|
3904
4309
|
data: { userAddress },
|
|
3905
4310
|
});
|
|
3906
4311
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Fetching user data in background', {
|
|
3907
4312
|
userAddress,
|
|
3908
4313
|
});
|
|
4314
|
+
if (activeProvider === 'hyperliquid') {
|
|
4315
|
+
const snapshot = await this.getUserDataSnapshot();
|
|
4316
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: User data preloaded', {
|
|
4317
|
+
positionCount: snapshot.positions.length,
|
|
4318
|
+
orderCount: snapshot.orders.length,
|
|
4319
|
+
totalBalance: snapshot.accountState.totalBalance,
|
|
4320
|
+
});
|
|
4321
|
+
traceData = {
|
|
4322
|
+
success: true,
|
|
4323
|
+
positionCount: snapshot.positions.length,
|
|
4324
|
+
orderCount: snapshot.orders.length,
|
|
4325
|
+
};
|
|
4326
|
+
__classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.tracer.setMeasurement(performanceMetrics_js_1.PerpsMeasurementName.PerpsUserDataPreload, performance.now() - preloadStart, 'millisecond');
|
|
4327
|
+
return;
|
|
4328
|
+
}
|
|
3909
4329
|
const [positions, orders, accountState] = await Promise.all([
|
|
3910
4330
|
this.getPositions({ standalone: true, userAddress }),
|
|
3911
4331
|
this.getOpenOrders({ standalone: true, userAddress }),
|
|
3912
4332
|
this.getAccountState({ standalone: true, userAddress }),
|
|
3913
4333
|
]);
|
|
3914
|
-
if (
|
|
3915
|
-
|
|
4334
|
+
if (!isCurrent()) {
|
|
4335
|
+
throw new Error('User data preload context changed');
|
|
4336
|
+
}
|
|
4337
|
+
if (activeProvider === 'aggregated' && activeProviderInstance) {
|
|
3916
4338
|
// Split by providerId and write one cache entry per provider key
|
|
3917
4339
|
// (mirrors the market-data preload pattern at ~line 2976)
|
|
3918
4340
|
const ts = Date.now();
|
|
@@ -3934,26 +4356,22 @@ async function _PerpsController_performUserDataPreload() {
|
|
|
3934
4356
|
}
|
|
3935
4357
|
// AccountState — assign to its provider bucket
|
|
3936
4358
|
ensureBucket(accountState.providerId ?? fallbackProviderId).accountState = accountState;
|
|
3937
|
-
const diskEntries = [];
|
|
3938
4359
|
this.update((state) => {
|
|
3939
4360
|
for (const [pid, data] of byProvider) {
|
|
3940
|
-
const key = (0, perpsConfig_js_1.buildProviderCacheKey)(pid,
|
|
3941
|
-
diskEntries.push({
|
|
3942
|
-
providerNetworkKey: key,
|
|
3943
|
-
address: userAddress,
|
|
3944
|
-
positions: data.positions,
|
|
3945
|
-
orders: data.orders,
|
|
3946
|
-
accountState: data.accountState,
|
|
3947
|
-
timestamp: ts,
|
|
3948
|
-
});
|
|
4361
|
+
const key = (0, perpsConfig_js_1.buildProviderCacheKey)(pid, isTestnet);
|
|
3949
4362
|
state.cachedUserDataByProvider[key] = {
|
|
3950
4363
|
...data,
|
|
3951
4364
|
timestamp: ts,
|
|
3952
4365
|
address: userAddress,
|
|
4366
|
+
...(pid === 'hyperliquid' &&
|
|
4367
|
+
hyperliquidDexes && {
|
|
4368
|
+
hip3ConfigVersion,
|
|
4369
|
+
dexes: hyperliquidDexes,
|
|
4370
|
+
}),
|
|
3953
4371
|
};
|
|
3954
4372
|
}
|
|
3955
4373
|
// Write aggregated sentinel so the staleness guard sees it
|
|
3956
|
-
state.cachedUserDataByProvider[
|
|
4374
|
+
state.cachedUserDataByProvider[providerNetworkKey] = {
|
|
3957
4375
|
positions: [],
|
|
3958
4376
|
orders: [],
|
|
3959
4377
|
accountState: null,
|
|
@@ -3961,30 +4379,26 @@ async function _PerpsController_performUserDataPreload() {
|
|
|
3961
4379
|
address: userAddress,
|
|
3962
4380
|
};
|
|
3963
4381
|
});
|
|
3964
|
-
|
|
4382
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_persistUserCacheToDisk).call(this);
|
|
3965
4383
|
}
|
|
3966
4384
|
else {
|
|
3967
4385
|
// Single provider — store directly under its key
|
|
3968
4386
|
const ts = Date.now();
|
|
3969
4387
|
this.update((state) => {
|
|
3970
|
-
state.cachedUserDataByProvider[
|
|
4388
|
+
state.cachedUserDataByProvider[providerNetworkKey] = {
|
|
3971
4389
|
positions,
|
|
3972
4390
|
orders,
|
|
3973
4391
|
accountState,
|
|
3974
4392
|
timestamp: ts,
|
|
3975
4393
|
address: userAddress,
|
|
4394
|
+
...(actualProviderId === 'hyperliquid' &&
|
|
4395
|
+
hyperliquidDexes && {
|
|
4396
|
+
hip3ConfigVersion,
|
|
4397
|
+
dexes: hyperliquidDexes,
|
|
4398
|
+
}),
|
|
3976
4399
|
};
|
|
3977
4400
|
});
|
|
3978
|
-
|
|
3979
|
-
{
|
|
3980
|
-
providerNetworkKey: userCacheKey,
|
|
3981
|
-
address: userAddress,
|
|
3982
|
-
positions,
|
|
3983
|
-
orders,
|
|
3984
|
-
accountState,
|
|
3985
|
-
timestamp: ts,
|
|
3986
|
-
},
|
|
3987
|
-
]);
|
|
4401
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_persistUserCacheToDisk).call(this);
|
|
3988
4402
|
}
|
|
3989
4403
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: User data preloaded', {
|
|
3990
4404
|
positionCount: positions.length,
|
|
@@ -4015,6 +4429,12 @@ async function _PerpsController_performUserDataPreload() {
|
|
|
4015
4429
|
data: traceData,
|
|
4016
4430
|
});
|
|
4017
4431
|
__classPrivateFieldSet(this, _PerpsController_isPreloadingUserData, false, "f");
|
|
4432
|
+
if (__classPrivateFieldGet(this, _PerpsController_userPreloadQueued, "f") && __classPrivateFieldGet(this, _PerpsController_preloadTimer, "f")) {
|
|
4433
|
+
__classPrivateFieldSet(this, _PerpsController_userPreloadQueued, false, "f");
|
|
4434
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
|
|
4435
|
+
// Background preload is best-effort.
|
|
4436
|
+
});
|
|
4437
|
+
}
|
|
4018
4438
|
}
|
|
4019
4439
|
}, _PerpsController_persistWatchlistToRemote =
|
|
4020
4440
|
/**
|