@metamask-previews/perps-controller 11.0.0-preview-ea8763e0c → 11.0.0-preview-6b4bcdab3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/CHANGELOG.md +0 -8
  2. package/dist/PerpsController-method-action-types.cjs.map +1 -1
  3. package/dist/PerpsController-method-action-types.d.cts +1 -12
  4. package/dist/PerpsController-method-action-types.d.cts.map +1 -1
  5. package/dist/PerpsController-method-action-types.d.mts +1 -12
  6. package/dist/PerpsController-method-action-types.d.mts.map +1 -1
  7. package/dist/PerpsController-method-action-types.mjs.map +1 -1
  8. package/dist/PerpsController.cjs +99 -519
  9. package/dist/PerpsController.cjs.map +1 -1
  10. package/dist/PerpsController.d.cts +4 -17
  11. package/dist/PerpsController.d.cts.map +1 -1
  12. package/dist/PerpsController.d.mts +4 -17
  13. package/dist/PerpsController.d.mts.map +1 -1
  14. package/dist/PerpsController.mjs +102 -522
  15. package/dist/PerpsController.mjs.map +1 -1
  16. package/dist/constants/eventNames.cjs +0 -3
  17. package/dist/constants/eventNames.cjs.map +1 -1
  18. package/dist/constants/eventNames.d.cts +0 -1
  19. package/dist/constants/eventNames.d.cts.map +1 -1
  20. package/dist/constants/eventNames.d.mts +0 -1
  21. package/dist/constants/eventNames.d.mts.map +1 -1
  22. package/dist/constants/eventNames.mjs +0 -3
  23. package/dist/constants/eventNames.mjs.map +1 -1
  24. package/dist/constants/hyperLiquidConfig.cjs +2 -14
  25. package/dist/constants/hyperLiquidConfig.cjs.map +1 -1
  26. package/dist/constants/hyperLiquidConfig.d.cts +0 -7
  27. package/dist/constants/hyperLiquidConfig.d.cts.map +1 -1
  28. package/dist/constants/hyperLiquidConfig.d.mts +0 -7
  29. package/dist/constants/hyperLiquidConfig.d.mts.map +1 -1
  30. package/dist/constants/hyperLiquidConfig.mjs +0 -11
  31. package/dist/constants/hyperLiquidConfig.mjs.map +1 -1
  32. package/dist/constants/perpsConfig.cjs +1 -4
  33. package/dist/constants/perpsConfig.cjs.map +1 -1
  34. package/dist/constants/perpsConfig.d.cts +7 -25
  35. package/dist/constants/perpsConfig.d.cts.map +1 -1
  36. package/dist/constants/perpsConfig.d.mts +7 -25
  37. package/dist/constants/perpsConfig.d.mts.map +1 -1
  38. package/dist/constants/perpsConfig.mjs +1 -4
  39. package/dist/constants/perpsConfig.mjs.map +1 -1
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.cts +3 -3
  42. package/dist/index.d.cts.map +1 -1
  43. package/dist/index.d.mts +3 -3
  44. package/dist/index.d.mts.map +1 -1
  45. package/dist/index.mjs.map +1 -1
  46. package/dist/providers/HyperLiquidProvider.cjs +1 -148
  47. package/dist/providers/HyperLiquidProvider.cjs.map +1 -1
  48. package/dist/providers/HyperLiquidProvider.d.cts +1 -11
  49. package/dist/providers/HyperLiquidProvider.d.cts.map +1 -1
  50. package/dist/providers/HyperLiquidProvider.d.mts +1 -11
  51. package/dist/providers/HyperLiquidProvider.d.mts.map +1 -1
  52. package/dist/providers/HyperLiquidProvider.mjs +2 -149
  53. package/dist/providers/HyperLiquidProvider.mjs.map +1 -1
  54. package/dist/services/HyperLiquidSubscriptionService.cjs +4 -15
  55. package/dist/services/HyperLiquidSubscriptionService.cjs.map +1 -1
  56. package/dist/services/HyperLiquidSubscriptionService.d.cts +1 -1
  57. package/dist/services/HyperLiquidSubscriptionService.d.cts.map +1 -1
  58. package/dist/services/HyperLiquidSubscriptionService.d.mts +1 -1
  59. package/dist/services/HyperLiquidSubscriptionService.d.mts.map +1 -1
  60. package/dist/services/HyperLiquidSubscriptionService.mjs +4 -15
  61. package/dist/services/HyperLiquidSubscriptionService.mjs.map +1 -1
  62. package/dist/services/MarketDataService.cjs +3 -41
  63. package/dist/services/MarketDataService.cjs.map +1 -1
  64. package/dist/services/MarketDataService.d.cts +2 -2
  65. package/dist/services/MarketDataService.d.cts.map +1 -1
  66. package/dist/services/MarketDataService.d.mts +2 -2
  67. package/dist/services/MarketDataService.d.mts.map +1 -1
  68. package/dist/services/MarketDataService.mjs +3 -41
  69. package/dist/services/MarketDataService.mjs.map +1 -1
  70. package/dist/services/ServiceContext.cjs.map +1 -1
  71. package/dist/services/ServiceContext.d.cts +1 -10
  72. package/dist/services/ServiceContext.d.cts.map +1 -1
  73. package/dist/services/ServiceContext.d.mts +1 -10
  74. package/dist/services/ServiceContext.d.mts.map +1 -1
  75. package/dist/services/ServiceContext.mjs.map +1 -1
  76. package/dist/services/TerminalMarketService.cjs +7 -422
  77. package/dist/services/TerminalMarketService.cjs.map +1 -1
  78. package/dist/services/TerminalMarketService.d.cts +1 -10
  79. package/dist/services/TerminalMarketService.d.cts.map +1 -1
  80. package/dist/services/TerminalMarketService.d.mts +1 -10
  81. package/dist/services/TerminalMarketService.d.mts.map +1 -1
  82. package/dist/services/TerminalMarketService.mjs +8 -423
  83. package/dist/services/TerminalMarketService.mjs.map +1 -1
  84. package/dist/types/index.cjs.map +1 -1
  85. package/dist/types/index.d.cts +7 -43
  86. package/dist/types/index.d.cts.map +1 -1
  87. package/dist/types/index.d.mts +7 -43
  88. package/dist/types/index.d.mts.map +1 -1
  89. package/dist/types/index.mjs.map +1 -1
  90. package/dist/utils/marketUtils.cjs +1 -16
  91. package/dist/utils/marketUtils.cjs.map +1 -1
  92. package/dist/utils/marketUtils.d.cts +0 -1
  93. package/dist/utils/marketUtils.d.cts.map +1 -1
  94. package/dist/utils/marketUtils.d.mts +0 -1
  95. package/dist/utils/marketUtils.d.mts.map +1 -1
  96. package/dist/utils/marketUtils.mjs +0 -14
  97. package/dist/utils/marketUtils.mjs.map +1 -1
  98. package/dist/utils/perpsDiskPersistence.cjs +12 -19
  99. package/dist/utils/perpsDiskPersistence.cjs.map +1 -1
  100. package/dist/utils/perpsDiskPersistence.d.cts +1 -5
  101. package/dist/utils/perpsDiskPersistence.d.cts.map +1 -1
  102. package/dist/utils/perpsDiskPersistence.d.mts +1 -5
  103. package/dist/utils/perpsDiskPersistence.d.mts.map +1 -1
  104. package/dist/utils/perpsDiskPersistence.mjs +12 -19
  105. package/dist/utils/perpsDiskPersistence.mjs.map +1 -1
  106. package/package.json +1 -1
