@metamask-previews/perps-controller 11.0.0-preview-9efd0b754 → 12.0.0-preview-4e64b66e8
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 +30 -1
- package/dist/PerpsController-method-action-types.cjs.map +1 -1
- package/dist/PerpsController-method-action-types.d.cts +36 -1
- package/dist/PerpsController-method-action-types.d.cts.map +1 -1
- package/dist/PerpsController-method-action-types.d.mts +36 -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 +600 -119
- package/dist/PerpsController.cjs.map +1 -1
- package/dist/PerpsController.d.cts +35 -4
- package/dist/PerpsController.d.cts.map +1 -1
- package/dist/PerpsController.d.mts +35 -4
- package/dist/PerpsController.d.mts.map +1 -1
- package/dist/PerpsController.mjs +603 -122
- 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 +19 -2
- package/dist/constants/perpsConfig.cjs.map +1 -1
- package/dist/constants/perpsConfig.d.cts +39 -7
- package/dist/constants/perpsConfig.d.cts.map +1 -1
- package/dist/constants/perpsConfig.d.mts +39 -7
- package/dist/constants/perpsConfig.d.mts.map +1 -1
- package/dist/constants/perpsConfig.mjs +18 -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/AggregatedPerpsProvider.cjs +16 -0
- package/dist/providers/AggregatedPerpsProvider.cjs.map +1 -1
- package/dist/providers/AggregatedPerpsProvider.d.cts +3 -1
- package/dist/providers/AggregatedPerpsProvider.d.cts.map +1 -1
- package/dist/providers/AggregatedPerpsProvider.d.mts +3 -1
- package/dist/providers/AggregatedPerpsProvider.d.mts.map +1 -1
- package/dist/providers/AggregatedPerpsProvider.mjs +16 -0
- package/dist/providers/AggregatedPerpsProvider.mjs.map +1 -1
- package/dist/providers/HyperLiquidProvider.cjs +325 -59
- package/dist/providers/HyperLiquidProvider.cjs.map +1 -1
- package/dist/providers/HyperLiquidProvider.d.cts +27 -1
- package/dist/providers/HyperLiquidProvider.d.cts.map +1 -1
- package/dist/providers/HyperLiquidProvider.d.mts +27 -1
- package/dist/providers/HyperLiquidProvider.d.mts.map +1 -1
- package/dist/providers/HyperLiquidProvider.mjs +326 -60
- package/dist/providers/HyperLiquidProvider.mjs.map +1 -1
- package/dist/services/HyperLiquidClientService.cjs +74 -25
- 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 +74 -25
- package/dist/services/HyperLiquidClientService.mjs.map +1 -1
- package/dist/services/HyperLiquidSubscriptionService.cjs +16 -5
- 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 +16 -5
- package/dist/services/HyperLiquidSubscriptionService.mjs.map +1 -1
- package/dist/services/MarketDataService.cjs +49 -5
- 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 +49 -5
- package/dist/services/MarketDataService.mjs.map +1 -1
- package/dist/services/RewardsIntegrationService.cjs +330 -68
- package/dist/services/RewardsIntegrationService.cjs.map +1 -1
- package/dist/services/RewardsIntegrationService.d.cts +61 -5
- package/dist/services/RewardsIntegrationService.d.cts.map +1 -1
- package/dist/services/RewardsIntegrationService.d.mts +61 -5
- package/dist/services/RewardsIntegrationService.d.mts.map +1 -1
- package/dist/services/RewardsIntegrationService.mjs +330 -68
- package/dist/services/RewardsIntegrationService.mjs.map +1 -1
- package/dist/services/ServiceContext.cjs.map +1 -1
- package/dist/services/ServiceContext.d.cts +17 -1
- package/dist/services/ServiceContext.d.cts.map +1 -1
- package/dist/services/ServiceContext.d.mts +17 -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/services/TradingService.cjs +52 -28
- package/dist/services/TradingService.cjs.map +1 -1
- package/dist/services/TradingService.d.cts.map +1 -1
- package/dist/services/TradingService.d.mts.map +1 -1
- package/dist/services/TradingService.mjs +52 -28
- package/dist/services/TradingService.mjs.map +1 -1
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.cts +156 -7
- package/dist/types/index.d.cts.map +1 -1
- package/dist/types/index.d.mts +156 -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_awaitInitializationIfInProgress, _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_getActiveProviderWhenReady, _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.
|
|
@@ -384,6 +414,7 @@ const metadata = {
|
|
|
384
414
|
},
|
|
385
415
|
};
|
|
386
416
|
const MESSENGER_EXPOSED_METHODS = [
|
|
417
|
+
'approveSubscriptionBuilderFee',
|
|
387
418
|
'calculateFees',
|
|
388
419
|
'calculateLiquidationPrice',
|
|
389
420
|
'calculateMaintenanceMargin',
|
|
@@ -411,6 +442,7 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
411
442
|
'getBlockExplorerUrl',
|
|
412
443
|
'getCachedMarketDataForActiveProvider',
|
|
413
444
|
'getCachedUserDataForActiveProvider',
|
|
445
|
+
'getUserDataSnapshot',
|
|
414
446
|
'getCurrentNetwork',
|
|
415
447
|
'getFunding',
|
|
416
448
|
'getHistoricalPortfolio',
|
|
@@ -432,6 +464,7 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
432
464
|
'getWithdrawalProgress',
|
|
433
465
|
'getWithdrawalRoutes',
|
|
434
466
|
'init',
|
|
467
|
+
'invalidateSubscriptionBenefits',
|
|
435
468
|
'isCurrentlyReinitializing',
|
|
436
469
|
'isFirstTimeUserOnCurrentNetwork',
|
|
437
470
|
'isWatchlistMarket',
|
|
@@ -543,6 +576,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
543
576
|
_PerpsController_handlersRegistered.set(this, false);
|
|
544
577
|
_PerpsController_standaloneProviderIsTestnet.set(this, null);
|
|
545
578
|
_PerpsController_standaloneProviderHip3Version.set(this, null);
|
|
579
|
+
_PerpsController_standaloneProviderOperations.set(this, new Map());
|
|
546
580
|
_PerpsController_eligibilityCheckDeferred.set(this, void 0);
|
|
547
581
|
/**
|
|
548
582
|
* Serial promise queue for all AUS watchlist operations (hydration and
|
|
@@ -558,6 +592,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
558
592
|
* a failed operation does not stall subsequent ones.
|
|
559
593
|
*/
|
|
560
594
|
_PerpsController_ausQueue.set(this, Promise.resolve());
|
|
595
|
+
_PerpsController_userDiskWrite.set(this, Promise.resolve());
|
|
561
596
|
// Store options for dependency injection (allows core package to inject platform-specific services)
|
|
562
597
|
_PerpsController_options.set(this, void 0);
|
|
563
598
|
// Service instances (instantiated with platform dependencies)
|
|
@@ -571,7 +606,10 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
571
606
|
_PerpsController_rewardsIntegrationService.set(this, void 0);
|
|
572
607
|
_PerpsController_preloadTimer.set(this, null);
|
|
573
608
|
_PerpsController_isPreloading.set(this, false);
|
|
609
|
+
_PerpsController_marketPreloadQueued.set(this, false);
|
|
574
610
|
_PerpsController_isPreloadingUserData.set(this, false);
|
|
611
|
+
_PerpsController_userPreloadQueued.set(this, false);
|
|
612
|
+
_PerpsController_userSnapshotRequests.set(this, new Map());
|
|
575
613
|
_PerpsController_preloadStateUnsubscribe.set(this, null);
|
|
576
614
|
_PerpsController_accountChangeUnsubscribe.set(this, null);
|
|
577
615
|
_PerpsController_previousIsTestnet.set(this, null);
|
|
@@ -590,7 +628,9 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
590
628
|
__classPrivateFieldSet(this, _PerpsController_marketDataService, new MarketDataService_js_1.MarketDataService({
|
|
591
629
|
...infrastructure,
|
|
592
630
|
terminalMarketService: infrastructure.terminalMarketService ??
|
|
593
|
-
(infrastructure.
|
|
631
|
+
(infrastructure.terminalApi?.marketDataUrl ||
|
|
632
|
+
infrastructure.terminalApiUrl ||
|
|
633
|
+
infrastructure.terminalApi?.globalSnapshotUrl
|
|
594
634
|
? new TerminalMarketService_js_1.TerminalMarketService(infrastructure)
|
|
595
635
|
: undefined),
|
|
596
636
|
}), "f");
|
|
@@ -657,24 +697,20 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
657
697
|
if (activeProvider === 'aggregated') {
|
|
658
698
|
// Assemble from all registered provider entries
|
|
659
699
|
const assembled = [];
|
|
660
|
-
let oldestTimestamp = Infinity;
|
|
661
700
|
for (const providerId of __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getAggregatedCacheProviderIds).call(this, Object.keys(cache))) {
|
|
662
701
|
const key = (0, perpsConfig_js_1.buildProviderCacheKey)(providerId, this.state.isTestnet);
|
|
663
702
|
const entry = cache[key];
|
|
664
703
|
if (!entry || entry.data.length === 0) {
|
|
665
704
|
continue;
|
|
666
705
|
}
|
|
667
|
-
|
|
668
|
-
|
|
706
|
+
if (!__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_isMarketCacheEntryCurrent).call(this, providerId, entry, options)) {
|
|
707
|
+
continue;
|
|
708
|
+
}
|
|
709
|
+
assembled.push(...(0, marketUtils_js_1.clonePerpsMarketData)(entry.data));
|
|
669
710
|
}
|
|
670
711
|
if (assembled.length === 0) {
|
|
671
712
|
return null;
|
|
672
713
|
}
|
|
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
714
|
return assembled;
|
|
679
715
|
}
|
|
680
716
|
// Single provider mode
|
|
@@ -683,11 +719,10 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
683
719
|
if (!entry || entry.data.length === 0) {
|
|
684
720
|
return null;
|
|
685
721
|
}
|
|
686
|
-
if (!options
|
|
687
|
-
Date.now() - entry.timestamp > __classPrivateFieldGet(_a, _a, "f", _PerpsController_preloadGuardMs) * 10) {
|
|
722
|
+
if (!__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_isMarketCacheEntryCurrent).call(this, activeProvider, entry, options)) {
|
|
688
723
|
return null;
|
|
689
724
|
}
|
|
690
|
-
return entry.data;
|
|
725
|
+
return (0, marketUtils_js_1.clonePerpsMarketData)(entry.data);
|
|
691
726
|
}
|
|
692
727
|
/**
|
|
693
728
|
* Read cached user data for the currently active provider (or aggregated).
|
|
@@ -711,18 +746,21 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
711
746
|
currentAddress = evmAccount?.address ?? null;
|
|
712
747
|
}
|
|
713
748
|
catch {
|
|
714
|
-
//
|
|
749
|
+
// Account identity is required before account-scoped data can be trusted.
|
|
715
750
|
}
|
|
751
|
+
if (!currentAddress) {
|
|
752
|
+
return null;
|
|
753
|
+
}
|
|
754
|
+
const selectedAddress = currentAddress;
|
|
716
755
|
const skipTTL = options?.skipTTL ?? false;
|
|
717
|
-
const isValidEntry = (entry) => {
|
|
756
|
+
const isValidEntry = (providerId, entry) => {
|
|
718
757
|
if (!entry) {
|
|
719
758
|
return false;
|
|
720
759
|
}
|
|
721
760
|
if (!skipTTL && Date.now() - entry.timestamp >= staleCutoff) {
|
|
722
761
|
return false;
|
|
723
762
|
}
|
|
724
|
-
if (
|
|
725
|
-
entry.address.toLowerCase() !== currentAddress.toLowerCase()) {
|
|
763
|
+
if (!__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_isUserCacheIdentityCurrent).call(this, providerId, entry, selectedAddress)) {
|
|
726
764
|
return false;
|
|
727
765
|
}
|
|
728
766
|
return true;
|
|
@@ -734,9 +772,9 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
734
772
|
let defaultAccountState = null;
|
|
735
773
|
let hasValidEntry = false;
|
|
736
774
|
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)) {
|
|
775
|
+
const providerNetworkKey = (0, perpsConfig_js_1.buildProviderCacheKey)(providerId, this.state.isTestnet);
|
|
776
|
+
const entry = cache[providerNetworkKey];
|
|
777
|
+
if (!isValidEntry(providerId, entry)) {
|
|
740
778
|
continue;
|
|
741
779
|
}
|
|
742
780
|
hasValidEntry = true;
|
|
@@ -757,9 +795,9 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
757
795
|
};
|
|
758
796
|
}
|
|
759
797
|
// Single provider mode
|
|
760
|
-
const
|
|
761
|
-
const entry = cache[
|
|
762
|
-
if (!entry || !isValidEntry(entry)) {
|
|
798
|
+
const providerNetworkKey = (0, perpsConfig_js_1.buildProviderCacheKey)(activeProvider, this.state.isTestnet);
|
|
799
|
+
const entry = cache[providerNetworkKey];
|
|
800
|
+
if (!entry || !isValidEntry(activeProvider, entry)) {
|
|
763
801
|
return null;
|
|
764
802
|
}
|
|
765
803
|
return {
|
|
@@ -768,6 +806,82 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
768
806
|
accountState: entry.accountState,
|
|
769
807
|
};
|
|
770
808
|
}
|
|
809
|
+
/**
|
|
810
|
+
* Fetch, validate, and atomically cache a complete user-data snapshot.
|
|
811
|
+
* This remains callable after mount so consumers can seed their live channel
|
|
812
|
+
* from one coherent positions/orders/account result.
|
|
813
|
+
*
|
|
814
|
+
* @returns The accepted user-data snapshot.
|
|
815
|
+
*/
|
|
816
|
+
async getUserDataSnapshot() {
|
|
817
|
+
const evmAccount = (0, accountUtils_js_1.getSelectedEvmAccountFromMessenger)(this.messenger);
|
|
818
|
+
if (!evmAccount?.address) {
|
|
819
|
+
throw new Error('Cannot fetch user data snapshot without an EVM account');
|
|
820
|
+
}
|
|
821
|
+
if (this.state.activeProvider !== 'hyperliquid') {
|
|
822
|
+
throw new Error('User data snapshots require Hyperliquid provider mode');
|
|
823
|
+
}
|
|
824
|
+
const capturedActiveProvider = this.activeProviderInstance;
|
|
825
|
+
const standaloneProvider = capturedActiveProvider
|
|
826
|
+
? null
|
|
827
|
+
: __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getOrCreateStandaloneProvider).call(this);
|
|
828
|
+
const provider = capturedActiveProvider ?? standaloneProvider;
|
|
829
|
+
if (!provider) {
|
|
830
|
+
throw new Error('Cannot create standalone Hyperliquid provider');
|
|
831
|
+
}
|
|
832
|
+
const { address } = evmAccount;
|
|
833
|
+
const { isTestnet, hip3ConfigVersion } = this.state;
|
|
834
|
+
const network = isTestnet ? 'testnet' : 'mainnet';
|
|
835
|
+
const expectedDexes = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getStaticSnapshotDexes).call(this);
|
|
836
|
+
if (!expectedDexes) {
|
|
837
|
+
throw new Error('User data snapshot DEX identity is not static');
|
|
838
|
+
}
|
|
839
|
+
const isCurrent = () => {
|
|
840
|
+
let currentAddress;
|
|
841
|
+
try {
|
|
842
|
+
currentAddress = (0, accountUtils_js_1.getSelectedEvmAccountFromMessenger)(this.messenger)?.address;
|
|
843
|
+
}
|
|
844
|
+
catch {
|
|
845
|
+
return false;
|
|
846
|
+
}
|
|
847
|
+
return (this.state.activeProvider === 'hyperliquid' &&
|
|
848
|
+
(!capturedActiveProvider ||
|
|
849
|
+
this.activeProviderInstance === capturedActiveProvider) &&
|
|
850
|
+
this.state.isTestnet === isTestnet &&
|
|
851
|
+
this.state.hip3ConfigVersion === hip3ConfigVersion &&
|
|
852
|
+
currentAddress?.toLowerCase() === address.toLowerCase());
|
|
853
|
+
};
|
|
854
|
+
const context = {
|
|
855
|
+
provider,
|
|
856
|
+
standaloneProvider,
|
|
857
|
+
address,
|
|
858
|
+
isTestnet,
|
|
859
|
+
hip3ConfigVersion,
|
|
860
|
+
expectedDexes,
|
|
861
|
+
isCurrent,
|
|
862
|
+
};
|
|
863
|
+
const requestKey = [
|
|
864
|
+
'hyperliquid',
|
|
865
|
+
network,
|
|
866
|
+
address.toLowerCase(),
|
|
867
|
+
hip3ConfigVersion,
|
|
868
|
+
...expectedDexes,
|
|
869
|
+
].join('|');
|
|
870
|
+
const existingRequest = __classPrivateFieldGet(this, _PerpsController_userSnapshotRequests, "f").get(requestKey);
|
|
871
|
+
if (existingRequest?.provider === provider) {
|
|
872
|
+
return existingRequest.promise;
|
|
873
|
+
}
|
|
874
|
+
const request = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_fetchAndCacheUserDataSnapshot).call(this, context);
|
|
875
|
+
__classPrivateFieldGet(this, _PerpsController_userSnapshotRequests, "f").set(requestKey, { provider, promise: request });
|
|
876
|
+
try {
|
|
877
|
+
return await request;
|
|
878
|
+
}
|
|
879
|
+
finally {
|
|
880
|
+
if (__classPrivateFieldGet(this, _PerpsController_userSnapshotRequests, "f").get(requestKey)?.promise === request) {
|
|
881
|
+
__classPrivateFieldGet(this, _PerpsController_userSnapshotRequests, "f").delete(requestKey);
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
}
|
|
771
885
|
/**
|
|
772
886
|
* Test-observable accessor for whether a standalone provider is cached.
|
|
773
887
|
*
|
|
@@ -919,14 +1033,11 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
919
1033
|
// Check if not initialized
|
|
920
1034
|
if (this.state.initializationState !== InitializationState.Initialized ||
|
|
921
1035
|
!this.isInitialized) {
|
|
922
|
-
const errorMessage = this.state.initializationState === InitializationState.Failed
|
|
923
|
-
? `${perpsErrorCodes_js_1.PERPS_ERROR_CODES.CLIENT_NOT_INITIALIZED}: ${this.state.initializationError ?? 'Initialization failed'}`
|
|
924
|
-
: perpsErrorCodes_js_1.PERPS_ERROR_CODES.CLIENT_NOT_INITIALIZED;
|
|
925
1036
|
this.update((state) => {
|
|
926
|
-
state.lastError =
|
|
1037
|
+
state.lastError = perpsErrorCodes_js_1.PERPS_ERROR_CODES.CLIENT_NOT_INITIALIZED;
|
|
927
1038
|
state.lastUpdateTimestamp = Date.now();
|
|
928
1039
|
});
|
|
929
|
-
throw new Error(
|
|
1040
|
+
throw new Error(perpsErrorCodes_js_1.PERPS_ERROR_CODES.CLIENT_NOT_INITIALIZED);
|
|
930
1041
|
}
|
|
931
1042
|
// Return the active provider instance (set during initialization based on providerMode)
|
|
932
1043
|
if (!this.activeProviderInstance) {
|
|
@@ -966,7 +1077,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
966
1077
|
* @returns The order result with order ID and status.
|
|
967
1078
|
*/
|
|
968
1079
|
async placeOrder(params) {
|
|
969
|
-
const provider = this.
|
|
1080
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getActiveProviderWhenReady).call(this);
|
|
970
1081
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_ensureTradingServiceDeps).call(this);
|
|
971
1082
|
return __classPrivateFieldGet(this, _PerpsController_tradingService, "f").placeOrder({
|
|
972
1083
|
provider,
|
|
@@ -985,7 +1096,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
985
1096
|
* @returns The updated order result with order ID and status.
|
|
986
1097
|
*/
|
|
987
1098
|
async editOrder(params) {
|
|
988
|
-
const provider = this.
|
|
1099
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getActiveProviderWhenReady).call(this);
|
|
989
1100
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_ensureTradingServiceDeps).call(this);
|
|
990
1101
|
return __classPrivateFieldGet(this, _PerpsController_tradingService, "f").editOrder({
|
|
991
1102
|
provider,
|
|
@@ -1000,7 +1111,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1000
1111
|
* @returns The cancellation result with status.
|
|
1001
1112
|
*/
|
|
1002
1113
|
async cancelOrder(params) {
|
|
1003
|
-
const provider = this.
|
|
1114
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getActiveProviderWhenReady).call(this);
|
|
1004
1115
|
return __classPrivateFieldGet(this, _PerpsController_tradingService, "f").cancelOrder({
|
|
1005
1116
|
provider,
|
|
1006
1117
|
params,
|
|
@@ -1015,7 +1126,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1015
1126
|
* @returns The batch cancellation results for each order.
|
|
1016
1127
|
*/
|
|
1017
1128
|
async cancelOrders(params) {
|
|
1018
|
-
const provider = this.
|
|
1129
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getActiveProviderWhenReady).call(this);
|
|
1019
1130
|
return __classPrivateFieldGet(this, _PerpsController_tradingService, "f").cancelOrders({
|
|
1020
1131
|
provider,
|
|
1021
1132
|
params,
|
|
@@ -1033,7 +1144,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1033
1144
|
* @returns The order result from the close position request.
|
|
1034
1145
|
*/
|
|
1035
1146
|
async closePosition(params) {
|
|
1036
|
-
const provider = this.
|
|
1147
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getActiveProviderWhenReady).call(this);
|
|
1037
1148
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_ensureTradingServiceDeps).call(this);
|
|
1038
1149
|
return __classPrivateFieldGet(this, _PerpsController_tradingService, "f").closePosition({
|
|
1039
1150
|
provider,
|
|
@@ -1052,7 +1163,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1052
1163
|
* @returns The batch close results for each position.
|
|
1053
1164
|
*/
|
|
1054
1165
|
async closePositions(params) {
|
|
1055
|
-
const provider = this.
|
|
1166
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getActiveProviderWhenReady).call(this);
|
|
1056
1167
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_ensureTradingServiceDeps).call(this);
|
|
1057
1168
|
return __classPrivateFieldGet(this, _PerpsController_tradingService, "f").closePositions({
|
|
1058
1169
|
provider,
|
|
@@ -1069,7 +1180,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1069
1180
|
* @returns The order result from the TP/SL update.
|
|
1070
1181
|
*/
|
|
1071
1182
|
async updatePositionTPSL(params) {
|
|
1072
|
-
const provider = this.
|
|
1183
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getActiveProviderWhenReady).call(this);
|
|
1073
1184
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_ensureTradingServiceDeps).call(this);
|
|
1074
1185
|
return __classPrivateFieldGet(this, _PerpsController_tradingService, "f").updatePositionTPSL({
|
|
1075
1186
|
provider,
|
|
@@ -1084,7 +1195,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1084
1195
|
* @returns The margin update result.
|
|
1085
1196
|
*/
|
|
1086
1197
|
async updateMargin(params) {
|
|
1087
|
-
const provider = this.
|
|
1198
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getActiveProviderWhenReady).call(this);
|
|
1088
1199
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_ensureTradingServiceDeps).call(this);
|
|
1089
1200
|
return __classPrivateFieldGet(this, _PerpsController_tradingService, "f").updateMargin({
|
|
1090
1201
|
provider,
|
|
@@ -1100,7 +1211,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1100
1211
|
* @returns The order result from the position flip.
|
|
1101
1212
|
*/
|
|
1102
1213
|
async flipPosition(params) {
|
|
1103
|
-
const provider = this.
|
|
1214
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getActiveProviderWhenReady).call(this);
|
|
1104
1215
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_ensureTradingServiceDeps).call(this);
|
|
1105
1216
|
return __classPrivateFieldGet(this, _PerpsController_tradingService, "f").flipPosition({
|
|
1106
1217
|
provider,
|
|
@@ -1122,10 +1233,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1122
1233
|
const { amount, placeOrder } = params;
|
|
1123
1234
|
let currentDepositId;
|
|
1124
1235
|
try {
|
|
1125
|
-
|
|
1126
|
-
// Don't set depositInProgress yet - wait until user confirms
|
|
1127
|
-
// Prepare deposit transaction using DepositService
|
|
1128
|
-
const provider = this.getActiveProvider();
|
|
1236
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getActiveProviderWhenReady).call(this);
|
|
1129
1237
|
const { transaction, assetChainId, currentDepositId: depositId, } = await __classPrivateFieldGet(this, _PerpsController_depositService, "f").prepareTransaction({ provider });
|
|
1130
1238
|
currentDepositId = depositId;
|
|
1131
1239
|
// Get current account address via messenger (outside of update() for proper typing)
|
|
@@ -1515,7 +1623,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1515
1623
|
* @returns WithdrawResult with withdrawal ID and tracking info
|
|
1516
1624
|
*/
|
|
1517
1625
|
async withdraw(params) {
|
|
1518
|
-
const provider = this.
|
|
1626
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getActiveProviderWhenReady).call(this);
|
|
1519
1627
|
return __classPrivateFieldGet(this, _PerpsController_accountService, "f").withdraw({
|
|
1520
1628
|
provider,
|
|
1521
1629
|
params,
|
|
@@ -1543,7 +1651,10 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1543
1651
|
// Fallback to cached standalone provider for pre-initialization discovery
|
|
1544
1652
|
// TODO: When adding new providers (MYX), consider a provider factory pattern
|
|
1545
1653
|
const provider = this.activeProviderInstance ?? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getOrCreateStandaloneProvider).call(this);
|
|
1546
|
-
|
|
1654
|
+
const operation = provider.getPositions(params);
|
|
1655
|
+
return provider === __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f")
|
|
1656
|
+
? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_trackStandaloneProviderOperation).call(this, provider, operation)
|
|
1657
|
+
: operation;
|
|
1547
1658
|
}
|
|
1548
1659
|
const provider = this.getActiveProvider();
|
|
1549
1660
|
return __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getPositions({
|
|
@@ -1604,7 +1715,10 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1604
1715
|
// For standalone mode, access provider directly without initialization check
|
|
1605
1716
|
if (params?.standalone && params.userAddress) {
|
|
1606
1717
|
const provider = this.activeProviderInstance ?? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getOrCreateStandaloneProvider).call(this);
|
|
1607
|
-
|
|
1718
|
+
const operation = provider.getOpenOrders(params);
|
|
1719
|
+
return provider === __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f")
|
|
1720
|
+
? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_trackStandaloneProviderOperation).call(this, provider, operation)
|
|
1721
|
+
: operation;
|
|
1608
1722
|
}
|
|
1609
1723
|
const provider = this.getActiveProvider();
|
|
1610
1724
|
return __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getOpenOrders({
|
|
@@ -1649,7 +1763,10 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1649
1763
|
// Use activeProviderInstance if available (respects provider abstraction)
|
|
1650
1764
|
// Fallback to cached standalone provider for pre-initialization discovery
|
|
1651
1765
|
const provider = this.activeProviderInstance ?? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getOrCreateStandaloneProvider).call(this);
|
|
1652
|
-
|
|
1766
|
+
const operation = provider.getAccountState(params);
|
|
1767
|
+
return provider === __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f")
|
|
1768
|
+
? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_trackStandaloneProviderOperation).call(this, provider, operation)
|
|
1769
|
+
: operation;
|
|
1653
1770
|
}
|
|
1654
1771
|
const provider = this.getActiveProvider();
|
|
1655
1772
|
return __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getAccountState({
|
|
@@ -1687,12 +1804,15 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1687
1804
|
const isMarketAllowed = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_buildMarketAllowedFilter).call(this);
|
|
1688
1805
|
if (params?.standalone) {
|
|
1689
1806
|
const provider = this.activeProviderInstance ?? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getOrCreateStandaloneProvider).call(this);
|
|
1690
|
-
|
|
1807
|
+
const operation = __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getMarkets({
|
|
1691
1808
|
provider,
|
|
1692
1809
|
params,
|
|
1693
1810
|
context: __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_createServiceContext).call(this, 'getMarkets'),
|
|
1694
1811
|
isMarketAllowed,
|
|
1695
1812
|
});
|
|
1813
|
+
return provider === __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f")
|
|
1814
|
+
? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_trackStandaloneProviderOperation).call(this, provider, operation)
|
|
1815
|
+
: operation;
|
|
1696
1816
|
}
|
|
1697
1817
|
const provider = this.getActiveProvider();
|
|
1698
1818
|
return __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getMarkets({
|
|
@@ -1718,19 +1838,26 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1718
1838
|
* @returns A promise that resolves to the market data.
|
|
1719
1839
|
*/
|
|
1720
1840
|
async getMarketDataWithPrices(params) {
|
|
1841
|
+
const globalSnapshot = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_buildGlobalSnapshotContext).call(this);
|
|
1842
|
+
const context = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_createServiceContext).call(this, 'getMarketDataWithPrices', {
|
|
1843
|
+
...(globalSnapshot && { globalSnapshot }),
|
|
1844
|
+
});
|
|
1721
1845
|
if (params?.standalone) {
|
|
1722
1846
|
const provider = this.activeProviderInstance ?? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getOrCreateStandaloneProvider).call(this);
|
|
1723
|
-
|
|
1847
|
+
const operation = __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getMarketDataWithPrices({
|
|
1724
1848
|
provider,
|
|
1725
1849
|
params,
|
|
1726
|
-
context
|
|
1850
|
+
context,
|
|
1727
1851
|
});
|
|
1852
|
+
return provider === __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f")
|
|
1853
|
+
? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_trackStandaloneProviderOperation).call(this, provider, operation)
|
|
1854
|
+
: operation;
|
|
1728
1855
|
}
|
|
1729
1856
|
const provider = this.getActiveProvider();
|
|
1730
1857
|
return __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getMarketDataWithPrices({
|
|
1731
1858
|
provider,
|
|
1732
1859
|
params,
|
|
1733
|
-
context
|
|
1860
|
+
context,
|
|
1734
1861
|
});
|
|
1735
1862
|
}
|
|
1736
1863
|
/**
|
|
@@ -1751,11 +1878,17 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1751
1878
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performMarketDataPreload).call(this).catch(() => {
|
|
1752
1879
|
/* fire-and-forget */
|
|
1753
1880
|
});
|
|
1881
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
|
|
1882
|
+
/* fire-and-forget */
|
|
1883
|
+
});
|
|
1754
1884
|
// Periodic refresh
|
|
1755
1885
|
__classPrivateFieldSet(this, _PerpsController_preloadTimer, setInterval(() => {
|
|
1756
1886
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performMarketDataPreload).call(this).catch(() => {
|
|
1757
1887
|
/* fire-and-forget */
|
|
1758
1888
|
});
|
|
1889
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
|
|
1890
|
+
/* fire-and-forget */
|
|
1891
|
+
});
|
|
1759
1892
|
}, __classPrivateFieldGet(_a, _a, "f", _PerpsController_preloadRefreshMs)), "f");
|
|
1760
1893
|
// Watch for isTestnet / hip3ConfigVersion changes
|
|
1761
1894
|
const handler = (_state, patches) => {
|
|
@@ -1784,36 +1917,29 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1784
1917
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performMarketDataPreload).call(this).catch(() => {
|
|
1785
1918
|
/* fire-and-forget */
|
|
1786
1919
|
});
|
|
1920
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
|
|
1921
|
+
/* fire-and-forget */
|
|
1922
|
+
});
|
|
1787
1923
|
}
|
|
1788
1924
|
};
|
|
1789
|
-
this.messenger.subscribe('PerpsController:
|
|
1925
|
+
this.messenger.subscribe('PerpsController:stateChanged', handler);
|
|
1790
1926
|
__classPrivateFieldSet(this, _PerpsController_preloadStateUnsubscribe, () => {
|
|
1791
|
-
this.messenger.unsubscribe('PerpsController:
|
|
1927
|
+
this.messenger.unsubscribe('PerpsController:stateChanged', handler);
|
|
1792
1928
|
}, "f");
|
|
1793
1929
|
// Watch for selected account changes and selected account group changes.
|
|
1794
1930
|
const accountChangeHandler = () => {
|
|
1795
1931
|
const evmAccount = (0, accountUtils_js_1.getSelectedEvmAccountFromMessenger)(this.messenger);
|
|
1796
1932
|
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(() => {
|
|
1933
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: account cache selection', {
|
|
1934
|
+
address: currentAddress?.toLowerCase() ?? null,
|
|
1935
|
+
availableKeys: Object.keys(this.state.cachedUserDataByProvider).sort(),
|
|
1936
|
+
});
|
|
1937
|
+
// The address guard makes the previous entry unreadable immediately;
|
|
1938
|
+
// refresh replaces it under the existing provider/network key.
|
|
1939
|
+
if (currentAddress) {
|
|
1940
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
|
|
1809
1941
|
/* fire-and-forget */
|
|
1810
1942
|
});
|
|
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
1943
|
}
|
|
1818
1944
|
};
|
|
1819
1945
|
this.messenger.subscribe('AccountsController:selectedAccountChange', accountChangeHandler);
|
|
@@ -1842,6 +1968,8 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1842
1968
|
}
|
|
1843
1969
|
__classPrivateFieldSet(this, _PerpsController_previousIsTestnet, null, "f");
|
|
1844
1970
|
__classPrivateFieldSet(this, _PerpsController_previousHip3ConfigVersion, null, "f");
|
|
1971
|
+
__classPrivateFieldSet(this, _PerpsController_marketPreloadQueued, false, "f");
|
|
1972
|
+
__classPrivateFieldSet(this, _PerpsController_userPreloadQueued, false, "f");
|
|
1845
1973
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_cleanupStandaloneProvider).call(this).catch(() => {
|
|
1846
1974
|
/* fire-and-forget to preserve sync signature */
|
|
1847
1975
|
});
|
|
@@ -2102,6 +2230,9 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2102
2230
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performMarketDataPreload).call(this).catch(() => {
|
|
2103
2231
|
/* fire-and-forget */
|
|
2104
2232
|
});
|
|
2233
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
|
|
2234
|
+
/* fire-and-forget */
|
|
2235
|
+
});
|
|
2105
2236
|
}
|
|
2106
2237
|
}
|
|
2107
2238
|
}
|
|
@@ -2211,6 +2342,9 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2211
2342
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performMarketDataPreload).call(this).catch(() => {
|
|
2212
2343
|
/* fire-and-forget */
|
|
2213
2344
|
});
|
|
2345
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
|
|
2346
|
+
/* fire-and-forget */
|
|
2347
|
+
});
|
|
2214
2348
|
}
|
|
2215
2349
|
}
|
|
2216
2350
|
}
|
|
@@ -2546,9 +2680,41 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2546
2680
|
*/
|
|
2547
2681
|
async calculateFees(params) {
|
|
2548
2682
|
const provider = this.getActiveProvider();
|
|
2549
|
-
|
|
2683
|
+
// Preview owns subscription hydration. The submit resolver remains a pure
|
|
2684
|
+
// cache read and can therefore never start a benefits request while an
|
|
2685
|
+
// order is being signed.
|
|
2686
|
+
await __classPrivateFieldGet(this, _PerpsController_rewardsIntegrationService, "f").refreshSubscriptionBenefits();
|
|
2687
|
+
const waiverStatus = __classPrivateFieldGet(this, _PerpsController_rewardsIntegrationService, "f").getSubscriptionFeeWaiverStatus();
|
|
2688
|
+
const context = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_createServiceContext).call(this, 'calculateFees', {
|
|
2689
|
+
subscriptionFeeWaiver: waiverStatus.reason === 'no-source' ? undefined : waiverStatus,
|
|
2690
|
+
});
|
|
2550
2691
|
return __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").calculateFees({ provider, params, context });
|
|
2551
2692
|
}
|
|
2693
|
+
/**
|
|
2694
|
+
* Approve the dedicated subscription builder outside order submission.
|
|
2695
|
+
* Until this succeeds, subscription waivers fall back to the ordinary
|
|
2696
|
+
* builder at the standard fee.
|
|
2697
|
+
*
|
|
2698
|
+
* @returns Whether the subscription builder is approved.
|
|
2699
|
+
*/
|
|
2700
|
+
async approveSubscriptionBuilderFee() {
|
|
2701
|
+
const provider = this.getActiveProvider();
|
|
2702
|
+
return provider.approveSubscriptionBuilderFee
|
|
2703
|
+
? provider.approveSubscriptionBuilderFee()
|
|
2704
|
+
: false;
|
|
2705
|
+
}
|
|
2706
|
+
/**
|
|
2707
|
+
* Drop the cached subscription benefits snapshot.
|
|
2708
|
+
*
|
|
2709
|
+
* Call this when the identity behind the benefits changes — sign-out, or a
|
|
2710
|
+
* profile switch. The snapshot carries no profile identity of its own, so
|
|
2711
|
+
* without this it keeps answering for the previous profile until the next
|
|
2712
|
+
* successful refresh. The next fee resolution reports the waiver as
|
|
2713
|
+
* unavailable, so it is withheld until preview or lifecycle hydration.
|
|
2714
|
+
*/
|
|
2715
|
+
invalidateSubscriptionBenefits() {
|
|
2716
|
+
__classPrivateFieldGet(this, _PerpsController_rewardsIntegrationService, "f").invalidateSubscriptionBenefits();
|
|
2717
|
+
}
|
|
2552
2718
|
/**
|
|
2553
2719
|
* Disconnect provider and cleanup subscriptions
|
|
2554
2720
|
* Call this when navigating away from Perps screens to prevent battery drain
|
|
@@ -3274,7 +3440,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
3274
3440
|
}
|
|
3275
3441
|
}
|
|
3276
3442
|
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() {
|
|
3443
|
+
_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
3444
|
const myx = __classPrivateFieldGet(this, _PerpsController_options, "f").clientConfig?.providerCredentials?.myx;
|
|
3279
3445
|
// Local env-var override (MM_PERPS_MYX_PROVIDER_ENABLED) always wins —
|
|
3280
3446
|
// matches the UI selector (resolvePerpsMyxProviderEnabled) so controller
|
|
@@ -3307,6 +3473,16 @@ _a = PerpsController, _PerpsController_initializationPromise = new WeakMap(), _P
|
|
|
3307
3473
|
__classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.logger.error(error, options);
|
|
3308
3474
|
}, _PerpsController_debugLog = function _PerpsController_debugLog(...args) {
|
|
3309
3475
|
__classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.debugLogger.log(...args);
|
|
3476
|
+
}, _PerpsController_awaitInitializationIfInProgress =
|
|
3477
|
+
/**
|
|
3478
|
+
* Awaits the in-flight initialization promise if init is currently running.
|
|
3479
|
+
* Called internally by #getActiveProviderWhenReady().
|
|
3480
|
+
*/
|
|
3481
|
+
async function _PerpsController_awaitInitializationIfInProgress() {
|
|
3482
|
+
if (this.state.initializationState === InitializationState.Initializing &&
|
|
3483
|
+
__classPrivateFieldGet(this, _PerpsController_initializationPromise, "f")) {
|
|
3484
|
+
await __classPrivateFieldGet(this, _PerpsController_initializationPromise, "f");
|
|
3485
|
+
}
|
|
3310
3486
|
}, _PerpsController_getAggregatedCacheProviderIds = function _PerpsController_getAggregatedCacheProviderIds(cacheKeys) {
|
|
3311
3487
|
const providerIds = new Set();
|
|
3312
3488
|
const currentNetwork = this.state.isTestnet ? 'testnet' : 'mainnet';
|
|
@@ -3327,6 +3503,96 @@ _a = PerpsController, _PerpsController_initializationPromise = new WeakMap(), _P
|
|
|
3327
3503
|
}
|
|
3328
3504
|
}
|
|
3329
3505
|
return Array.from(providerIds);
|
|
3506
|
+
}, _PerpsController_isMarketCacheEntryCurrent = function _PerpsController_isMarketCacheEntryCurrent(providerId, entry, options) {
|
|
3507
|
+
if (entry.sourceExpiresAt !== undefined) {
|
|
3508
|
+
const expectedDexes = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getStaticSnapshotDexes).call(this);
|
|
3509
|
+
return (providerId === 'hyperliquid' &&
|
|
3510
|
+
Date.now() < entry.sourceExpiresAt &&
|
|
3511
|
+
entry.hip3ConfigVersion === this.state.hip3ConfigVersion &&
|
|
3512
|
+
expectedDexes !== undefined &&
|
|
3513
|
+
Array.isArray(entry.dexes) &&
|
|
3514
|
+
entry.dexes.length === expectedDexes.length &&
|
|
3515
|
+
entry.dexes.every((dex, index) => dex === expectedDexes[index]));
|
|
3516
|
+
}
|
|
3517
|
+
return (options?.skipTTL === true ||
|
|
3518
|
+
Date.now() - entry.timestamp <= __classPrivateFieldGet(_a, _a, "f", _PerpsController_preloadGuardMs) * 10);
|
|
3519
|
+
}, _PerpsController_isUserCacheIdentityCurrent = function _PerpsController_isUserCacheIdentityCurrent(providerId, entry, address) {
|
|
3520
|
+
if (entry.address.toLowerCase() !== address.toLowerCase()) {
|
|
3521
|
+
return false;
|
|
3522
|
+
}
|
|
3523
|
+
if (providerId !== 'hyperliquid') {
|
|
3524
|
+
return true;
|
|
3525
|
+
}
|
|
3526
|
+
const expectedDexes = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getStaticSnapshotDexes).call(this);
|
|
3527
|
+
return (entry.hip3ConfigVersion === this.state.hip3ConfigVersion &&
|
|
3528
|
+
expectedDexes !== undefined &&
|
|
3529
|
+
Array.isArray(entry.dexes) &&
|
|
3530
|
+
entry.dexes.length === expectedDexes.length &&
|
|
3531
|
+
entry.dexes.every((dex, index) => dex === expectedDexes[index]));
|
|
3532
|
+
}, _PerpsController_fetchAndCacheUserDataSnapshot = async function _PerpsController_fetchAndCacheUserDataSnapshot(context) {
|
|
3533
|
+
const { provider, standaloneProvider, address, isTestnet, hip3ConfigVersion, expectedDexes, isCurrent, } = context;
|
|
3534
|
+
if (!isCurrent()) {
|
|
3535
|
+
throw new Error('User data snapshot context changed');
|
|
3536
|
+
}
|
|
3537
|
+
if (!provider.getUserDataSnapshot) {
|
|
3538
|
+
throw new Error('Provider has no atomic snapshot API');
|
|
3539
|
+
}
|
|
3540
|
+
const identity = {
|
|
3541
|
+
provider: 'hyperliquid',
|
|
3542
|
+
network: isTestnet ? 'testnet' : 'mainnet',
|
|
3543
|
+
hip3ConfigVersion,
|
|
3544
|
+
dexes: expectedDexes,
|
|
3545
|
+
};
|
|
3546
|
+
const snapshotRequest = provider.getUserDataSnapshot({
|
|
3547
|
+
userAddress: address,
|
|
3548
|
+
identity,
|
|
3549
|
+
});
|
|
3550
|
+
const snapshot = standaloneProvider
|
|
3551
|
+
? await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_trackStandaloneProviderOperation).call(this, standaloneProvider, snapshotRequest)
|
|
3552
|
+
: await snapshotRequest;
|
|
3553
|
+
if (!isCurrent()) {
|
|
3554
|
+
throw new Error('User data snapshot context changed');
|
|
3555
|
+
}
|
|
3556
|
+
const snapshotIdentity = snapshot.identity;
|
|
3557
|
+
const hasCompleteBundle = Array.isArray(snapshot.positions) &&
|
|
3558
|
+
Array.isArray(snapshot.orders) &&
|
|
3559
|
+
snapshot.accountState !== null &&
|
|
3560
|
+
typeof snapshot.accountState === 'object';
|
|
3561
|
+
const hasExactIdentity = snapshotIdentity.provider === identity.provider &&
|
|
3562
|
+
snapshotIdentity.network === identity.network &&
|
|
3563
|
+
snapshotIdentity.hip3ConfigVersion === identity.hip3ConfigVersion &&
|
|
3564
|
+
snapshotIdentity.address.toLowerCase() === address.toLowerCase() &&
|
|
3565
|
+
snapshotIdentity.dexes.length === expectedDexes.length &&
|
|
3566
|
+
snapshotIdentity.dexes.every((dex, index) => dex === expectedDexes[index]);
|
|
3567
|
+
if (!hasCompleteBundle || !hasExactIdentity) {
|
|
3568
|
+
throw new Error('User data snapshot is incomplete or mismatched');
|
|
3569
|
+
}
|
|
3570
|
+
if (!isCurrent()) {
|
|
3571
|
+
throw new Error('User data snapshot context changed');
|
|
3572
|
+
}
|
|
3573
|
+
const cachedSnapshot = cloneUserDataSnapshot(snapshot);
|
|
3574
|
+
const result = cloneUserDataSnapshot(snapshot);
|
|
3575
|
+
const timestamp = Date.now();
|
|
3576
|
+
const providerNetworkKey = (0, perpsConfig_js_1.buildProviderCacheKey)('hyperliquid', isTestnet);
|
|
3577
|
+
this.update((state) => {
|
|
3578
|
+
state.cachedUserDataByProvider[providerNetworkKey] = {
|
|
3579
|
+
positions: cachedSnapshot.positions,
|
|
3580
|
+
orders: cachedSnapshot.orders,
|
|
3581
|
+
accountState: cachedSnapshot.accountState,
|
|
3582
|
+
timestamp,
|
|
3583
|
+
address,
|
|
3584
|
+
hip3ConfigVersion,
|
|
3585
|
+
dexes: expectedDexes,
|
|
3586
|
+
};
|
|
3587
|
+
});
|
|
3588
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_persistUserCacheToDisk).call(this);
|
|
3589
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: user cache snapshot written', {
|
|
3590
|
+
writtenKey: providerNetworkKey,
|
|
3591
|
+
availableKeys: Object.keys(this.state.cachedUserDataByProvider).sort(),
|
|
3592
|
+
positionCount: cachedSnapshot.positions.length,
|
|
3593
|
+
orderCount: cachedSnapshot.orders.length,
|
|
3594
|
+
});
|
|
3595
|
+
return result;
|
|
3330
3596
|
}, _PerpsController_getOrCreateStandaloneProvider = function _PerpsController_getOrCreateStandaloneProvider() {
|
|
3331
3597
|
const currentIsTestnet = this.state.isTestnet;
|
|
3332
3598
|
const currentHip3Version = this.state.hip3ConfigVersion ?? 0;
|
|
@@ -3335,10 +3601,13 @@ _a = PerpsController, _PerpsController_initializationPromise = new WeakMap(), _P
|
|
|
3335
3601
|
__classPrivateFieldGet(this, _PerpsController_standaloneProviderHip3Version, "f") === currentHip3Version) {
|
|
3336
3602
|
return __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f");
|
|
3337
3603
|
}
|
|
3338
|
-
// Stale or missing —
|
|
3604
|
+
// Stale or missing — retire the old provider after active operations finish.
|
|
3339
3605
|
if (__classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f")) {
|
|
3340
3606
|
const old = __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f");
|
|
3341
|
-
|
|
3607
|
+
__classPrivateFieldSet(this, _PerpsController_standaloneProvider, null, "f");
|
|
3608
|
+
__classPrivateFieldSet(this, _PerpsController_standaloneProviderIsTestnet, null, "f");
|
|
3609
|
+
__classPrivateFieldSet(this, _PerpsController_standaloneProviderHip3Version, null, "f");
|
|
3610
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_retireStandaloneProvider).call(this, old).catch(() => {
|
|
3342
3611
|
/* best-effort */
|
|
3343
3612
|
});
|
|
3344
3613
|
}
|
|
@@ -3354,28 +3623,53 @@ _a = PerpsController, _PerpsController_initializationPromise = new WeakMap(), _P
|
|
|
3354
3623
|
?.builderAddressTestnet,
|
|
3355
3624
|
builderAddressMainnet: __classPrivateFieldGet(this, _PerpsController_options, "f").clientConfig?.providerCredentials?.hyperliquid
|
|
3356
3625
|
?.builderAddressMainnet,
|
|
3626
|
+
subscriptionBuilderAddressTestnet: __classPrivateFieldGet(this, _PerpsController_options, "f").clientConfig?.providerCredentials?.hyperliquid
|
|
3627
|
+
?.subscriptionBuilderAddressTestnet,
|
|
3628
|
+
subscriptionBuilderAddressMainnet: __classPrivateFieldGet(this, _PerpsController_options, "f").clientConfig?.providerCredentials?.hyperliquid
|
|
3629
|
+
?.subscriptionBuilderAddressMainnet,
|
|
3357
3630
|
}), "f");
|
|
3358
3631
|
__classPrivateFieldSet(this, _PerpsController_standaloneProviderIsTestnet, currentIsTestnet, "f");
|
|
3359
3632
|
__classPrivateFieldSet(this, _PerpsController_standaloneProviderHip3Version, currentHip3Version, "f");
|
|
3360
3633
|
return __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f");
|
|
3634
|
+
}, _PerpsController_trackStandaloneProviderOperation = function _PerpsController_trackStandaloneProviderOperation(provider, operation) {
|
|
3635
|
+
const operations = __classPrivateFieldGet(this, _PerpsController_standaloneProviderOperations, "f").get(provider) ?? new Set();
|
|
3636
|
+
__classPrivateFieldGet(this, _PerpsController_standaloneProviderOperations, "f").set(provider, operations);
|
|
3637
|
+
const trackedOperation = operation.finally(() => {
|
|
3638
|
+
operations.delete(trackedOperation);
|
|
3639
|
+
if (operations.size === 0) {
|
|
3640
|
+
__classPrivateFieldGet(this, _PerpsController_standaloneProviderOperations, "f").delete(provider);
|
|
3641
|
+
}
|
|
3642
|
+
});
|
|
3643
|
+
operations.add(trackedOperation);
|
|
3644
|
+
return trackedOperation;
|
|
3645
|
+
}, _PerpsController_retireStandaloneProvider = async function _PerpsController_retireStandaloneProvider(provider) {
|
|
3646
|
+
const operations = __classPrivateFieldGet(this, _PerpsController_standaloneProviderOperations, "f").get(provider);
|
|
3647
|
+
if (operations?.size) {
|
|
3648
|
+
await Promise.allSettled([...operations]);
|
|
3649
|
+
}
|
|
3650
|
+
try {
|
|
3651
|
+
await provider.disconnect();
|
|
3652
|
+
}
|
|
3653
|
+
catch {
|
|
3654
|
+
/* best-effort */
|
|
3655
|
+
}
|
|
3656
|
+
finally {
|
|
3657
|
+
__classPrivateFieldGet(this, _PerpsController_standaloneProviderOperations, "f").delete(provider);
|
|
3658
|
+
}
|
|
3361
3659
|
}, _PerpsController_cleanupStandaloneProvider =
|
|
3362
3660
|
/**
|
|
3363
3661
|
* Disconnect and discard the cached standalone provider (if any).
|
|
3364
3662
|
* Best-effort — errors are silently caught.
|
|
3365
3663
|
*/
|
|
3366
3664
|
async function _PerpsController_cleanupStandaloneProvider() {
|
|
3367
|
-
|
|
3665
|
+
const provider = __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f");
|
|
3666
|
+
if (!provider) {
|
|
3368
3667
|
return;
|
|
3369
3668
|
}
|
|
3370
|
-
try {
|
|
3371
|
-
await __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f").disconnect();
|
|
3372
|
-
}
|
|
3373
|
-
catch {
|
|
3374
|
-
/* best-effort */
|
|
3375
|
-
}
|
|
3376
3669
|
__classPrivateFieldSet(this, _PerpsController_standaloneProvider, null, "f");
|
|
3377
3670
|
__classPrivateFieldSet(this, _PerpsController_standaloneProviderIsTestnet, null, "f");
|
|
3378
3671
|
__classPrivateFieldSet(this, _PerpsController_standaloneProviderHip3Version, null, "f");
|
|
3672
|
+
await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_retireStandaloneProvider).call(this, provider);
|
|
3379
3673
|
}, _PerpsController_getMetrics = function _PerpsController_getMetrics() {
|
|
3380
3674
|
return __classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.metrics;
|
|
3381
3675
|
}, _PerpsController_findNetworkClientIdForChain = function _PerpsController_findNetworkClientIdForChain(chainId) {
|
|
@@ -3593,6 +3887,10 @@ async function _PerpsController_performInitialization() {
|
|
|
3593
3887
|
?.builderAddressTestnet,
|
|
3594
3888
|
builderAddressMainnet: __classPrivateFieldGet(this, _PerpsController_options, "f").clientConfig?.providerCredentials?.hyperliquid
|
|
3595
3889
|
?.builderAddressMainnet,
|
|
3890
|
+
subscriptionBuilderAddressTestnet: __classPrivateFieldGet(this, _PerpsController_options, "f").clientConfig?.providerCredentials?.hyperliquid
|
|
3891
|
+
?.subscriptionBuilderAddressTestnet,
|
|
3892
|
+
subscriptionBuilderAddressMainnet: __classPrivateFieldGet(this, _PerpsController_options, "f").clientConfig?.providerCredentials?.hyperliquid
|
|
3893
|
+
?.subscriptionBuilderAddressMainnet,
|
|
3596
3894
|
});
|
|
3597
3895
|
this.providers.set('hyperliquid', hyperLiquidProvider);
|
|
3598
3896
|
// Register MYX provider if enabled via feature flag.
|
|
@@ -3709,6 +4007,75 @@ async function _PerpsController_performInitialization() {
|
|
|
3709
4007
|
__classPrivateFieldGet(this, _PerpsController_tradingService, "f").setControllerDependencies({
|
|
3710
4008
|
rewardsIntegrationService: __classPrivateFieldGet(this, _PerpsController_rewardsIntegrationService, "f"),
|
|
3711
4009
|
});
|
|
4010
|
+
}, _PerpsController_getActiveProviderWhenReady =
|
|
4011
|
+
/**
|
|
4012
|
+
* Await in-flight initialization, then return the active provider.
|
|
4013
|
+
* Use for async action methods (trading, deposits, withdrawals) that should
|
|
4014
|
+
* tolerate an in-progress cold-start or reconnection instead of failing
|
|
4015
|
+
* immediately with CLIENT_NOT_INITIALIZED.
|
|
4016
|
+
*
|
|
4017
|
+
* Synchronous callers that need fail-fast behaviour should keep using
|
|
4018
|
+
* getActiveProvider() directly.
|
|
4019
|
+
*
|
|
4020
|
+
* @returns The active provider once initialization completes.
|
|
4021
|
+
*/
|
|
4022
|
+
async function _PerpsController_getActiveProviderWhenReady() {
|
|
4023
|
+
await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_awaitInitializationIfInProgress).call(this);
|
|
4024
|
+
return this.getActiveProvider();
|
|
4025
|
+
}, _PerpsController_buildGlobalSnapshotContext = function _PerpsController_buildGlobalSnapshotContext() {
|
|
4026
|
+
const snapshotConfigured = Boolean(__classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.terminalApi?.globalSnapshotUrl) ||
|
|
4027
|
+
typeof __classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.terminalMarketService
|
|
4028
|
+
?.fetchGlobalSnapshot === 'function';
|
|
4029
|
+
if (!snapshotConfigured || this.state.activeProvider !== 'hyperliquid') {
|
|
4030
|
+
return undefined;
|
|
4031
|
+
}
|
|
4032
|
+
const enabledDexes = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getStaticSnapshotDexes).call(this);
|
|
4033
|
+
if (!enabledDexes) {
|
|
4034
|
+
return undefined;
|
|
4035
|
+
}
|
|
4036
|
+
const { isTestnet, hip3ConfigVersion } = this.state;
|
|
4037
|
+
return {
|
|
4038
|
+
request: {
|
|
4039
|
+
provider: 'hyperliquid',
|
|
4040
|
+
network: isTestnet ? 'testnet' : 'mainnet',
|
|
4041
|
+
enabledDexes,
|
|
4042
|
+
},
|
|
4043
|
+
isCurrent: () => this.state.activeProvider === 'hyperliquid' &&
|
|
4044
|
+
this.state.isTestnet === isTestnet &&
|
|
4045
|
+
this.state.hip3ConfigVersion === hip3ConfigVersion,
|
|
4046
|
+
isMarketAllowed: __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_buildMarketAllowedFilter).call(this),
|
|
4047
|
+
};
|
|
4048
|
+
}, _PerpsController_getStaticSnapshotDexes = function _PerpsController_getStaticSnapshotDexes() {
|
|
4049
|
+
if (!__classPrivateFieldGet(this, _PerpsController_hip3Enabled, "f")) {
|
|
4050
|
+
return ['main'];
|
|
4051
|
+
}
|
|
4052
|
+
if (this.state.isTestnet) {
|
|
4053
|
+
return hyperLiquidConfig_js_1.TESTNET_HIP3_CONFIG.AutoDiscoverAll
|
|
4054
|
+
? undefined
|
|
4055
|
+
: (0, hyperLiquidConfig_js_1.canonicalizeHyperLiquidDexes)(hyperLiquidConfig_js_1.TESTNET_HIP3_CONFIG.EnabledDexs);
|
|
4056
|
+
}
|
|
4057
|
+
if (hyperLiquidConfig_js_1.MAINNET_HIP3_CONFIG.AutoDiscoverAll) {
|
|
4058
|
+
return undefined;
|
|
4059
|
+
}
|
|
4060
|
+
const dexes = new Set();
|
|
4061
|
+
for (const pattern of __classPrivateFieldGet(this, _PerpsController_hip3AllowlistMarkets, "f")) {
|
|
4062
|
+
const colonIndex = pattern.indexOf(':');
|
|
4063
|
+
if (colonIndex <= 0) {
|
|
4064
|
+
if (/^[a-z][a-z0-9]*$/iu.test(pattern)) {
|
|
4065
|
+
dexes.add(pattern.toLowerCase());
|
|
4066
|
+
continue;
|
|
4067
|
+
}
|
|
4068
|
+
return undefined;
|
|
4069
|
+
}
|
|
4070
|
+
const dex = pattern.slice(0, colonIndex);
|
|
4071
|
+
if (dex && /^[a-z0-9][a-z0-9-]*$/u.test(dex)) {
|
|
4072
|
+
dexes.add(dex);
|
|
4073
|
+
}
|
|
4074
|
+
else {
|
|
4075
|
+
return undefined;
|
|
4076
|
+
}
|
|
4077
|
+
}
|
|
4078
|
+
return (0, hyperLiquidConfig_js_1.canonicalizeHyperLiquidDexes)(dexes);
|
|
3712
4079
|
}, _PerpsController_hydrateCacheFromDiskSync = function _PerpsController_hydrateCacheFromDiskSync() {
|
|
3713
4080
|
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
4081
|
const hasMarketUpdates = Object.keys(marketUpdates).length > 0;
|
|
@@ -3729,12 +4096,40 @@ async function _PerpsController_performInitialization() {
|
|
|
3729
4096
|
orders: stats.userOrders,
|
|
3730
4097
|
duration_ms: stats.durationMs,
|
|
3731
4098
|
});
|
|
4099
|
+
}, _PerpsController_persistUserCacheToDisk = function _PerpsController_persistUserCacheToDisk() {
|
|
4100
|
+
const entries = [];
|
|
4101
|
+
for (const [cacheKey, entry] of Object.entries(this.state.cachedUserDataByProvider)) {
|
|
4102
|
+
const [providerId, network] = cacheKey.split(':');
|
|
4103
|
+
if (!providerId ||
|
|
4104
|
+
(network !== 'mainnet' && network !== 'testnet') ||
|
|
4105
|
+
providerId === 'aggregated') {
|
|
4106
|
+
continue;
|
|
4107
|
+
}
|
|
4108
|
+
entries.push({
|
|
4109
|
+
providerNetworkKey: `${providerId}:${network}`,
|
|
4110
|
+
address: entry.address,
|
|
4111
|
+
positions: entry.positions,
|
|
4112
|
+
orders: entry.orders,
|
|
4113
|
+
accountState: entry.accountState,
|
|
4114
|
+
timestamp: entry.timestamp,
|
|
4115
|
+
...(entry.hip3ConfigVersion !== undefined && {
|
|
4116
|
+
hip3ConfigVersion: entry.hip3ConfigVersion,
|
|
4117
|
+
}),
|
|
4118
|
+
...(entry.dexes !== undefined && { dexes: entry.dexes }),
|
|
4119
|
+
});
|
|
4120
|
+
}
|
|
4121
|
+
__classPrivateFieldSet(this, _PerpsController_userDiskWrite, __classPrivateFieldGet(this, _PerpsController_userDiskWrite, "f")
|
|
4122
|
+
.then(() => (0, perpsDiskPersistence_js_1.persistUserEntriesToDisk)(__classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.diskCache, entries))
|
|
4123
|
+
.catch(() => {
|
|
4124
|
+
// Disk persistence is best-effort and must not block live data.
|
|
4125
|
+
}), "f");
|
|
3732
4126
|
}, _PerpsController_performMarketDataPreload =
|
|
3733
4127
|
/**
|
|
3734
4128
|
* Perform a single market data preload (best-effort, no throw).
|
|
3735
4129
|
*/
|
|
3736
4130
|
async function _PerpsController_performMarketDataPreload() {
|
|
3737
4131
|
if (__classPrivateFieldGet(this, _PerpsController_isPreloading, "f")) {
|
|
4132
|
+
__classPrivateFieldSet(this, _PerpsController_marketPreloadQueued, true, "f");
|
|
3738
4133
|
return;
|
|
3739
4134
|
}
|
|
3740
4135
|
// Skip preloading during provider/network reinitialisation.
|
|
@@ -3749,9 +4144,16 @@ async function _PerpsController_performMarketDataPreload() {
|
|
|
3749
4144
|
? this.state.activeProvider // includes 'aggregated'
|
|
3750
4145
|
: 'hyperliquid';
|
|
3751
4146
|
const cacheKey = (0, perpsConfig_js_1.buildProviderCacheKey)(actualProviderId, this.state.isTestnet);
|
|
4147
|
+
const preloadContext = {
|
|
4148
|
+
activeProvider: this.state.activeProvider,
|
|
4149
|
+
isTestnet: this.state.isTestnet,
|
|
4150
|
+
hip3ConfigVersion: this.state.hip3ConfigVersion,
|
|
4151
|
+
};
|
|
4152
|
+
const staticSnapshotDexes = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getStaticSnapshotDexes).call(this);
|
|
3752
4153
|
const now = Date.now();
|
|
3753
4154
|
const existingEntry = this.state.cachedMarketDataByProvider[cacheKey];
|
|
3754
4155
|
if (existingEntry &&
|
|
4156
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_isMarketCacheEntryCurrent).call(this, actualProviderId, existingEntry) &&
|
|
3755
4157
|
now - existingEntry.timestamp < __classPrivateFieldGet(_a, _a, "f", _PerpsController_preloadGuardMs)) {
|
|
3756
4158
|
return;
|
|
3757
4159
|
}
|
|
@@ -3776,8 +4178,32 @@ async function _PerpsController_performMarketDataPreload() {
|
|
|
3776
4178
|
duration_ms: Math.round(performance.now() - preloadStart),
|
|
3777
4179
|
markets: data.length,
|
|
3778
4180
|
});
|
|
4181
|
+
if (this.state.activeProvider !== preloadContext.activeProvider ||
|
|
4182
|
+
this.state.isTestnet !== preloadContext.isTestnet ||
|
|
4183
|
+
this.state.hip3ConfigVersion !== preloadContext.hip3ConfigVersion) {
|
|
4184
|
+
traceData = {
|
|
4185
|
+
success: false,
|
|
4186
|
+
error: 'Global snapshot preload context changed',
|
|
4187
|
+
};
|
|
4188
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Discarding stale global snapshot preload');
|
|
4189
|
+
return;
|
|
4190
|
+
}
|
|
3779
4191
|
// Store under per-provider key(s)
|
|
3780
4192
|
const ts = Date.now();
|
|
4193
|
+
const sourceExpiries = data.flatMap((market) => market.dataSource === 'terminal-global-snapshot-mark' &&
|
|
4194
|
+
typeof market.sourceExpiresAt === 'number'
|
|
4195
|
+
? [market.sourceExpiresAt]
|
|
4196
|
+
: []);
|
|
4197
|
+
const sourceExpiresAt = data.length > 0 && sourceExpiries.length === data.length
|
|
4198
|
+
? Math.min(...sourceExpiries)
|
|
4199
|
+
: undefined;
|
|
4200
|
+
const snapshotCacheIdentity = sourceExpiresAt !== undefined && staticSnapshotDexes
|
|
4201
|
+
? {
|
|
4202
|
+
sourceExpiresAt,
|
|
4203
|
+
hip3ConfigVersion: preloadContext.hip3ConfigVersion,
|
|
4204
|
+
dexes: staticSnapshotDexes,
|
|
4205
|
+
}
|
|
4206
|
+
: {};
|
|
3781
4207
|
const marketDiskEntries = [];
|
|
3782
4208
|
if (this.state.activeProvider === 'aggregated' &&
|
|
3783
4209
|
this.activeProviderInstance) {
|
|
@@ -3824,6 +4250,7 @@ async function _PerpsController_performMarketDataPreload() {
|
|
|
3824
4250
|
state.cachedMarketDataByProvider[cacheKey] = {
|
|
3825
4251
|
data,
|
|
3826
4252
|
timestamp: ts,
|
|
4253
|
+
...snapshotCacheIdentity,
|
|
3827
4254
|
};
|
|
3828
4255
|
});
|
|
3829
4256
|
}
|
|
@@ -3833,10 +4260,6 @@ async function _PerpsController_performMarketDataPreload() {
|
|
|
3833
4260
|
});
|
|
3834
4261
|
traceData = { success: true, marketCount: data.length };
|
|
3835
4262
|
__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
4263
|
}
|
|
3841
4264
|
catch (error) {
|
|
3842
4265
|
traceData = {
|
|
@@ -3855,6 +4278,12 @@ async function _PerpsController_performMarketDataPreload() {
|
|
|
3855
4278
|
data: traceData,
|
|
3856
4279
|
});
|
|
3857
4280
|
__classPrivateFieldSet(this, _PerpsController_isPreloading, false, "f");
|
|
4281
|
+
if (__classPrivateFieldGet(this, _PerpsController_marketPreloadQueued, "f") && __classPrivateFieldGet(this, _PerpsController_preloadTimer, "f")) {
|
|
4282
|
+
__classPrivateFieldSet(this, _PerpsController_marketPreloadQueued, false, "f");
|
|
4283
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performMarketDataPreload).call(this).catch(() => {
|
|
4284
|
+
// Background preload is best-effort.
|
|
4285
|
+
});
|
|
4286
|
+
}
|
|
3858
4287
|
}
|
|
3859
4288
|
}, _PerpsController_performUserDataPreload =
|
|
3860
4289
|
/**
|
|
@@ -3863,6 +4292,10 @@ async function _PerpsController_performMarketDataPreload() {
|
|
|
3863
4292
|
*/
|
|
3864
4293
|
async function _PerpsController_performUserDataPreload() {
|
|
3865
4294
|
if (__classPrivateFieldGet(this, _PerpsController_isPreloadingUserData, "f")) {
|
|
4295
|
+
__classPrivateFieldSet(this, _PerpsController_userPreloadQueued, true, "f");
|
|
4296
|
+
return;
|
|
4297
|
+
}
|
|
4298
|
+
if (__classPrivateFieldGet(this, _PerpsController_isReinitializing, "f")) {
|
|
3866
4299
|
return;
|
|
3867
4300
|
}
|
|
3868
4301
|
// Get current user address
|
|
@@ -3871,21 +4304,54 @@ async function _PerpsController_performUserDataPreload() {
|
|
|
3871
4304
|
return;
|
|
3872
4305
|
}
|
|
3873
4306
|
const userAddress = evmAccount.address;
|
|
4307
|
+
const { activeProvider, isTestnet, hip3ConfigVersion } = this.state;
|
|
4308
|
+
const { activeProviderInstance } = this;
|
|
4309
|
+
const hyperliquidDexes = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getStaticSnapshotDexes).call(this);
|
|
4310
|
+
const isCurrent = () => {
|
|
4311
|
+
let currentAddress;
|
|
4312
|
+
try {
|
|
4313
|
+
currentAddress = (0, accountUtils_js_1.getSelectedEvmAccountFromMessenger)(this.messenger)?.address;
|
|
4314
|
+
}
|
|
4315
|
+
catch {
|
|
4316
|
+
return false;
|
|
4317
|
+
}
|
|
4318
|
+
return (this.state.activeProvider === activeProvider &&
|
|
4319
|
+
this.activeProviderInstance === activeProviderInstance &&
|
|
4320
|
+
this.state.isTestnet === isTestnet &&
|
|
4321
|
+
this.state.hip3ConfigVersion === hip3ConfigVersion &&
|
|
4322
|
+
currentAddress?.toLowerCase() === userAddress.toLowerCase());
|
|
4323
|
+
};
|
|
3874
4324
|
// Determine actual provider (same logic as market preload)
|
|
3875
|
-
const actualProviderId =
|
|
3876
|
-
?
|
|
4325
|
+
const actualProviderId = activeProviderInstance
|
|
4326
|
+
? activeProvider // includes 'aggregated'
|
|
3877
4327
|
: 'hyperliquid';
|
|
3878
|
-
const
|
|
4328
|
+
const providerNetworkKey = (0, perpsConfig_js_1.buildProviderCacheKey)(actualProviderId, isTestnet);
|
|
3879
4329
|
// Skip if cache is fresh and for same account
|
|
3880
4330
|
const now = Date.now();
|
|
3881
|
-
const existingEntry = this.state.cachedUserDataByProvider[
|
|
3882
|
-
|
|
4331
|
+
const existingEntry = this.state.cachedUserDataByProvider[providerNetworkKey];
|
|
4332
|
+
const hasMatchingCache = existingEntry !== undefined &&
|
|
4333
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_isUserCacheIdentityCurrent).call(this, actualProviderId, existingEntry, userAddress);
|
|
4334
|
+
const cacheAgeMs = existingEntry ? now - existingEntry.timestamp : null;
|
|
4335
|
+
const websocketState = this.getWebSocketConnectionState();
|
|
4336
|
+
let selectedEntryKey = null;
|
|
4337
|
+
if (this.state.cachedUserDataByProvider[providerNetworkKey]) {
|
|
4338
|
+
selectedEntryKey = providerNetworkKey;
|
|
4339
|
+
}
|
|
4340
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: user cache preload decision', {
|
|
4341
|
+
requestedKey: providerNetworkKey,
|
|
4342
|
+
selectedEntryKey,
|
|
4343
|
+
availableKeys: Object.keys(this.state.cachedUserDataByProvider).sort(),
|
|
4344
|
+
hasMatchingCache,
|
|
4345
|
+
cacheAgeMs,
|
|
4346
|
+
websocketState,
|
|
4347
|
+
});
|
|
4348
|
+
if (existingEntry &&
|
|
4349
|
+
hasMatchingCache &&
|
|
3883
4350
|
now - existingEntry.timestamp < __classPrivateFieldGet(_a, _a, "f", _PerpsController_preloadGuardMs)) {
|
|
3884
4351
|
return;
|
|
3885
4352
|
}
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Skipping user data preload — WebSocket connected');
|
|
4353
|
+
if (hasMatchingCache &&
|
|
4354
|
+
this.getWebSocketConnectionState() === index_js_1.WebSocketConnectionState.Connected) {
|
|
3889
4355
|
return;
|
|
3890
4356
|
}
|
|
3891
4357
|
__classPrivateFieldSet(this, _PerpsController_isPreloadingUserData, true, "f");
|
|
@@ -3898,21 +4364,38 @@ async function _PerpsController_performUserDataPreload() {
|
|
|
3898
4364
|
id: traceId,
|
|
3899
4365
|
op: index_js_1.PerpsTraceOperations.Operation,
|
|
3900
4366
|
tags: {
|
|
3901
|
-
provider:
|
|
3902
|
-
isTestnet
|
|
4367
|
+
provider: activeProvider,
|
|
4368
|
+
isTestnet,
|
|
3903
4369
|
},
|
|
3904
4370
|
data: { userAddress },
|
|
3905
4371
|
});
|
|
3906
4372
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Fetching user data in background', {
|
|
3907
4373
|
userAddress,
|
|
3908
4374
|
});
|
|
4375
|
+
if (activeProvider === 'hyperliquid') {
|
|
4376
|
+
const snapshot = await this.getUserDataSnapshot();
|
|
4377
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: User data preloaded', {
|
|
4378
|
+
positionCount: snapshot.positions.length,
|
|
4379
|
+
orderCount: snapshot.orders.length,
|
|
4380
|
+
totalBalance: snapshot.accountState.totalBalance,
|
|
4381
|
+
});
|
|
4382
|
+
traceData = {
|
|
4383
|
+
success: true,
|
|
4384
|
+
positionCount: snapshot.positions.length,
|
|
4385
|
+
orderCount: snapshot.orders.length,
|
|
4386
|
+
};
|
|
4387
|
+
__classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.tracer.setMeasurement(performanceMetrics_js_1.PerpsMeasurementName.PerpsUserDataPreload, performance.now() - preloadStart, 'millisecond');
|
|
4388
|
+
return;
|
|
4389
|
+
}
|
|
3909
4390
|
const [positions, orders, accountState] = await Promise.all([
|
|
3910
4391
|
this.getPositions({ standalone: true, userAddress }),
|
|
3911
4392
|
this.getOpenOrders({ standalone: true, userAddress }),
|
|
3912
4393
|
this.getAccountState({ standalone: true, userAddress }),
|
|
3913
4394
|
]);
|
|
3914
|
-
if (
|
|
3915
|
-
|
|
4395
|
+
if (!isCurrent()) {
|
|
4396
|
+
throw new Error('User data preload context changed');
|
|
4397
|
+
}
|
|
4398
|
+
if (activeProvider === 'aggregated' && activeProviderInstance) {
|
|
3916
4399
|
// Split by providerId and write one cache entry per provider key
|
|
3917
4400
|
// (mirrors the market-data preload pattern at ~line 2976)
|
|
3918
4401
|
const ts = Date.now();
|
|
@@ -3934,26 +4417,22 @@ async function _PerpsController_performUserDataPreload() {
|
|
|
3934
4417
|
}
|
|
3935
4418
|
// AccountState — assign to its provider bucket
|
|
3936
4419
|
ensureBucket(accountState.providerId ?? fallbackProviderId).accountState = accountState;
|
|
3937
|
-
const diskEntries = [];
|
|
3938
4420
|
this.update((state) => {
|
|
3939
4421
|
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
|
-
});
|
|
4422
|
+
const key = (0, perpsConfig_js_1.buildProviderCacheKey)(pid, isTestnet);
|
|
3949
4423
|
state.cachedUserDataByProvider[key] = {
|
|
3950
4424
|
...data,
|
|
3951
4425
|
timestamp: ts,
|
|
3952
4426
|
address: userAddress,
|
|
4427
|
+
...(pid === 'hyperliquid' &&
|
|
4428
|
+
hyperliquidDexes && {
|
|
4429
|
+
hip3ConfigVersion,
|
|
4430
|
+
dexes: hyperliquidDexes,
|
|
4431
|
+
}),
|
|
3953
4432
|
};
|
|
3954
4433
|
}
|
|
3955
4434
|
// Write aggregated sentinel so the staleness guard sees it
|
|
3956
|
-
state.cachedUserDataByProvider[
|
|
4435
|
+
state.cachedUserDataByProvider[providerNetworkKey] = {
|
|
3957
4436
|
positions: [],
|
|
3958
4437
|
orders: [],
|
|
3959
4438
|
accountState: null,
|
|
@@ -3961,30 +4440,26 @@ async function _PerpsController_performUserDataPreload() {
|
|
|
3961
4440
|
address: userAddress,
|
|
3962
4441
|
};
|
|
3963
4442
|
});
|
|
3964
|
-
|
|
4443
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_persistUserCacheToDisk).call(this);
|
|
3965
4444
|
}
|
|
3966
4445
|
else {
|
|
3967
4446
|
// Single provider — store directly under its key
|
|
3968
4447
|
const ts = Date.now();
|
|
3969
4448
|
this.update((state) => {
|
|
3970
|
-
state.cachedUserDataByProvider[
|
|
4449
|
+
state.cachedUserDataByProvider[providerNetworkKey] = {
|
|
3971
4450
|
positions,
|
|
3972
4451
|
orders,
|
|
3973
4452
|
accountState,
|
|
3974
4453
|
timestamp: ts,
|
|
3975
4454
|
address: userAddress,
|
|
4455
|
+
...(actualProviderId === 'hyperliquid' &&
|
|
4456
|
+
hyperliquidDexes && {
|
|
4457
|
+
hip3ConfigVersion,
|
|
4458
|
+
dexes: hyperliquidDexes,
|
|
4459
|
+
}),
|
|
3976
4460
|
};
|
|
3977
4461
|
});
|
|
3978
|
-
|
|
3979
|
-
{
|
|
3980
|
-
providerNetworkKey: userCacheKey,
|
|
3981
|
-
address: userAddress,
|
|
3982
|
-
positions,
|
|
3983
|
-
orders,
|
|
3984
|
-
accountState,
|
|
3985
|
-
timestamp: ts,
|
|
3986
|
-
},
|
|
3987
|
-
]);
|
|
4462
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_persistUserCacheToDisk).call(this);
|
|
3988
4463
|
}
|
|
3989
4464
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: User data preloaded', {
|
|
3990
4465
|
positionCount: positions.length,
|
|
@@ -4015,6 +4490,12 @@ async function _PerpsController_performUserDataPreload() {
|
|
|
4015
4490
|
data: traceData,
|
|
4016
4491
|
});
|
|
4017
4492
|
__classPrivateFieldSet(this, _PerpsController_isPreloadingUserData, false, "f");
|
|
4493
|
+
if (__classPrivateFieldGet(this, _PerpsController_userPreloadQueued, "f") && __classPrivateFieldGet(this, _PerpsController_preloadTimer, "f")) {
|
|
4494
|
+
__classPrivateFieldSet(this, _PerpsController_userPreloadQueued, false, "f");
|
|
4495
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
|
|
4496
|
+
// Background preload is best-effort.
|
|
4497
|
+
});
|
|
4498
|
+
}
|
|
4018
4499
|
}
|
|
4019
4500
|
}, _PerpsController_persistWatchlistToRemote =
|
|
4020
4501
|
/**
|