@@ -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_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;
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;
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,36 +41,6 @@ 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
- }
74
44
  /**
75
45
  * Returns the first non-empty string from the given values.
76
46
  * Env vars default to '' (not null/undefined), so ?? wouldn't fall through.
@@ -441,7 +411,6 @@ const MESSENGER_EXPOSED_METHODS = [
441
411
  'getBlockExplorerUrl',
442
412
  'getCachedMarketDataForActiveProvider',
443
413
  'getCachedUserDataForActiveProvider',
444
- 'getUserDataSnapshot',
445
414
  'getCurrentNetwork',
446
415
  'getFunding',
447
416
  'getHistoricalPortfolio',
@@ -574,7 +543,6 @@ class PerpsController extends base_controller_1.BaseController {
574
543
  _PerpsController_handlersRegistered.set(this, false);
575
544
  _PerpsController_standaloneProviderIsTestnet.set(this, null);
576
545
  _PerpsController_standaloneProviderHip3Version.set(this, null);
577
- _PerpsController_standaloneProviderOperations.set(this, new Map());
578
546
  _PerpsController_eligibilityCheckDeferred.set(this, void 0);
579
547
  /**
580
548
  * Serial promise queue for all AUS watchlist operations (hydration and
@@ -590,7 +558,6 @@ class PerpsController extends base_controller_1.BaseController {
590
558
  * a failed operation does not stall subsequent ones.
591
559
  */
592
560
  _PerpsController_ausQueue.set(this, Promise.resolve());
593
- _PerpsController_userDiskWrite.set(this, Promise.resolve());
594
561
  // Store options for dependency injection (allows core package to inject platform-specific services)
595
562
  _PerpsController_options.set(this, void 0);
596
563
  // Service instances (instantiated with platform dependencies)
@@ -604,10 +571,7 @@ class PerpsController extends base_controller_1.BaseController {
604
571
  _PerpsController_rewardsIntegrationService.set(this, void 0);
605
572
  _PerpsController_preloadTimer.set(this, null);
606
573
  _PerpsController_isPreloading.set(this, false);
607
- _PerpsController_marketPreloadQueued.set(this, false);
608
574
  _PerpsController_isPreloadingUserData.set(this, false);
609
- _PerpsController_userPreloadQueued.set(this, false);
610
- _PerpsController_userSnapshotRequests.set(this, new Map());
611
575
  _PerpsController_preloadStateUnsubscribe.set(this, null);
612
576
  _PerpsController_accountChangeUnsubscribe.set(this, null);
613
577
  _PerpsController_previousIsTestnet.set(this, null);
@@ -626,9 +590,7 @@ class PerpsController extends base_controller_1.BaseController {
626
590
  __classPrivateFieldSet(this, _PerpsController_marketDataService, new MarketDataService_js_1.MarketDataService({
627
591
  ...infrastructure,
628
592
  terminalMarketService: infrastructure.terminalMarketService ??
629
- (infrastructure.terminalApi?.marketDataUrl ||
630
- infrastructure.terminalApiUrl ||
631
- infrastructure.terminalApi?.globalSnapshotUrl
593
+ (infrastructure.terminalApiUrl
632
594
  ? new TerminalMarketService_js_1.TerminalMarketService(infrastructure)
633
595
  : undefined),
634
596
  }), "f");
@@ -695,20 +657,24 @@ class PerpsController extends base_controller_1.BaseController {
695
657
  if (activeProvider === 'aggregated') {
696
658
  // Assemble from all registered provider entries
697
659
  const assembled = [];
660
+ let oldestTimestamp = Infinity;
698
661
  for (const providerId of __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getAggregatedCacheProviderIds).call(this, Object.keys(cache))) {
699
662
  const key = (0, perpsConfig_js_1.buildProviderCacheKey)(providerId, this.state.isTestnet);
700
663
  const entry = cache[key];
701
664
  if (!entry || entry.data.length === 0) {
702
665
  continue;
703
666
  }
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));
667
+ oldestTimestamp = Math.min(oldestTimestamp, entry.timestamp);
668
+ assembled.push(...entry.data);
708
669
  }
709
670
  if (assembled.length === 0) {
710
671
  return null;
711
672
  }
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
+ }
712
678
  return assembled;
713
679
  }
714
680
  // Single provider mode
@@ -717,10 +683,11 @@ class PerpsController extends base_controller_1.BaseController {
717
683
  if (!entry || entry.data.length === 0) {
718
684
  return null;
719
685
  }
720
- if (!__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_isMarketCacheEntryCurrent).call(this, activeProvider, entry, options)) {
686
+ if (!options?.skipTTL &&
687
+ Date.now() - entry.timestamp > __classPrivateFieldGet(_a, _a, "f", _PerpsController_preloadGuardMs) * 10) {
721
688
  return null;
722
689
  }
723
- return (0, marketUtils_js_1.clonePerpsMarketData)(entry.data);
690
+ return entry.data;
724
691
  }
725
692
  /**
726
693
  * Read cached user data for the currently active provider (or aggregated).
@@ -744,21 +711,18 @@ class PerpsController extends base_controller_1.BaseController {
744
711
  currentAddress = evmAccount?.address ?? null;
745
712
  }
746
713
  catch {
747
- // Account identity is required before account-scoped data can be trusted.
714
+ // Can't determine current account — trust the cache
748
715
  }
749
- if (!currentAddress) {
750
- return null;
751
- }
752
- const selectedAddress = currentAddress;
753
716
  const skipTTL = options?.skipTTL ?? false;
754
- const isValidEntry = (providerId, entry) => {
717
+ const isValidEntry = (entry) => {
755
718
  if (!entry) {
756
719
  return false;
757
720
  }
758
721
  if (!skipTTL && Date.now() - entry.timestamp >= staleCutoff) {
759
722
  return false;
760
723
  }
761
- if (!__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_isUserCacheIdentityCurrent).call(this, providerId, entry, selectedAddress)) {
724
+ if (currentAddress &&
725
+ entry.address.toLowerCase() !== currentAddress.toLowerCase()) {
762
726
  return false;
763
727
  }
764
728
  return true;
@@ -770,9 +734,9 @@ class PerpsController extends base_controller_1.BaseController {
770
734
  let defaultAccountState = null;
771
735
  let hasValidEntry = false;
772
736
  for (const providerId of __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getAggregatedCacheProviderIds).call(this, Object.keys(cache))) {
773
- const providerNetworkKey = (0, perpsConfig_js_1.buildProviderCacheKey)(providerId, this.state.isTestnet);
774
- const entry = cache[providerNetworkKey];
775
- if (!isValidEntry(providerId, entry)) {
737
+ const key = (0, perpsConfig_js_1.buildProviderCacheKey)(providerId, this.state.isTestnet);
738
+ const entry = cache[key];
739
+ if (!isValidEntry(entry)) {
776
740
  continue;
777
741
  }
778
742
  hasValidEntry = true;
@@ -793,9 +757,9 @@ class PerpsController extends base_controller_1.BaseController {
793
757
  };
794
758
  }
795
759
  // Single provider mode
796
- const providerNetworkKey = (0, perpsConfig_js_1.buildProviderCacheKey)(activeProvider, this.state.isTestnet);
797
- const entry = cache[providerNetworkKey];
798
- if (!entry || !isValidEntry(activeProvider, entry)) {
760
+ const key = (0, perpsConfig_js_1.buildProviderCacheKey)(activeProvider, this.state.isTestnet);
761
+ const entry = cache[key];
762
+ if (!entry || !isValidEntry(entry)) {
799
763
  return null;
800
764
  }
801
765
  return {
@@ -804,82 +768,6 @@ class PerpsController extends base_controller_1.BaseController {
804
768
  accountState: entry.accountState,
805
769
  };
806
770
  }
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
- }
883
771
  /**
884
772
  * Test-observable accessor for whether a standalone provider is cached.
885
773
  *
@@ -1655,10 +1543,7 @@ class PerpsController extends base_controller_1.BaseController {
1655
1543
  // Fallback to cached standalone provider for pre-initialization discovery
1656
1544
  // TODO: When adding new providers (MYX), consider a provider factory pattern
1657
1545
  const provider = this.activeProviderInstance ?? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getOrCreateStandaloneProvider).call(this);
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;
1546
+ return provider.getPositions(params);
1662
1547
  }
1663
1548
  const provider = this.getActiveProvider();
1664
1549
  return __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getPositions({
@@ -1719,10 +1604,7 @@ class PerpsController extends base_controller_1.BaseController {
1719
1604
  // For standalone mode, access provider directly without initialization check
1720
1605
  if (params?.standalone && params.userAddress) {
1721
1606
  const provider = this.activeProviderInstance ?? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getOrCreateStandaloneProvider).call(this);
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;
1607
+ return provider.getOpenOrders(params);
1726
1608
  }
1727
1609
  const provider = this.getActiveProvider();
1728
1610
  return __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getOpenOrders({
@@ -1767,10 +1649,7 @@ class PerpsController extends base_controller_1.BaseController {
1767
1649
  // Use activeProviderInstance if available (respects provider abstraction)
1768
1650
  // Fallback to cached standalone provider for pre-initialization discovery
1769
1651
  const provider = this.activeProviderInstance ?? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getOrCreateStandaloneProvider).call(this);
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;
1652
+ return provider.getAccountState(params);
1774
1653
  }
1775
1654
  const provider = this.getActiveProvider();
1776
1655
  return __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getAccountState({
@@ -1808,15 +1687,12 @@ class PerpsController extends base_controller_1.BaseController {
1808
1687
  const isMarketAllowed = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_buildMarketAllowedFilter).call(this);
1809
1688
  if (params?.standalone) {
1810
1689
  const provider = this.activeProviderInstance ?? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getOrCreateStandaloneProvider).call(this);
1811
- const operation = __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getMarkets({
1690
+ return __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getMarkets({
1812
1691
  provider,
1813
1692
  params,
1814
1693
  context: __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_createServiceContext).call(this, 'getMarkets'),
1815
1694
  isMarketAllowed,
1816
1695
  });
1817
- return provider === __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f")
1818
- ? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_trackStandaloneProviderOperation).call(this, provider, operation)
1819
- : operation;
1820
1696
  }
1821
1697
  const provider = this.getActiveProvider();
1822
1698
  return __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getMarkets({
@@ -1842,26 +1718,19 @@ class PerpsController extends base_controller_1.BaseController {
1842
1718
  * @returns A promise that resolves to the market data.
1843
1719
  */
1844
1720
  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
- });
1849
1721
  if (params?.standalone) {
1850
1722
  const provider = this.activeProviderInstance ?? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getOrCreateStandaloneProvider).call(this);
1851
- const operation = __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getMarketDataWithPrices({
1723
+ return __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getMarketDataWithPrices({
1852
1724
  provider,
1853
1725
  params,
1854
- context,
1726
+ context: __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_createServiceContext).call(this, 'getMarketDataWithPrices'),
1855
1727
  });
1856
- return provider === __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f")
1857
- ? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_trackStandaloneProviderOperation).call(this, provider, operation)
1858
- : operation;
1859
1728
  }
1860
1729
  const provider = this.getActiveProvider();
1861
1730
  return __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").getMarketDataWithPrices({
1862
1731
  provider,
1863
1732
  params,
1864
- context,
1733
+ context: __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_createServiceContext).call(this, 'getMarketDataWithPrices'),
1865
1734
  });
1866
1735
  }
1867
1736
  /**
@@ -1882,17 +1751,11 @@ class PerpsController extends base_controller_1.BaseController {
1882
1751
  __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performMarketDataPreload).call(this).catch(() => {
1883
1752
  /* fire-and-forget */
1884
1753
  });
1885
- __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
1886
- /* fire-and-forget */
1887
- });
1888
1754
  // Periodic refresh
1889
1755
  __classPrivateFieldSet(this, _PerpsController_preloadTimer, setInterval(() => {
1890
1756
  __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performMarketDataPreload).call(this).catch(() => {
1891
1757
  /* fire-and-forget */
1892
1758
  });
1893
- __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
1894
- /* fire-and-forget */
1895
- });
1896
1759
  }, __classPrivateFieldGet(_a, _a, "f", _PerpsController_preloadRefreshMs)), "f");
1897
1760
  // Watch for isTestnet / hip3ConfigVersion changes
1898
1761
  const handler = (_state, patches) => {
@@ -1921,29 +1784,36 @@ class PerpsController extends base_controller_1.BaseController {
1921
1784
  __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performMarketDataPreload).call(this).catch(() => {
1922
1785
  /* fire-and-forget */
1923
1786
  });
1924
- __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
1925
- /* fire-and-forget */
1926
- });
1927
1787
  }
1928
1788
  };
1929
- this.messenger.subscribe('PerpsController:stateChanged', handler);
1789
+ this.messenger.subscribe('PerpsController:stateChange', handler);
1930
1790
  __classPrivateFieldSet(this, _PerpsController_preloadStateUnsubscribe, () => {
1931
- this.messenger.unsubscribe('PerpsController:stateChanged', handler);
1791
+ this.messenger.unsubscribe('PerpsController:stateChange', handler);
1932
1792
  }, "f");
1933
1793
  // Watch for selected account changes and selected account group changes.
1934
1794
  const accountChangeHandler = () => {
1935
1795
  const evmAccount = (0, accountUtils_js_1.getSelectedEvmAccountFromMessenger)(this.messenger);
1936
1796
  const currentAddress = evmAccount?.address ?? null;
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(() => {
1797
+ // If any cached entry belongs to a different account, clear all entries.
1798
+ // Max 4 entries (2 providers × 2 networks) — clearing all is simple and safe.
1799
+ const hasStaleEntries = Object.values(this.state.cachedUserDataByProvider).some((entry) => entry.address.toLowerCase() !== currentAddress?.toLowerCase());
1800
+ if (hasStaleEntries) {
1801
+ __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Account changed, clearing user data cache');
1802
+ this.update((state) => {
1803
+ state.cachedUserDataByProvider = {};
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(() => {
1945
1809
  /* fire-and-forget */
1946
1810
  });
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
+ }
1947
1817
  }
1948
1818
  };
1949
1819
  this.messenger.subscribe('AccountsController:selectedAccountChange', accountChangeHandler);
@@ -1972,8 +1842,6 @@ class PerpsController extends base_controller_1.BaseController {
1972
1842
  }
1973
1843
  __classPrivateFieldSet(this, _PerpsController_previousIsTestnet, null, "f");
1974
1844
  __classPrivateFieldSet(this, _PerpsController_previousHip3ConfigVersion, null, "f");
1975
- __classPrivateFieldSet(this, _PerpsController_marketPreloadQueued, false, "f");
1976
- __classPrivateFieldSet(this, _PerpsController_userPreloadQueued, false, "f");
1977
1845
  __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_cleanupStandaloneProvider).call(this).catch(() => {
1978
1846
  /* fire-and-forget to preserve sync signature */
1979
1847
  });
@@ -2234,9 +2102,6 @@ class PerpsController extends base_controller_1.BaseController {
2234
2102
  __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performMarketDataPreload).call(this).catch(() => {
2235
2103
  /* fire-and-forget */
2236
2104
  });
2237
- __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
2238
- /* fire-and-forget */
2239
- });
2240
2105
  }
2241
2106
  }
2242
2107
  }
@@ -2346,9 +2211,6 @@ class PerpsController extends base_controller_1.BaseController {
2346
2211
  __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performMarketDataPreload).call(this).catch(() => {
2347
2212
  /* fire-and-forget */
2348
2213
  });
2349
- __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performUserDataPreload).call(this).catch(() => {
2350
- /* fire-and-forget */
2351
- });
2352
2214
  }
2353
2215
  }
2354
2216
  }
@@ -3412,7 +3274,7 @@ class PerpsController extends base_controller_1.BaseController {
3412
3274
  }
3413
3275
  }
3414
3276
  exports.PerpsController = PerpsController;
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() {
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() {
3416
3278
  const myx = __classPrivateFieldGet(this, _PerpsController_options, "f").clientConfig?.providerCredentials?.myx;
3417
3279
  // Local env-var override (MM_PERPS_MYX_PROVIDER_ENABLED) always wins —
3418
3280
  // matches the UI selector (resolvePerpsMyxProviderEnabled) so controller
@@ -3465,96 +3327,6 @@ _a = PerpsController, _PerpsController_initializationPromise = new WeakMap(), _P
3465
3327
  }
3466
3328
  }
3467
3329
  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;
3558
3330
  }, _PerpsController_getOrCreateStandaloneProvider = function _PerpsController_getOrCreateStandaloneProvider() {
3559
3331
  const currentIsTestnet = this.state.isTestnet;
3560
3332
  const currentHip3Version = this.state.hip3ConfigVersion ?? 0;
@@ -3563,13 +3335,10 @@ _a = PerpsController, _PerpsController_initializationPromise = new WeakMap(), _P
3563
3335
  __classPrivateFieldGet(this, _PerpsController_standaloneProviderHip3Version, "f") === currentHip3Version) {
3564
3336
  return __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f");
3565
3337
  }
3566
- // Stale or missing — retire the old provider after active operations finish.
3338
+ // Stale or missing — tear down old one (fire-and-forget)
3567
3339
  if (__classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f")) {
3568
3340
  const old = __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f");
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(() => {
3341
+ Promise.resolve(old.disconnect()).catch(() => {
3573
3342
  /* best-effort */
3574
3343
  });
3575
3344
  }
@@ -3589,45 +3358,24 @@ _a = PerpsController, _PerpsController_initializationPromise = new WeakMap(), _P
3589
3358
  __classPrivateFieldSet(this, _PerpsController_standaloneProviderIsTestnet, currentIsTestnet, "f");
3590
3359
  __classPrivateFieldSet(this, _PerpsController_standaloneProviderHip3Version, currentHip3Version, "f");
3591
3360
  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
- }
3617
3361
  }, _PerpsController_cleanupStandaloneProvider =
3618
3362
  /**
3619
3363
  * Disconnect and discard the cached standalone provider (if any).
3620
3364
  * Best-effort — errors are silently caught.
3621
3365
  */
3622
3366
  async function _PerpsController_cleanupStandaloneProvider() {
3623
- const provider = __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f");
3624
- if (!provider) {
3367
+ if (!__classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f")) {
3625
3368
  return;
3626
3369
  }
3370
+ try {
3371
+ await __classPrivateFieldGet(this, _PerpsController_standaloneProvider, "f").disconnect();
3372
+ }
3373
+ catch {
3374
+ /* best-effort */
3375
+ }
3627
3376
  __classPrivateFieldSet(this, _PerpsController_standaloneProvider, null, "f");
3628
3377
  __classPrivateFieldSet(this, _PerpsController_standaloneProviderIsTestnet, null, "f");
3629
3378
  __classPrivateFieldSet(this, _PerpsController_standaloneProviderHip3Version, null, "f");
3630
- await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_retireStandaloneProvider).call(this, provider);
3631
3379
  }, _PerpsController_getMetrics = function _PerpsController_getMetrics() {
3632
3380
  return __classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.metrics;
3633
3381
  }, _PerpsController_findNetworkClientIdForChain = function _PerpsController_findNetworkClientIdForChain(chainId) {
@@ -3961,60 +3709,6 @@ async function _PerpsController_performInitialization() {
3961
3709
  __classPrivateFieldGet(this, _PerpsController_tradingService, "f").setControllerDependencies({
3962
3710
  rewardsIntegrationService: __classPrivateFieldGet(this, _PerpsController_rewardsIntegrationService, "f"),
3963
3711
  });
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);
4018
3712
  }, _PerpsController_hydrateCacheFromDiskSync = function _PerpsController_hydrateCacheFromDiskSync() {
4019
3713
  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));
4020
3714
  const hasMarketUpdates = Object.keys(marketUpdates).length > 0;
@@ -4035,40 +3729,12 @@ async function _PerpsController_performInitialization() {
4035
3729
  orders: stats.userOrders,
4036
3730
  duration_ms: stats.durationMs,
4037
3731
  });
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");
4065
3732
  }, _PerpsController_performMarketDataPreload =
4066
3733
  /**
4067
3734
  * Perform a single market data preload (best-effort, no throw).
4068
3735
  */
4069
3736
  async function _PerpsController_performMarketDataPreload() {
4070
3737
  if (__classPrivateFieldGet(this, _PerpsController_isPreloading, "f")) {
4071
- __classPrivateFieldSet(this, _PerpsController_marketPreloadQueued, true, "f");
4072
3738
  return;
4073
3739
  }
4074
3740
  // Skip preloading during provider/network reinitialisation.
@@ -4083,16 +3749,9 @@ async function _PerpsController_performMarketDataPreload() {
4083
3749
  ? this.state.activeProvider // includes 'aggregated'
4084
3750
  : 'hyperliquid';
4085
3751
  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);
4092
3752
  const now = Date.now();
4093
3753
  const existingEntry = this.state.cachedMarketDataByProvider[cacheKey];
4094
3754
  if (existingEntry &&
4095
- __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_isMarketCacheEntryCurrent).call(this, actualProviderId, existingEntry) &&
4096
3755
  now - existingEntry.timestamp < __classPrivateFieldGet(_a, _a, "f", _PerpsController_preloadGuardMs)) {
4097
3756
  return;
4098
3757
  }
@@ -4117,32 +3776,8 @@ async function _PerpsController_performMarketDataPreload() {
4117
3776
  duration_ms: Math.round(performance.now() - preloadStart),
4118
3777
  markets: data.length,
4119
3778
  });
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
- }
4130
3779
  // Store under per-provider key(s)
4131
3780
  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
- : {};
4146
3781
  const marketDiskEntries = [];
4147
3782
  if (this.state.activeProvider === 'aggregated' &&
4148
3783
  this.activeProviderInstance) {
@@ -4189,7 +3824,6 @@ async function _PerpsController_performMarketDataPreload() {
4189
3824
  state.cachedMarketDataByProvider[cacheKey] = {
4190
3825
  data,
4191
3826
  timestamp: ts,
4192
- ...snapshotCacheIdentity,
4193
3827
  };
4194
3828
  });
4195
3829
  }
@@ -4199,6 +3833,10 @@ async function _PerpsController_performMarketDataPreload() {
4199
3833
  });
4200
3834
  traceData = { success: true, marketCount: data.length };
4201
3835
  __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
+ });
4202
3840
  }
4203
3841
  catch (error) {
4204
3842
  traceData = {
@@ -4217,12 +3855,6 @@ async function _PerpsController_performMarketDataPreload() {
4217
3855
  data: traceData,
4218
3856
  });
4219
3857
  __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
- }
4226
3858
  }
4227
3859
  }, _PerpsController_performUserDataPreload =
4228
3860
  /**
@@ -4231,10 +3863,6 @@ async function _PerpsController_performMarketDataPreload() {
4231
3863
  */
4232
3864
  async function _PerpsController_performUserDataPreload() {
4233
3865
  if (__classPrivateFieldGet(this, _PerpsController_isPreloadingUserData, "f")) {
4234
- __classPrivateFieldSet(this, _PerpsController_userPreloadQueued, true, "f");
4235
- return;
4236
- }
4237
- if (__classPrivateFieldGet(this, _PerpsController_isReinitializing, "f")) {
4238
3866
  return;
4239
3867
  }
4240
3868
  // Get current user address
@@ -4243,54 +3871,21 @@ async function _PerpsController_performUserDataPreload() {
4243
3871
  return;
4244
3872
  }
4245
3873
  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
- };
4263
3874
  // Determine actual provider (same logic as market preload)
4264
- const actualProviderId = activeProviderInstance
4265
- ? activeProvider // includes 'aggregated'
3875
+ const actualProviderId = this.activeProviderInstance
3876
+ ? this.state.activeProvider // includes 'aggregated'
4266
3877
  : 'hyperliquid';
4267
- const providerNetworkKey = (0, perpsConfig_js_1.buildProviderCacheKey)(actualProviderId, isTestnet);
3878
+ const userCacheKey = (0, perpsConfig_js_1.buildProviderCacheKey)(actualProviderId, this.state.isTestnet);
4268
3879
  // Skip if cache is fresh and for same account
4269
3880
  const now = Date.now();
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 &&
3881
+ const existingEntry = this.state.cachedUserDataByProvider[userCacheKey];
3882
+ if (existingEntry?.address === userAddress &&
4289
3883
  now - existingEntry.timestamp < __classPrivateFieldGet(_a, _a, "f", _PerpsController_preloadGuardMs)) {
4290
3884
  return;
4291
3885
  }
4292
- if (hasMatchingCache &&
4293
- this.getWebSocketConnectionState() === index_js_1.WebSocketConnectionState.Connected) {
3886
+ // Skip standalone REST polling when WebSocket is connected — live data is streaming
3887
+ if (this.getWebSocketConnectionState() === index_js_1.WebSocketConnectionState.Connected) {
3888
+ __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Skipping user data preload — WebSocket connected');
4294
3889
  return;
4295
3890
  }
4296
3891
  __classPrivateFieldSet(this, _PerpsController_isPreloadingUserData, true, "f");
@@ -4303,38 +3898,21 @@ async function _PerpsController_performUserDataPreload() {
4303
3898
  id: traceId,
4304
3899
  op: index_js_1.PerpsTraceOperations.Operation,
4305
3900
  tags: {
4306
- provider: activeProvider,
4307
- isTestnet,
3901
+ provider: this.state.activeProvider,
3902
+ isTestnet: this.state.isTestnet,
4308
3903
  },
4309
3904
  data: { userAddress },
4310
3905
  });
4311
3906
  __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Fetching user data in background', {
4312
3907
  userAddress,
4313
3908
  });
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
- }
4329
3909
  const [positions, orders, accountState] = await Promise.all([
4330
3910
  this.getPositions({ standalone: true, userAddress }),
4331
3911
  this.getOpenOrders({ standalone: true, userAddress }),
4332
3912
  this.getAccountState({ standalone: true, userAddress }),
4333
3913
  ]);
4334
- if (!isCurrent()) {
4335
- throw new Error('User data preload context changed');
4336
- }
4337
- if (activeProvider === 'aggregated' && activeProviderInstance) {
3914
+ if (this.state.activeProvider === 'aggregated' &&
3915
+ this.activeProviderInstance) {
4338
3916
  // Split by providerId and write one cache entry per provider key
4339
3917
  // (mirrors the market-data preload pattern at ~line 2976)
4340
3918
  const ts = Date.now();
@@ -4356,22 +3934,26 @@ async function _PerpsController_performUserDataPreload() {
4356
3934
  }
4357
3935
  // AccountState — assign to its provider bucket
4358
3936
  ensureBucket(accountState.providerId ?? fallbackProviderId).accountState = accountState;
3937
+ const diskEntries = [];
4359
3938
  this.update((state) => {
4360
3939
  for (const [pid, data] of byProvider) {
4361
- const key = (0, perpsConfig_js_1.buildProviderCacheKey)(pid, isTestnet);
3940
+ const key = (0, perpsConfig_js_1.buildProviderCacheKey)(pid, this.state.isTestnet);
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
+ });
4362
3949
  state.cachedUserDataByProvider[key] = {
4363
3950
  ...data,
4364
3951
  timestamp: ts,
4365
3952
  address: userAddress,
4366
- ...(pid === 'hyperliquid' &&
4367
- hyperliquidDexes && {
4368
- hip3ConfigVersion,
4369
- dexes: hyperliquidDexes,
4370
- }),
4371
3953
  };
4372
3954
  }
4373
3955
  // Write aggregated sentinel so the staleness guard sees it
4374
- state.cachedUserDataByProvider[providerNetworkKey] = {
3956
+ state.cachedUserDataByProvider[userCacheKey] = {
4375
3957
  positions: [],
4376
3958
  orders: [],
4377
3959
  accountState: null,
@@ -4379,26 +3961,30 @@ async function _PerpsController_performUserDataPreload() {
4379
3961
  address: userAddress,
4380
3962
  };
4381
3963
  });
4382
- __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_persistUserCacheToDisk).call(this);
3964
+ (0, perpsDiskPersistence_js_1.persistUserEntriesToDisk)(__classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.diskCache, diskEntries);
4383
3965
  }
4384
3966
  else {
4385
3967
  // Single provider — store directly under its key
4386
3968
  const ts = Date.now();
4387
3969
  this.update((state) => {
4388
- state.cachedUserDataByProvider[providerNetworkKey] = {
3970
+ state.cachedUserDataByProvider[userCacheKey] = {
4389
3971
  positions,
4390
3972
  orders,
4391
3973
  accountState,
4392
3974
  timestamp: ts,
4393
3975
  address: userAddress,
4394
- ...(actualProviderId === 'hyperliquid' &&
4395
- hyperliquidDexes && {
4396
- hip3ConfigVersion,
4397
- dexes: hyperliquidDexes,
4398
- }),
4399
3976
  };
4400
3977
  });
4401
- __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_persistUserCacheToDisk).call(this);
3978
+ (0, perpsDiskPersistence_js_1.persistUserEntriesToDisk)(__classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.diskCache, [
3979
+ {
3980
+ providerNetworkKey: userCacheKey,
3981
+ address: userAddress,
3982
+ positions,
3983
+ orders,
3984
+ accountState,
3985
+ timestamp: ts,
3986
+ },
3987
+ ]);
4402
3988
  }
4403
3989
  __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: User data preloaded', {
4404
3990
  positionCount: positions.length,
@@ -4429,12 +4015,6 @@ async function _PerpsController_performUserDataPreload() {
4429
4015
  data: traceData,
4430
4016
  });
4431
4017
  __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
- }
4438
4018
  }
4439
4019
  }, _PerpsController_persistWatchlistToRemote =
4440
4020
  /**