@metamask-previews/perps-controller 12.2.0-preview-e68ab1498 → 13.0.0-preview-4b37525
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 +15 -6
- package/dist/PerpsController-method-action-types.cjs.map +1 -1
- package/dist/PerpsController-method-action-types.d.cts +26 -3
- package/dist/PerpsController-method-action-types.d.cts.map +1 -1
- package/dist/PerpsController-method-action-types.d.mts +26 -3
- 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 +392 -102
- package/dist/PerpsController.cjs.map +1 -1
- package/dist/PerpsController.d.cts +26 -7
- package/dist/PerpsController.d.cts.map +1 -1
- package/dist/PerpsController.d.mts +26 -7
- package/dist/PerpsController.d.mts.map +1 -1
- package/dist/PerpsController.mjs +392 -102
- package/dist/PerpsController.mjs.map +1 -1
- package/dist/constants/eventNames.cjs +1 -1
- package/dist/constants/eventNames.cjs.map +1 -1
- package/dist/constants/eventNames.d.cts +1 -1
- package/dist/constants/eventNames.d.mts +1 -1
- package/dist/constants/eventNames.mjs +1 -1
- 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 +10 -0
- package/dist/constants/hyperLiquidConfig.d.cts.map +1 -1
- package/dist/constants/hyperLiquidConfig.d.mts +10 -0
- package/dist/constants/hyperLiquidConfig.d.mts.map +1 -1
- package/dist/constants/hyperLiquidConfig.mjs +12 -0
- package/dist/constants/hyperLiquidConfig.mjs.map +1 -1
- package/dist/constants/perpsConfig.cjs +3 -4
- package/dist/constants/perpsConfig.cjs.map +1 -1
- package/dist/constants/perpsConfig.d.cts +2 -4
- package/dist/constants/perpsConfig.d.cts.map +1 -1
- package/dist/constants/perpsConfig.d.mts +2 -4
- package/dist/constants/perpsConfig.d.mts.map +1 -1
- package/dist/constants/perpsConfig.mjs +3 -4
- package/dist/constants/perpsConfig.mjs.map +1 -1
- package/dist/index.cjs +8 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +4 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -1
- package/dist/perpsErrorCodes.cjs +5 -1
- package/dist/perpsErrorCodes.cjs.map +1 -1
- package/dist/perpsErrorCodes.d.cts +4 -0
- package/dist/perpsErrorCodes.d.cts.map +1 -1
- package/dist/perpsErrorCodes.d.mts +4 -0
- package/dist/perpsErrorCodes.d.mts.map +1 -1
- package/dist/perpsErrorCodes.mjs +5 -1
- package/dist/perpsErrorCodes.mjs.map +1 -1
- package/dist/providers/AggregatedPerpsProvider.cjs +104 -14
- package/dist/providers/AggregatedPerpsProvider.cjs.map +1 -1
- package/dist/providers/AggregatedPerpsProvider.d.cts +34 -2
- package/dist/providers/AggregatedPerpsProvider.d.cts.map +1 -1
- package/dist/providers/AggregatedPerpsProvider.d.mts +34 -2
- package/dist/providers/AggregatedPerpsProvider.d.mts.map +1 -1
- package/dist/providers/AggregatedPerpsProvider.mjs +102 -13
- package/dist/providers/AggregatedPerpsProvider.mjs.map +1 -1
- package/dist/providers/HyperLiquidProvider.cjs +2141 -637
- package/dist/providers/HyperLiquidProvider.cjs.map +1 -1
- package/dist/providers/HyperLiquidProvider.d.cts +37 -17
- package/dist/providers/HyperLiquidProvider.d.cts.map +1 -1
- package/dist/providers/HyperLiquidProvider.d.mts +37 -17
- package/dist/providers/HyperLiquidProvider.d.mts.map +1 -1
- package/dist/providers/HyperLiquidProvider.mjs +2146 -642
- package/dist/providers/HyperLiquidProvider.mjs.map +1 -1
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.cts +96 -3
- package/dist/types/index.d.cts.map +1 -1
- package/dist/types/index.d.mts +96 -3
- package/dist/types/index.d.mts.map +1 -1
- package/dist/types/index.mjs.map +1 -1
- package/dist/utils/capabilitySymbols.cjs +25 -0
- package/dist/utils/capabilitySymbols.cjs.map +1 -0
- package/dist/utils/capabilitySymbols.d.cts +15 -0
- package/dist/utils/capabilitySymbols.d.cts.map +1 -0
- package/dist/utils/capabilitySymbols.d.mts +15 -0
- package/dist/utils/capabilitySymbols.d.mts.map +1 -0
- package/dist/utils/capabilitySymbols.mjs +21 -0
- package/dist/utils/capabilitySymbols.mjs.map +1 -0
- package/dist/utils/hyperLiquidAdapter.cjs +20 -1
- package/dist/utils/hyperLiquidAdapter.cjs.map +1 -1
- package/dist/utils/hyperLiquidAdapter.d.cts +1 -0
- package/dist/utils/hyperLiquidAdapter.d.cts.map +1 -1
- package/dist/utils/hyperLiquidAdapter.d.mts +1 -0
- package/dist/utils/hyperLiquidAdapter.d.mts.map +1 -1
- package/dist/utils/hyperLiquidAdapter.mjs +19 -0
- package/dist/utils/hyperLiquidAdapter.mjs.map +1 -1
- package/dist/utils/hyperLiquidValidation.cjs +1 -1
- package/dist/utils/hyperLiquidValidation.cjs.map +1 -1
- package/dist/utils/hyperLiquidValidation.d.cts +1 -1
- package/dist/utils/hyperLiquidValidation.d.mts +1 -1
- package/dist/utils/hyperLiquidValidation.mjs +1 -1
- package/dist/utils/hyperLiquidValidation.mjs.map +1 -1
- package/dist/utils/stringParseUtils.cjs +17 -1
- package/dist/utils/stringParseUtils.cjs.map +1 -1
- package/dist/utils/stringParseUtils.d.cts +8 -0
- package/dist/utils/stringParseUtils.d.cts.map +1 -1
- package/dist/utils/stringParseUtils.d.mts +8 -0
- package/dist/utils/stringParseUtils.d.mts.map +1 -1
- package/dist/utils/stringParseUtils.mjs +15 -0
- package/dist/utils/stringParseUtils.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_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,
|
|
13
|
+
var _PerpsController_instances, _a, _PerpsController_initializationPromise, _PerpsController_isReinitializing, _PerpsController_reinitializationOperationPromise, _PerpsController_disconnectOperationPromise, _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_publishChaseOrderMaxDistanceReached, _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_initWithoutDisconnectWait, _PerpsController_beginReinitialization, _PerpsController_performInitialization, _PerpsController_createProviders, _PerpsController_assignActiveProvider, _PerpsController_getErrorContext, _PerpsController_getControllerState, _PerpsController_buildMarketAllowedFilter, _PerpsController_compilePatternsSafely, _PerpsController_createServiceContext, _PerpsController_ensureTradingServiceDeps, _PerpsController_getActiveProviderWhenReady, _PerpsController_getUnavailableOrderCapabilities, _PerpsController_getDirectProviderId, _PerpsController_hasConflictingProviderRoute, _PerpsController_resolveRoutedOrderProvider, _PerpsController_buildGlobalSnapshotContext, _PerpsController_getStaticSnapshotDexes, _PerpsController_preloadWatchedPaths, _PerpsController_preloadTimer, _PerpsController_preloadStartRequested, _PerpsController_isPreloading, _PerpsController_marketPreloadQueued, _PerpsController_isPreloadingUserData, _PerpsController_userPreloadQueued, _PerpsController_lifecycleGeneration, _PerpsController_userSnapshotRequests, _PerpsController_preloadStateUnsubscribe, _PerpsController_accountChangeUnsubscribe, _PerpsController_previousIsTestnet, _PerpsController_previousHip3ConfigVersion, _PerpsController_preloadRefreshMs, _PerpsController_preloadGuardMs, _PerpsController_hydrateCacheFromDiskSync, _PerpsController_persistUserCacheToDisk, _PerpsController_performMarketDataPreload, _PerpsController_performUserDataPreload, _PerpsController_performDisconnect, _PerpsController_persistWatchlistToRemote, _PerpsController_syncWatchlistFromRemote;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.PerpsController = exports.getDefaultPerpsControllerState = exports.DEFAULT_SELECTED_ORDER_TYPE = exports.DEFAULT_PRO_LAYOUT_PREFERENCES = exports.DEFAULT_PERPS_MODE = exports.DEFAULT_ORDER_BOOK_PREFERENCES = 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");
|
|
@@ -39,6 +39,7 @@ const accountUtils_js_1 = require("./utils/accountUtils.cjs");
|
|
|
39
39
|
const errorUtils_js_1 = require("./utils/errorUtils.cjs");
|
|
40
40
|
const hyperLiquidAdapter_js_1 = require("./utils/hyperLiquidAdapter.cjs");
|
|
41
41
|
const marketUtils_js_1 = require("./utils/marketUtils.cjs");
|
|
42
|
+
const orderTypes_js_1 = require("./utils/orderTypes.cjs");
|
|
42
43
|
const perpsDiskPersistence_js_1 = require("./utils/perpsDiskPersistence.cjs");
|
|
43
44
|
const wait_js_1 = require("./utils/wait.cjs");
|
|
44
45
|
function cloneUserDataSnapshot(snapshot) {
|
|
@@ -466,6 +467,7 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
466
467
|
'getCachedMarketDataForActiveProvider',
|
|
467
468
|
'getCachedUserDataForActiveProvider',
|
|
468
469
|
'getChaseOrders',
|
|
470
|
+
'getTwapOrders',
|
|
469
471
|
'getUserDataSnapshot',
|
|
470
472
|
'getCurrentNetwork',
|
|
471
473
|
'getFunding',
|
|
@@ -478,6 +480,7 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
478
480
|
'getOpenOrders',
|
|
479
481
|
'getOrderBookGrouping',
|
|
480
482
|
'getOrderBookPreferences',
|
|
483
|
+
'getOrderCapabilities',
|
|
481
484
|
'getOrderFills',
|
|
482
485
|
'getOrders',
|
|
483
486
|
'getPendingTradeConfiguration',
|
|
@@ -564,6 +567,8 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
564
567
|
this.isInitialized = false;
|
|
565
568
|
_PerpsController_initializationPromise.set(this, null);
|
|
566
569
|
_PerpsController_isReinitializing.set(this, false);
|
|
570
|
+
_PerpsController_reinitializationOperationPromise.set(this, null);
|
|
571
|
+
_PerpsController_disconnectOperationPromise.set(this, null);
|
|
567
572
|
/** Tracks the async MYX dynamic import so performInitialization can await it. */
|
|
568
573
|
_PerpsController_myxRegistrationPromise.set(this, null);
|
|
569
574
|
this.blockedRegionList = {
|
|
@@ -635,11 +640,16 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
635
640
|
_PerpsController_depositService.set(this, void 0);
|
|
636
641
|
_PerpsController_featureFlagConfigurationService.set(this, void 0);
|
|
637
642
|
_PerpsController_rewardsIntegrationService.set(this, void 0);
|
|
643
|
+
_PerpsController_publishChaseOrderMaxDistanceReached.set(this, (event) => {
|
|
644
|
+
this.messenger.publish('PerpsController:chaseOrderMaxDistanceReached', event);
|
|
645
|
+
});
|
|
638
646
|
_PerpsController_preloadTimer.set(this, null);
|
|
647
|
+
_PerpsController_preloadStartRequested.set(this, false);
|
|
639
648
|
_PerpsController_isPreloading.set(this, false);
|
|
640
649
|
_PerpsController_marketPreloadQueued.set(this, false);
|
|
641
650
|
_PerpsController_isPreloadingUserData.set(this, false);
|
|
642
651
|
_PerpsController_userPreloadQueued.set(this, false);
|
|
652
|
+
_PerpsController_lifecycleGeneration.set(this, 0);
|
|
643
653
|
_PerpsController_userSnapshotRequests.set(this, new Map());
|
|
644
654
|
_PerpsController_preloadStateUnsubscribe.set(this, null);
|
|
645
655
|
_PerpsController_accountChangeUnsubscribe.set(this, null);
|
|
@@ -863,6 +873,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
863
873
|
}
|
|
864
874
|
const { address } = evmAccount;
|
|
865
875
|
const { isTestnet, hip3ConfigVersion } = this.state;
|
|
876
|
+
const lifecycleGeneration = __classPrivateFieldGet(this, _PerpsController_lifecycleGeneration, "f");
|
|
866
877
|
const network = isTestnet ? 'testnet' : 'mainnet';
|
|
867
878
|
const expectedDexes = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getStaticSnapshotDexes).call(this);
|
|
868
879
|
if (!expectedDexes) {
|
|
@@ -876,7 +887,8 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
876
887
|
catch {
|
|
877
888
|
return false;
|
|
878
889
|
}
|
|
879
|
-
return (this
|
|
890
|
+
return (__classPrivateFieldGet(this, _PerpsController_lifecycleGeneration, "f") === lifecycleGeneration &&
|
|
891
|
+
this.state.activeProvider === 'hyperliquid' &&
|
|
880
892
|
(!capturedActiveProvider ||
|
|
881
893
|
this.activeProviderInstance === capturedActiveProvider) &&
|
|
882
894
|
this.state.isTestnet === isTestnet &&
|
|
@@ -992,18 +1004,19 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
992
1004
|
* @returns A promise that resolves when the operation completes.
|
|
993
1005
|
*/
|
|
994
1006
|
async init() {
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1007
|
+
while (true) {
|
|
1008
|
+
const pendingDisconnect = __classPrivateFieldGet(this, _PerpsController_disconnectOperationPromise, "f");
|
|
1009
|
+
if (pendingDisconnect) {
|
|
1010
|
+
await pendingDisconnect;
|
|
1011
|
+
continue;
|
|
1012
|
+
}
|
|
1013
|
+
const pendingReinitialization = __classPrivateFieldGet(this, _PerpsController_reinitializationOperationPromise, "f");
|
|
1014
|
+
if (pendingReinitialization) {
|
|
1015
|
+
await pendingReinitialization;
|
|
1016
|
+
continue;
|
|
1017
|
+
}
|
|
1018
|
+
return __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_initWithoutDisconnectWait).call(this);
|
|
1004
1019
|
}
|
|
1005
|
-
__classPrivateFieldSet(this, _PerpsController_initializationPromise, __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performInitialization).call(this), "f");
|
|
1006
|
-
return __classPrivateFieldGet(this, _PerpsController_initializationPromise, "f");
|
|
1007
1020
|
}
|
|
1008
1021
|
/**
|
|
1009
1022
|
* Registers the MYX provider after dynamic import resolves.
|
|
@@ -1105,6 +1118,50 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1105
1118
|
// Return the active provider instance or null if not found
|
|
1106
1119
|
return this.activeProviderInstance ?? null;
|
|
1107
1120
|
}
|
|
1121
|
+
/**
|
|
1122
|
+
* Get strategy capabilities through the active provider route used by order
|
|
1123
|
+
* placement. The query waits for in-flight initialization and reports an
|
|
1124
|
+
* explicit unavailable status when no provider route can answer reliably.
|
|
1125
|
+
*
|
|
1126
|
+
* @param params - Market and optional provider route.
|
|
1127
|
+
* @returns Provider-owned order capabilities.
|
|
1128
|
+
*/
|
|
1129
|
+
async getOrderCapabilities(params) {
|
|
1130
|
+
let activeProvider;
|
|
1131
|
+
try {
|
|
1132
|
+
activeProvider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getActiveProviderWhenReady).call(this);
|
|
1133
|
+
}
|
|
1134
|
+
catch (error) {
|
|
1135
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Order capabilities unavailable', {
|
|
1136
|
+
error: (0, errorUtils_js_1.ensureError)(error, 'PerpsController.getOrderCapabilities')
|
|
1137
|
+
.message,
|
|
1138
|
+
});
|
|
1139
|
+
return __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getUnavailableOrderCapabilities).call(this, 'provider_unavailable', params.providerId);
|
|
1140
|
+
}
|
|
1141
|
+
const resolvedProviderId = params.providerId ?? __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getDirectProviderId).call(this, activeProvider);
|
|
1142
|
+
if (__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_hasConflictingProviderRoute).call(this, params.providerId, activeProvider)) {
|
|
1143
|
+
return __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getUnavailableOrderCapabilities).call(this, 'provider_not_routable', resolvedProviderId);
|
|
1144
|
+
}
|
|
1145
|
+
if (!activeProvider.getOrderCapabilities) {
|
|
1146
|
+
return __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getUnavailableOrderCapabilities).call(this, 'not_implemented', resolvedProviderId);
|
|
1147
|
+
}
|
|
1148
|
+
try {
|
|
1149
|
+
const capabilities = await activeProvider.getOrderCapabilities(params);
|
|
1150
|
+
if (capabilities.status === 'unavailable' &&
|
|
1151
|
+
capabilities.providerId === undefined &&
|
|
1152
|
+
resolvedProviderId !== undefined) {
|
|
1153
|
+
return { ...capabilities, providerId: resolvedProviderId };
|
|
1154
|
+
}
|
|
1155
|
+
return capabilities;
|
|
1156
|
+
}
|
|
1157
|
+
catch (error) {
|
|
1158
|
+
const safeError = (0, errorUtils_js_1.ensureError)(error, 'PerpsController.getOrderCapabilities');
|
|
1159
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Order capabilities unavailable', {
|
|
1160
|
+
error: safeError.message,
|
|
1161
|
+
});
|
|
1162
|
+
return __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getUnavailableOrderCapabilities).call(this, 'provider_unavailable', resolvedProviderId);
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1108
1165
|
/**
|
|
1109
1166
|
* Place a new order
|
|
1110
1167
|
* Thin delegation to TradingService
|
|
@@ -1113,7 +1170,10 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1113
1170
|
* @returns The order result with order ID and status.
|
|
1114
1171
|
*/
|
|
1115
1172
|
async placeOrder(params) {
|
|
1116
|
-
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m",
|
|
1173
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_resolveRoutedOrderProvider).call(this, {
|
|
1174
|
+
orderType: params.orderType,
|
|
1175
|
+
providerId: params.providerId,
|
|
1176
|
+
});
|
|
1117
1177
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_ensureTradingServiceDeps).call(this);
|
|
1118
1178
|
const result = await __classPrivateFieldGet(this, _PerpsController_tradingService, "f").placeOrder({
|
|
1119
1179
|
provider,
|
|
@@ -1136,7 +1196,16 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1136
1196
|
* @returns The updated order result with order ID and status.
|
|
1137
1197
|
*/
|
|
1138
1198
|
async editOrder(params) {
|
|
1139
|
-
|
|
1199
|
+
if ((0, orderTypes_js_1.isStrategyOrderType)(params.newOrder.orderType)) {
|
|
1200
|
+
return {
|
|
1201
|
+
success: false,
|
|
1202
|
+
error: perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_EDIT_STRATEGY_UNSUPPORTED,
|
|
1203
|
+
};
|
|
1204
|
+
}
|
|
1205
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_resolveRoutedOrderProvider).call(this, {
|
|
1206
|
+
orderType: params.newOrder.orderType,
|
|
1207
|
+
providerId: params.newOrder.providerId,
|
|
1208
|
+
});
|
|
1140
1209
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_ensureTradingServiceDeps).call(this);
|
|
1141
1210
|
return __classPrivateFieldGet(this, _PerpsController_tradingService, "f").editOrder({
|
|
1142
1211
|
provider,
|
|
@@ -1151,13 +1220,26 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1151
1220
|
* @returns The cancellation result with status.
|
|
1152
1221
|
*/
|
|
1153
1222
|
async cancelOrder(params) {
|
|
1154
|
-
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m",
|
|
1223
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_resolveRoutedOrderProvider).call(this, {
|
|
1224
|
+
orderType: params.orderType,
|
|
1225
|
+
providerId: params.providerId,
|
|
1226
|
+
});
|
|
1155
1227
|
return __classPrivateFieldGet(this, _PerpsController_tradingService, "f").cancelOrder({
|
|
1156
1228
|
provider,
|
|
1157
1229
|
params,
|
|
1158
1230
|
context: __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_createServiceContext).call(this, 'cancelOrder'),
|
|
1159
1231
|
});
|
|
1160
1232
|
}
|
|
1233
|
+
/**
|
|
1234
|
+
* Read venue-backed TWAP lifecycle records through the active provider.
|
|
1235
|
+
* Providers without native TWAP history return an empty list.
|
|
1236
|
+
*
|
|
1237
|
+
* @returns Current and terminal TWAP schedules with slice fills.
|
|
1238
|
+
*/
|
|
1239
|
+
async getTwapOrders() {
|
|
1240
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getActiveProviderWhenReady).call(this);
|
|
1241
|
+
return provider.getTwapOrders ? await provider.getTwapOrders() : [];
|
|
1242
|
+
}
|
|
1161
1243
|
/**
|
|
1162
1244
|
* Read the active provider's retained Chase lifecycle snapshots.
|
|
1163
1245
|
* Providers without an emulated Chase implementation return an empty list.
|
|
@@ -1208,7 +1290,10 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1208
1290
|
* @returns The order result from the close position request.
|
|
1209
1291
|
*/
|
|
1210
1292
|
async closePosition(params) {
|
|
1211
|
-
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m",
|
|
1293
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_resolveRoutedOrderProvider).call(this, {
|
|
1294
|
+
orderType: params.orderType,
|
|
1295
|
+
providerId: params.providerId,
|
|
1296
|
+
});
|
|
1212
1297
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_ensureTradingServiceDeps).call(this);
|
|
1213
1298
|
return __classPrivateFieldGet(this, _PerpsController_tradingService, "f").closePosition({
|
|
1214
1299
|
provider,
|
|
@@ -1244,7 +1329,10 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1244
1329
|
* @returns The order result from the TP/SL update.
|
|
1245
1330
|
*/
|
|
1246
1331
|
async updatePositionTPSL(params) {
|
|
1247
|
-
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m",
|
|
1332
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_resolveRoutedOrderProvider).call(this, {
|
|
1333
|
+
orderType: undefined,
|
|
1334
|
+
providerId: params.providerId,
|
|
1335
|
+
});
|
|
1248
1336
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_ensureTradingServiceDeps).call(this);
|
|
1249
1337
|
return __classPrivateFieldGet(this, _PerpsController_tradingService, "f").updatePositionTPSL({
|
|
1250
1338
|
provider,
|
|
@@ -1930,6 +2018,11 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
1930
2018
|
* Watches for isTestnet and hip3ConfigVersion changes to re-preload.
|
|
1931
2019
|
*/
|
|
1932
2020
|
startMarketDataPreload() {
|
|
2021
|
+
__classPrivateFieldSet(this, _PerpsController_preloadStartRequested, true, "f");
|
|
2022
|
+
if (__classPrivateFieldGet(this, _PerpsController_disconnectOperationPromise, "f")) {
|
|
2023
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Disconnect in progress, deferring market data preload');
|
|
2024
|
+
return;
|
|
2025
|
+
}
|
|
1933
2026
|
if (__classPrivateFieldGet(this, _PerpsController_preloadTimer, "f")) {
|
|
1934
2027
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Preload already started, skipping');
|
|
1935
2028
|
return;
|
|
@@ -2018,6 +2111,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2018
2111
|
*/
|
|
2019
2112
|
stopMarketDataPreload() {
|
|
2020
2113
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Stopping market data preload');
|
|
2114
|
+
__classPrivateFieldSet(this, _PerpsController_preloadStartRequested, false, "f");
|
|
2021
2115
|
if (__classPrivateFieldGet(this, _PerpsController_preloadTimer, "f")) {
|
|
2022
2116
|
clearInterval(__classPrivateFieldGet(this, _PerpsController_preloadTimer, "f"));
|
|
2023
2117
|
__classPrivateFieldSet(this, _PerpsController_preloadTimer, null, "f");
|
|
@@ -2126,7 +2220,10 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2126
2220
|
* @returns True if the condition is met.
|
|
2127
2221
|
*/
|
|
2128
2222
|
async validateOrder(params) {
|
|
2129
|
-
const provider = this.
|
|
2223
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_resolveRoutedOrderProvider).call(this, {
|
|
2224
|
+
orderType: params.orderType,
|
|
2225
|
+
providerId: params.providerId,
|
|
2226
|
+
});
|
|
2130
2227
|
const context = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_createServiceContext).call(this, 'validateOrder');
|
|
2131
2228
|
return __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").validateOrder({ provider, params, context });
|
|
2132
2229
|
}
|
|
@@ -2137,7 +2234,10 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2137
2234
|
* @returns A promise that resolves to the result.
|
|
2138
2235
|
*/
|
|
2139
2236
|
async validateClosePosition(params) {
|
|
2140
|
-
const provider = this.
|
|
2237
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_resolveRoutedOrderProvider).call(this, {
|
|
2238
|
+
orderType: params.orderType,
|
|
2239
|
+
providerId: params.providerId,
|
|
2240
|
+
});
|
|
2141
2241
|
const context = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_createServiceContext).call(this, 'validateClosePosition');
|
|
2142
2242
|
return __classPrivateFieldGet(this, _PerpsController_marketDataService, "f").validateClosePosition({
|
|
2143
2243
|
provider,
|
|
@@ -2230,6 +2330,9 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2230
2330
|
* @returns The toggle result with success status and current network mode.
|
|
2231
2331
|
*/
|
|
2232
2332
|
async toggleTestnet() {
|
|
2333
|
+
while (__classPrivateFieldGet(this, _PerpsController_disconnectOperationPromise, "f")) {
|
|
2334
|
+
await __classPrivateFieldGet(this, _PerpsController_disconnectOperationPromise, "f");
|
|
2335
|
+
}
|
|
2233
2336
|
// Prevent concurrent reinitializations
|
|
2234
2337
|
if (this.isCurrentlyReinitializing()) {
|
|
2235
2338
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Already reinitializing, skipping toggle', {
|
|
@@ -2241,10 +2344,13 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2241
2344
|
error: perpsErrorCodes_js_1.PERPS_ERROR_CODES.CLIENT_REINITIALIZING,
|
|
2242
2345
|
};
|
|
2243
2346
|
}
|
|
2244
|
-
|
|
2245
|
-
// Store previous isTestnet for rollback on failure
|
|
2347
|
+
const completeReinitialization = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_beginReinitialization).call(this);
|
|
2246
2348
|
const previousIsTestnet = this.state.isTestnet;
|
|
2247
2349
|
try {
|
|
2350
|
+
const pendingInitialization = __classPrivateFieldGet(this, _PerpsController_initializationPromise, "f");
|
|
2351
|
+
if (pendingInitialization) {
|
|
2352
|
+
await pendingInitialization;
|
|
2353
|
+
}
|
|
2248
2354
|
await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_cleanupStandaloneProvider).call(this);
|
|
2249
2355
|
const previousNetwork = previousIsTestnet ? 'testnet' : 'mainnet';
|
|
2250
2356
|
this.update((state) => {
|
|
@@ -2259,7 +2365,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2259
2365
|
// Reset initialization state and reinitialize provider with new testnet setting
|
|
2260
2366
|
this.isInitialized = false;
|
|
2261
2367
|
__classPrivateFieldSet(this, _PerpsController_initializationPromise, null, "f");
|
|
2262
|
-
await this.
|
|
2368
|
+
await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_initWithoutDisconnectWait).call(this);
|
|
2263
2369
|
// Check if initialization actually succeeded — performInitialization()
|
|
2264
2370
|
// does not throw on failure, it sets state to Failed and resolves.
|
|
2265
2371
|
if (this.state.initializationState === InitializationState.Failed) {
|
|
@@ -2285,7 +2391,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2285
2391
|
};
|
|
2286
2392
|
}
|
|
2287
2393
|
finally {
|
|
2288
|
-
|
|
2394
|
+
completeReinitialization();
|
|
2289
2395
|
// Re-trigger preload now that reinit is complete and the
|
|
2290
2396
|
// activeProviderInstance points to the correct network.
|
|
2291
2397
|
// The state-change listener may have already fired during reinit
|
|
@@ -2309,19 +2415,8 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2309
2415
|
* @returns The switch result with success status and active provider.
|
|
2310
2416
|
*/
|
|
2311
2417
|
async switchProvider(providerId) {
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
return { success: true, providerId };
|
|
2315
|
-
}
|
|
2316
|
-
// Validate provider is available
|
|
2317
|
-
// 'aggregated' is always valid, individual providers must exist in the map
|
|
2318
|
-
const isValidProvider = providerId === 'aggregated' || this.providers.has(providerId);
|
|
2319
|
-
if (!isValidProvider) {
|
|
2320
|
-
return {
|
|
2321
|
-
success: false,
|
|
2322
|
-
providerId: this.state.activeProvider,
|
|
2323
|
-
error: `Provider ${providerId} not available`,
|
|
2324
|
-
};
|
|
2418
|
+
while (__classPrivateFieldGet(this, _PerpsController_disconnectOperationPromise, "f")) {
|
|
2419
|
+
await __classPrivateFieldGet(this, _PerpsController_disconnectOperationPromise, "f");
|
|
2325
2420
|
}
|
|
2326
2421
|
// Prevent concurrent switches
|
|
2327
2422
|
if (this.isCurrentlyReinitializing()) {
|
|
@@ -2331,10 +2426,44 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2331
2426
|
error: perpsErrorCodes_js_1.PERPS_ERROR_CODES.CLIENT_REINITIALIZING,
|
|
2332
2427
|
};
|
|
2333
2428
|
}
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
const previousProvider = this.state.activeProvider;
|
|
2429
|
+
const completeReinitialization = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_beginReinitialization).call(this);
|
|
2430
|
+
let previousProvider = this.state.activeProvider;
|
|
2337
2431
|
try {
|
|
2432
|
+
const pendingInitialization = __classPrivateFieldGet(this, _PerpsController_initializationPromise, "f");
|
|
2433
|
+
if (pendingInitialization) {
|
|
2434
|
+
await pendingInitialization;
|
|
2435
|
+
}
|
|
2436
|
+
// A completed disconnect leaves no initialization promise to await. Rebuild
|
|
2437
|
+
// the provider registry before same-provider detection or route validation
|
|
2438
|
+
// so a successful switch always leaves a usable active provider.
|
|
2439
|
+
const needsInitialization = !this.isInitialized ||
|
|
2440
|
+
this.state.initializationState !== InitializationState.Initialized;
|
|
2441
|
+
if (needsInitialization) {
|
|
2442
|
+
await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_initWithoutDisconnectWait).call(this);
|
|
2443
|
+
const initializationFailed = !this.isInitialized ||
|
|
2444
|
+
this.state.initializationState !== InitializationState.Initialized;
|
|
2445
|
+
if (initializationFailed) {
|
|
2446
|
+
throw new Error(this.state.initializationError ?? 'Provider initialization failed');
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2449
|
+
// Initialization may select a fallback provider. Read the effective
|
|
2450
|
+
// provider only after it settles so no-op detection and rollback both
|
|
2451
|
+
// use the state this switch is actually replacing.
|
|
2452
|
+
previousProvider = this.state.activeProvider;
|
|
2453
|
+
if (previousProvider === providerId) {
|
|
2454
|
+
return { success: true, providerId };
|
|
2455
|
+
}
|
|
2456
|
+
// Validate provider only after a pending initialization has rebuilt the
|
|
2457
|
+
// registry. Otherwise a switch queued behind disconnect can observe the
|
|
2458
|
+
// intentionally empty teardown state.
|
|
2459
|
+
const isValidProvider = providerId === 'aggregated' || this.providers.has(providerId);
|
|
2460
|
+
if (!isValidProvider) {
|
|
2461
|
+
return {
|
|
2462
|
+
success: false,
|
|
2463
|
+
providerId: this.state.activeProvider,
|
|
2464
|
+
error: `Provider ${providerId} not available`,
|
|
2465
|
+
};
|
|
2466
|
+
}
|
|
2338
2467
|
await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_cleanupStandaloneProvider).call(this);
|
|
2339
2468
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Provider switch initiated', {
|
|
2340
2469
|
from: previousProvider,
|
|
@@ -2342,8 +2471,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2342
2471
|
timestamp: new Date().toISOString(),
|
|
2343
2472
|
});
|
|
2344
2473
|
// Provider disconnect is handled by performInitialization() during
|
|
2345
|
-
// reinitialization.
|
|
2346
|
-
// when isReinitializing is true to prevent double-disconnect.
|
|
2474
|
+
// reinitialization.
|
|
2347
2475
|
// Update state with new provider (market data cache preserved per-provider)
|
|
2348
2476
|
this.update((state) => {
|
|
2349
2477
|
state.activeProvider = providerId;
|
|
@@ -2353,7 +2481,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2353
2481
|
// Reset initialization state and reinitialize
|
|
2354
2482
|
this.isInitialized = false;
|
|
2355
2483
|
__classPrivateFieldSet(this, _PerpsController_initializationPromise, null, "f");
|
|
2356
|
-
await this.
|
|
2484
|
+
await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_initWithoutDisconnectWait).call(this);
|
|
2357
2485
|
// Check if initialization actually succeeded — performInitialization()
|
|
2358
2486
|
// does not throw on failure, it sets state to Failed and resolves.
|
|
2359
2487
|
if (this.state.initializationState === InitializationState.Failed) {
|
|
@@ -2376,7 +2504,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2376
2504
|
try {
|
|
2377
2505
|
this.isInitialized = false;
|
|
2378
2506
|
__classPrivateFieldSet(this, _PerpsController_initializationPromise, null, "f");
|
|
2379
|
-
await this.
|
|
2507
|
+
await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_initWithoutDisconnectWait).call(this);
|
|
2380
2508
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Rollback to previous provider succeeded', {
|
|
2381
2509
|
previousProvider,
|
|
2382
2510
|
timestamp: new Date().toISOString(),
|
|
@@ -2400,7 +2528,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2400
2528
|
};
|
|
2401
2529
|
}
|
|
2402
2530
|
finally {
|
|
2403
|
-
|
|
2531
|
+
completeReinitialization();
|
|
2404
2532
|
// Re-trigger preload now that reinit is complete.
|
|
2405
2533
|
if (__classPrivateFieldGet(this, _PerpsController_preloadTimer, "f")) {
|
|
2406
2534
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performMarketDataPreload).call(this).catch(() => {
|
|
@@ -2736,14 +2864,18 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2736
2864
|
}
|
|
2737
2865
|
}
|
|
2738
2866
|
/**
|
|
2739
|
-
* Calculate trading fees
|
|
2740
|
-
* Each provider
|
|
2867
|
+
* Calculate trading fees through the active provider route.
|
|
2868
|
+
* Each provider owns its fee policy. An explicit provider route overrides
|
|
2869
|
+
* the active/default provider used by placement.
|
|
2741
2870
|
*
|
|
2742
2871
|
* @param params - The operation parameters.
|
|
2743
2872
|
* @returns The fee calculation result for the trade.
|
|
2744
2873
|
*/
|
|
2745
2874
|
async calculateFees(params) {
|
|
2746
|
-
const provider = this.
|
|
2875
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_resolveRoutedOrderProvider).call(this, {
|
|
2876
|
+
orderType: params.orderType,
|
|
2877
|
+
providerId: params.providerId,
|
|
2878
|
+
});
|
|
2747
2879
|
// Preview owns subscription hydration. The submit resolver remains a pure
|
|
2748
2880
|
// cache read and can therefore never start a benefits request while an
|
|
2749
2881
|
// order is being signed.
|
|
@@ -2784,46 +2916,33 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2784
2916
|
* Call this when navigating away from Perps screens to prevent battery drain
|
|
2785
2917
|
*/
|
|
2786
2918
|
async disconnect() {
|
|
2787
|
-
__classPrivateFieldGet(this,
|
|
2788
|
-
|
|
2919
|
+
while (__classPrivateFieldGet(this, _PerpsController_disconnectOperationPromise, "f")) {
|
|
2920
|
+
// Each explicit disconnect claims a teardown after the operation already
|
|
2921
|
+
// in flight. This lets a later disconnect close providers created by an
|
|
2922
|
+
// init call that was queued behind the same earlier teardown.
|
|
2923
|
+
__classPrivateFieldSet(this, _PerpsController_preloadStartRequested, false, "f");
|
|
2924
|
+
await __classPrivateFieldGet(this, _PerpsController_disconnectOperationPromise, "f");
|
|
2925
|
+
}
|
|
2926
|
+
// A disconnect stops the current preload session. A later start call made
|
|
2927
|
+
// while teardown is in flight sets this back to true and is resumed below.
|
|
2928
|
+
__classPrivateFieldSet(this, _PerpsController_preloadStartRequested, false, "f");
|
|
2929
|
+
let resolveOperation = () => undefined;
|
|
2930
|
+
const operation = new Promise((resolve) => {
|
|
2931
|
+
resolveOperation = resolve;
|
|
2789
2932
|
});
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
clearInterval(__classPrivateFieldGet(this, _PerpsController_preloadTimer, "f"));
|
|
2794
|
-
__classPrivateFieldSet(this, _PerpsController_preloadTimer, null, "f");
|
|
2795
|
-
}
|
|
2796
|
-
if (__classPrivateFieldGet(this, _PerpsController_preloadStateUnsubscribe, "f")) {
|
|
2797
|
-
__classPrivateFieldGet(this, _PerpsController_preloadStateUnsubscribe, "f").call(this);
|
|
2798
|
-
__classPrivateFieldSet(this, _PerpsController_preloadStateUnsubscribe, null, "f");
|
|
2799
|
-
}
|
|
2800
|
-
if (__classPrivateFieldGet(this, _PerpsController_accountChangeUnsubscribe, "f")) {
|
|
2801
|
-
__classPrivateFieldGet(this, _PerpsController_accountChangeUnsubscribe, "f").call(this);
|
|
2802
|
-
__classPrivateFieldSet(this, _PerpsController_accountChangeUnsubscribe, null, "f");
|
|
2933
|
+
__classPrivateFieldSet(this, _PerpsController_disconnectOperationPromise, operation, "f");
|
|
2934
|
+
try {
|
|
2935
|
+
await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performDisconnect).call(this);
|
|
2803
2936
|
}
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
try {
|
|
2809
|
-
const provider = this.getActiveProvider();
|
|
2810
|
-
await provider.disconnect();
|
|
2937
|
+
finally {
|
|
2938
|
+
resolveOperation();
|
|
2939
|
+
if (__classPrivateFieldGet(this, _PerpsController_disconnectOperationPromise, "f") === operation) {
|
|
2940
|
+
__classPrivateFieldSet(this, _PerpsController_disconnectOperationPromise, null, "f");
|
|
2811
2941
|
}
|
|
2812
|
-
|
|
2813
|
-
|
|
2942
|
+
if (__classPrivateFieldGet(this, _PerpsController_preloadStartRequested, "f")) {
|
|
2943
|
+
this.startMarketDataPreload();
|
|
2814
2944
|
}
|
|
2815
2945
|
}
|
|
2816
|
-
// Clear stale reference so standalone reads don't route through old provider
|
|
2817
|
-
this.activeProviderInstance = null;
|
|
2818
|
-
// Cleanup cached standalone provider (if any) — awaited to prevent races
|
|
2819
|
-
await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_cleanupStandaloneProvider).call(this);
|
|
2820
|
-
// Note: Feature-flag subscription is NOT cleaned up here.
|
|
2821
|
-
// It is a controller-lifetime concern (set once in the constructor),
|
|
2822
|
-
// not a session-lifetime concern. Unsubscribing here would break
|
|
2823
|
-
// geo-blocking / HIP-3 flag propagation after disconnect → reconnect.
|
|
2824
|
-
// Reset initialization state to ensure proper reconnection
|
|
2825
|
-
this.isInitialized = false;
|
|
2826
|
-
__classPrivateFieldSet(this, _PerpsController_initializationPromise, null, "f");
|
|
2827
2946
|
}
|
|
2828
2947
|
/**
|
|
2829
2948
|
* Eligibility (Geo-Blocking)
|
|
@@ -3572,7 +3691,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
3572
3691
|
}
|
|
3573
3692
|
}
|
|
3574
3693
|
exports.PerpsController = PerpsController;
|
|
3575
|
-
_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() {
|
|
3694
|
+
_a = PerpsController, _PerpsController_initializationPromise = new WeakMap(), _PerpsController_isReinitializing = new WeakMap(), _PerpsController_reinitializationOperationPromise = new WeakMap(), _PerpsController_disconnectOperationPromise = 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_publishChaseOrderMaxDistanceReached = new WeakMap(), _PerpsController_preloadTimer = new WeakMap(), _PerpsController_preloadStartRequested = new WeakMap(), _PerpsController_isPreloading = new WeakMap(), _PerpsController_marketPreloadQueued = new WeakMap(), _PerpsController_isPreloadingUserData = new WeakMap(), _PerpsController_userPreloadQueued = new WeakMap(), _PerpsController_lifecycleGeneration = 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() {
|
|
3576
3695
|
const myx = __classPrivateFieldGet(this, _PerpsController_options, "f").clientConfig?.providerCredentials?.myx;
|
|
3577
3696
|
// Local env-var override (MM_PERPS_MYX_PROVIDER_ENABLED) always wins —
|
|
3578
3697
|
// matches the UI selector (resolvePerpsMyxProviderEnabled) so controller
|
|
@@ -3605,16 +3724,6 @@ _a = PerpsController, _PerpsController_initializationPromise = new WeakMap(), _P
|
|
|
3605
3724
|
__classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.logger.error(error, options);
|
|
3606
3725
|
}, _PerpsController_debugLog = function _PerpsController_debugLog(...args) {
|
|
3607
3726
|
__classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.debugLogger.log(...args);
|
|
3608
|
-
}, _PerpsController_awaitInitializationIfInProgress =
|
|
3609
|
-
/**
|
|
3610
|
-
* Awaits the in-flight initialization promise if init is currently running.
|
|
3611
|
-
* Called internally by #getActiveProviderWhenReady().
|
|
3612
|
-
*/
|
|
3613
|
-
async function _PerpsController_awaitInitializationIfInProgress() {
|
|
3614
|
-
if (this.state.initializationState === InitializationState.Initializing &&
|
|
3615
|
-
__classPrivateFieldGet(this, _PerpsController_initializationPromise, "f")) {
|
|
3616
|
-
await __classPrivateFieldGet(this, _PerpsController_initializationPromise, "f");
|
|
3617
|
-
}
|
|
3618
3727
|
}, _PerpsController_getAggregatedCacheProviderIds = function _PerpsController_getAggregatedCacheProviderIds(cacheKeys) {
|
|
3619
3728
|
const providerIds = new Set();
|
|
3620
3729
|
const currentNetwork = this.state.isTestnet ? 'testnet' : 'mainnet';
|
|
@@ -3759,6 +3868,7 @@ async function _PerpsController_awaitInitializationIfInProgress() {
|
|
|
3759
3868
|
?.subscriptionBuilderAddressTestnet,
|
|
3760
3869
|
subscriptionBuilderAddressMainnet: __classPrivateFieldGet(this, _PerpsController_options, "f").clientConfig?.providerCredentials?.hyperliquid
|
|
3761
3870
|
?.subscriptionBuilderAddressMainnet,
|
|
3871
|
+
onChaseOrderMaxDistanceReached: __classPrivateFieldGet(this, _PerpsController_publishChaseOrderMaxDistanceReached, "f"),
|
|
3762
3872
|
}), "f");
|
|
3763
3873
|
__classPrivateFieldSet(this, _PerpsController_standaloneProviderIsTestnet, currentIsTestnet, "f");
|
|
3764
3874
|
__classPrivateFieldSet(this, _PerpsController_standaloneProviderHip3Version, currentHip3Version, "f");
|
|
@@ -3903,6 +4013,40 @@ async function _PerpsController_withStreamPause(operation, channels) {
|
|
|
3903
4013
|
}
|
|
3904
4014
|
}
|
|
3905
4015
|
}
|
|
4016
|
+
}, _PerpsController_initWithoutDisconnectWait =
|
|
4017
|
+
/**
|
|
4018
|
+
* Initialize without waiting for disconnect. Reinitialization operations use
|
|
4019
|
+
* this after they have claimed the controller lifecycle.
|
|
4020
|
+
*
|
|
4021
|
+
* @returns A promise that resolves when initialization finishes.
|
|
4022
|
+
*/
|
|
4023
|
+
async function _PerpsController_initWithoutDisconnectWait() {
|
|
4024
|
+
if (!__classPrivateFieldGet(this, _PerpsController_handlersRegistered, "f")) {
|
|
4025
|
+
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
4026
|
+
__classPrivateFieldSet(this, _PerpsController_handlersRegistered, true, "f");
|
|
4027
|
+
}
|
|
4028
|
+
if (this.isInitialized) {
|
|
4029
|
+
return undefined;
|
|
4030
|
+
}
|
|
4031
|
+
if (__classPrivateFieldGet(this, _PerpsController_initializationPromise, "f")) {
|
|
4032
|
+
return __classPrivateFieldGet(this, _PerpsController_initializationPromise, "f");
|
|
4033
|
+
}
|
|
4034
|
+
__classPrivateFieldSet(this, _PerpsController_initializationPromise, __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_performInitialization).call(this), "f");
|
|
4035
|
+
return __classPrivateFieldGet(this, _PerpsController_initializationPromise, "f");
|
|
4036
|
+
}, _PerpsController_beginReinitialization = function _PerpsController_beginReinitialization() {
|
|
4037
|
+
__classPrivateFieldSet(this, _PerpsController_isReinitializing, true, "f");
|
|
4038
|
+
let resolveOperation = () => undefined;
|
|
4039
|
+
const operation = new Promise((resolve) => {
|
|
4040
|
+
resolveOperation = resolve;
|
|
4041
|
+
});
|
|
4042
|
+
__classPrivateFieldSet(this, _PerpsController_reinitializationOperationPromise, operation, "f");
|
|
4043
|
+
return () => {
|
|
4044
|
+
__classPrivateFieldSet(this, _PerpsController_isReinitializing, false, "f");
|
|
4045
|
+
resolveOperation();
|
|
4046
|
+
if (__classPrivateFieldGet(this, _PerpsController_reinitializationOperationPromise, "f") === operation) {
|
|
4047
|
+
__classPrivateFieldSet(this, _PerpsController_reinitializationOperationPromise, null, "f");
|
|
4048
|
+
}
|
|
4049
|
+
};
|
|
3906
4050
|
}, _PerpsController_performInitialization =
|
|
3907
4051
|
/**
|
|
3908
4052
|
* Actual initialization implementation with retry logic
|
|
@@ -4023,6 +4167,7 @@ async function _PerpsController_performInitialization() {
|
|
|
4023
4167
|
?.subscriptionBuilderAddressTestnet,
|
|
4024
4168
|
subscriptionBuilderAddressMainnet: __classPrivateFieldGet(this, _PerpsController_options, "f").clientConfig?.providerCredentials?.hyperliquid
|
|
4025
4169
|
?.subscriptionBuilderAddressMainnet,
|
|
4170
|
+
onChaseOrderMaxDistanceReached: __classPrivateFieldGet(this, _PerpsController_publishChaseOrderMaxDistanceReached, "f"),
|
|
4026
4171
|
});
|
|
4027
4172
|
this.providers.set('hyperliquid', hyperLiquidProvider);
|
|
4028
4173
|
// Register MYX provider if enabled via feature flag.
|
|
@@ -4152,8 +4297,56 @@ async function _PerpsController_performInitialization() {
|
|
|
4152
4297
|
* @returns The active provider once initialization completes.
|
|
4153
4298
|
*/
|
|
4154
4299
|
async function _PerpsController_getActiveProviderWhenReady() {
|
|
4155
|
-
|
|
4156
|
-
|
|
4300
|
+
while (true) {
|
|
4301
|
+
const pendingDisconnect = __classPrivateFieldGet(this, _PerpsController_disconnectOperationPromise, "f");
|
|
4302
|
+
if (pendingDisconnect) {
|
|
4303
|
+
await pendingDisconnect;
|
|
4304
|
+
continue;
|
|
4305
|
+
}
|
|
4306
|
+
const pendingReinitialization = __classPrivateFieldGet(this, _PerpsController_reinitializationOperationPromise, "f");
|
|
4307
|
+
if (pendingReinitialization) {
|
|
4308
|
+
await pendingReinitialization;
|
|
4309
|
+
continue;
|
|
4310
|
+
}
|
|
4311
|
+
const pendingInitialization = __classPrivateFieldGet(this, _PerpsController_initializationPromise, "f");
|
|
4312
|
+
if (this.state.initializationState === InitializationState.Initializing &&
|
|
4313
|
+
pendingInitialization) {
|
|
4314
|
+
await pendingInitialization;
|
|
4315
|
+
continue;
|
|
4316
|
+
}
|
|
4317
|
+
return this.getActiveProvider();
|
|
4318
|
+
}
|
|
4319
|
+
}, _PerpsController_getUnavailableOrderCapabilities = function _PerpsController_getUnavailableOrderCapabilities(reason, providerId) {
|
|
4320
|
+
return providerId
|
|
4321
|
+
? { status: 'unavailable', providerId, reason }
|
|
4322
|
+
: { status: 'unavailable', reason };
|
|
4323
|
+
}, _PerpsController_getDirectProviderId = function _PerpsController_getDirectProviderId(provider) {
|
|
4324
|
+
if (provider.routesOrdersByProviderId) {
|
|
4325
|
+
return undefined;
|
|
4326
|
+
}
|
|
4327
|
+
return Array.from(this.providers.entries()).find(([, candidate]) => candidate === provider)?.[0];
|
|
4328
|
+
}, _PerpsController_hasConflictingProviderRoute = function _PerpsController_hasConflictingProviderRoute(providerId, provider) {
|
|
4329
|
+
return (providerId !== undefined &&
|
|
4330
|
+
!provider.routesOrdersByProviderId &&
|
|
4331
|
+
providerId !== provider.protocolId);
|
|
4332
|
+
}, _PerpsController_resolveRoutedOrderProvider =
|
|
4333
|
+
/**
|
|
4334
|
+
* Resolve one routed order operation after any in-flight initialization.
|
|
4335
|
+
*
|
|
4336
|
+
* @param params - Routed operation context.
|
|
4337
|
+
* @param params.orderType - Order type, when the operation carries one.
|
|
4338
|
+
* @param params.providerId - Explicit provider route, when supplied.
|
|
4339
|
+
* @returns The initialized provider that owns the operation.
|
|
4340
|
+
*/
|
|
4341
|
+
async function _PerpsController_resolveRoutedOrderProvider(params) {
|
|
4342
|
+
const { orderType, providerId } = params;
|
|
4343
|
+
const provider = await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getActiveProviderWhenReady).call(this);
|
|
4344
|
+
if (__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_hasConflictingProviderRoute).call(this, providerId, provider)) {
|
|
4345
|
+
throw new Error(orderType !== undefined && (0, orderTypes_js_1.isStrategyOrderType)(orderType)
|
|
4346
|
+
? perpsErrorCodes_js_1.PERPS_ERROR_CODES.ORDER_STRATEGY_ROUTE_UNAVAILABLE
|
|
4347
|
+
: perpsErrorCodes_js_1.PERPS_ERROR_CODES.PROVIDER_NOT_FOUND);
|
|
4348
|
+
}
|
|
4349
|
+
return provider;
|
|
4157
4350
|
}, _PerpsController_buildGlobalSnapshotContext = function _PerpsController_buildGlobalSnapshotContext() {
|
|
4158
4351
|
const snapshotConfigured = Boolean(__classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.terminalApi?.globalSnapshotUrl) ||
|
|
4159
4352
|
typeof __classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.terminalMarketService
|
|
@@ -4280,7 +4473,12 @@ async function _PerpsController_performMarketDataPreload() {
|
|
|
4280
4473
|
activeProvider: this.state.activeProvider,
|
|
4281
4474
|
isTestnet: this.state.isTestnet,
|
|
4282
4475
|
hip3ConfigVersion: this.state.hip3ConfigVersion,
|
|
4476
|
+
lifecycleGeneration: __classPrivateFieldGet(this, _PerpsController_lifecycleGeneration, "f"),
|
|
4283
4477
|
};
|
|
4478
|
+
const isCurrent = () => __classPrivateFieldGet(this, _PerpsController_lifecycleGeneration, "f") === preloadContext.lifecycleGeneration &&
|
|
4479
|
+
this.state.activeProvider === preloadContext.activeProvider &&
|
|
4480
|
+
this.state.isTestnet === preloadContext.isTestnet &&
|
|
4481
|
+
this.state.hip3ConfigVersion === preloadContext.hip3ConfigVersion;
|
|
4284
4482
|
const staticSnapshotDexes = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getStaticSnapshotDexes).call(this);
|
|
4285
4483
|
const now = Date.now();
|
|
4286
4484
|
const existingEntry = this.state.cachedMarketDataByProvider[cacheKey];
|
|
@@ -4310,9 +4508,7 @@ async function _PerpsController_performMarketDataPreload() {
|
|
|
4310
4508
|
duration_ms: Math.round(performance.now() - preloadStart),
|
|
4311
4509
|
markets: data.length,
|
|
4312
4510
|
});
|
|
4313
|
-
if (
|
|
4314
|
-
this.state.isTestnet !== preloadContext.isTestnet ||
|
|
4315
|
-
this.state.hip3ConfigVersion !== preloadContext.hip3ConfigVersion) {
|
|
4511
|
+
if (!isCurrent()) {
|
|
4316
4512
|
traceData = {
|
|
4317
4513
|
success: false,
|
|
4318
4514
|
error: 'Global snapshot preload context changed',
|
|
@@ -4337,6 +4533,13 @@ async function _PerpsController_performMarketDataPreload() {
|
|
|
4337
4533
|
}
|
|
4338
4534
|
: {};
|
|
4339
4535
|
const marketDiskEntries = [];
|
|
4536
|
+
if (!isCurrent()) {
|
|
4537
|
+
traceData = {
|
|
4538
|
+
success: false,
|
|
4539
|
+
error: 'Global snapshot preload context changed',
|
|
4540
|
+
};
|
|
4541
|
+
return;
|
|
4542
|
+
}
|
|
4340
4543
|
if (this.state.activeProvider === 'aggregated' &&
|
|
4341
4544
|
this.activeProviderInstance) {
|
|
4342
4545
|
// Split returned data by providerId and store each slice
|
|
@@ -4437,6 +4640,7 @@ async function _PerpsController_performUserDataPreload() {
|
|
|
4437
4640
|
}
|
|
4438
4641
|
const userAddress = evmAccount.address;
|
|
4439
4642
|
const { activeProvider, isTestnet, hip3ConfigVersion } = this.state;
|
|
4643
|
+
const lifecycleGeneration = __classPrivateFieldGet(this, _PerpsController_lifecycleGeneration, "f");
|
|
4440
4644
|
const { activeProviderInstance } = this;
|
|
4441
4645
|
const hyperliquidDexes = __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getStaticSnapshotDexes).call(this);
|
|
4442
4646
|
const isCurrent = () => {
|
|
@@ -4447,7 +4651,8 @@ async function _PerpsController_performUserDataPreload() {
|
|
|
4447
4651
|
catch {
|
|
4448
4652
|
return false;
|
|
4449
4653
|
}
|
|
4450
|
-
return (this
|
|
4654
|
+
return (__classPrivateFieldGet(this, _PerpsController_lifecycleGeneration, "f") === lifecycleGeneration &&
|
|
4655
|
+
this.state.activeProvider === activeProvider &&
|
|
4451
4656
|
this.activeProviderInstance === activeProviderInstance &&
|
|
4452
4657
|
this.state.isTestnet === isTestnet &&
|
|
4453
4658
|
this.state.hip3ConfigVersion === hip3ConfigVersion &&
|
|
@@ -4490,6 +4695,15 @@ async function _PerpsController_performUserDataPreload() {
|
|
|
4490
4695
|
const traceId = (0, uuid_1.v4)();
|
|
4491
4696
|
const preloadStart = performance.now();
|
|
4492
4697
|
let traceData;
|
|
4698
|
+
const staleContextError = 'User data preload context changed';
|
|
4699
|
+
const discardStalePreload = () => {
|
|
4700
|
+
if (isCurrent()) {
|
|
4701
|
+
return false;
|
|
4702
|
+
}
|
|
4703
|
+
traceData = { success: false, error: staleContextError };
|
|
4704
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Discarding stale user data preload');
|
|
4705
|
+
return true;
|
|
4706
|
+
};
|
|
4493
4707
|
try {
|
|
4494
4708
|
__classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.tracer.trace({
|
|
4495
4709
|
name: index_js_1.PerpsTraceNames.UserDataPreload,
|
|
@@ -4503,6 +4717,9 @@ async function _PerpsController_performUserDataPreload() {
|
|
|
4503
4717
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Fetching user data in background');
|
|
4504
4718
|
if (activeProvider === 'hyperliquid') {
|
|
4505
4719
|
const snapshot = await this.getUserDataSnapshot();
|
|
4720
|
+
if (discardStalePreload()) {
|
|
4721
|
+
return;
|
|
4722
|
+
}
|
|
4506
4723
|
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: User data preloaded', {
|
|
4507
4724
|
positionCount: snapshot.positions.length,
|
|
4508
4725
|
orderCount: snapshot.orders.length,
|
|
@@ -4521,8 +4738,8 @@ async function _PerpsController_performUserDataPreload() {
|
|
|
4521
4738
|
this.getOpenOrders({ standalone: true, userAddress }),
|
|
4522
4739
|
this.getAccountState({ standalone: true, userAddress }),
|
|
4523
4740
|
]);
|
|
4524
|
-
if (
|
|
4525
|
-
|
|
4741
|
+
if (discardStalePreload()) {
|
|
4742
|
+
return;
|
|
4526
4743
|
}
|
|
4527
4744
|
if (activeProvider === 'aggregated' && activeProviderInstance) {
|
|
4528
4745
|
// Split by providerId and write one cache entry per provider key
|
|
@@ -4546,6 +4763,9 @@ async function _PerpsController_performUserDataPreload() {
|
|
|
4546
4763
|
}
|
|
4547
4764
|
// AccountState — assign to its provider bucket
|
|
4548
4765
|
ensureBucket(accountState.providerId ?? fallbackProviderId).accountState = accountState;
|
|
4766
|
+
if (discardStalePreload()) {
|
|
4767
|
+
return;
|
|
4768
|
+
}
|
|
4549
4769
|
this.update((state) => {
|
|
4550
4770
|
for (const [pid, data] of byProvider) {
|
|
4551
4771
|
const key = (0, perpsConfig_js_1.buildProviderCacheKey)(pid, isTestnet);
|
|
@@ -4574,6 +4794,9 @@ async function _PerpsController_performUserDataPreload() {
|
|
|
4574
4794
|
else {
|
|
4575
4795
|
// Single provider — store directly under its key
|
|
4576
4796
|
const ts = Date.now();
|
|
4797
|
+
if (discardStalePreload()) {
|
|
4798
|
+
return;
|
|
4799
|
+
}
|
|
4577
4800
|
this.update((state) => {
|
|
4578
4801
|
state.cachedUserDataByProvider[providerNetworkKey] = {
|
|
4579
4802
|
positions,
|
|
@@ -4603,6 +4826,9 @@ async function _PerpsController_performUserDataPreload() {
|
|
|
4603
4826
|
__classPrivateFieldGet(this, _PerpsController_options, "f").infrastructure.tracer.setMeasurement(performanceMetrics_js_1.PerpsMeasurementName.PerpsUserDataPreload, performance.now() - preloadStart, 'millisecond', traceId);
|
|
4604
4827
|
}
|
|
4605
4828
|
catch (error) {
|
|
4829
|
+
if (discardStalePreload()) {
|
|
4830
|
+
return;
|
|
4831
|
+
}
|
|
4606
4832
|
traceData = {
|
|
4607
4833
|
success: false,
|
|
4608
4834
|
error: (0, errorUtils_js_1.ensureError)(error, 'PerpsController.performUserDataPreload')
|
|
@@ -4626,6 +4852,70 @@ async function _PerpsController_performUserDataPreload() {
|
|
|
4626
4852
|
});
|
|
4627
4853
|
}
|
|
4628
4854
|
}
|
|
4855
|
+
}, _PerpsController_performDisconnect =
|
|
4856
|
+
/**
|
|
4857
|
+
* Disconnect after this call has claimed the controller lifecycle.
|
|
4858
|
+
*
|
|
4859
|
+
* @returns A promise that resolves when teardown finishes.
|
|
4860
|
+
*/
|
|
4861
|
+
async function _PerpsController_performDisconnect() {
|
|
4862
|
+
__classPrivateFieldSet(this, _PerpsController_lifecycleGeneration, __classPrivateFieldGet(this, _PerpsController_lifecycleGeneration, "f") + 1, "f");
|
|
4863
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Disconnecting provider to cleanup subscriptions', {
|
|
4864
|
+
timestamp: new Date().toISOString(),
|
|
4865
|
+
});
|
|
4866
|
+
// Stop preload interval and messenger subscriptions first,
|
|
4867
|
+
// so no background work fires while we tear down providers.
|
|
4868
|
+
if (__classPrivateFieldGet(this, _PerpsController_preloadTimer, "f")) {
|
|
4869
|
+
clearInterval(__classPrivateFieldGet(this, _PerpsController_preloadTimer, "f"));
|
|
4870
|
+
__classPrivateFieldSet(this, _PerpsController_preloadTimer, null, "f");
|
|
4871
|
+
}
|
|
4872
|
+
if (__classPrivateFieldGet(this, _PerpsController_preloadStateUnsubscribe, "f")) {
|
|
4873
|
+
__classPrivateFieldGet(this, _PerpsController_preloadStateUnsubscribe, "f").call(this);
|
|
4874
|
+
__classPrivateFieldSet(this, _PerpsController_preloadStateUnsubscribe, null, "f");
|
|
4875
|
+
}
|
|
4876
|
+
if (__classPrivateFieldGet(this, _PerpsController_accountChangeUnsubscribe, "f")) {
|
|
4877
|
+
__classPrivateFieldGet(this, _PerpsController_accountChangeUnsubscribe, "f").call(this);
|
|
4878
|
+
__classPrivateFieldSet(this, _PerpsController_accountChangeUnsubscribe, null, "f");
|
|
4879
|
+
}
|
|
4880
|
+
__classPrivateFieldSet(this, _PerpsController_previousIsTestnet, null, "f");
|
|
4881
|
+
__classPrivateFieldSet(this, _PerpsController_previousHip3ConfigVersion, null, "f");
|
|
4882
|
+
const pendingReinitialization = __classPrivateFieldGet(this, _PerpsController_reinitializationOperationPromise, "f");
|
|
4883
|
+
if (pendingReinitialization) {
|
|
4884
|
+
await pendingReinitialization;
|
|
4885
|
+
}
|
|
4886
|
+
// Initialization owns provider creation. Let it finish before teardown so
|
|
4887
|
+
// it cannot repopulate providers after this method clears the references.
|
|
4888
|
+
const pendingInitialization = __classPrivateFieldGet(this, _PerpsController_initializationPromise, "f");
|
|
4889
|
+
if (pendingInitialization) {
|
|
4890
|
+
try {
|
|
4891
|
+
await pendingInitialization;
|
|
4892
|
+
}
|
|
4893
|
+
catch (error) {
|
|
4894
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_logError).call(this, (0, errorUtils_js_1.ensureError)(error, 'PerpsController.disconnect.initialization'), __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getErrorContext).call(this, 'disconnect', {
|
|
4895
|
+
operation: 'awaitInitialization',
|
|
4896
|
+
}));
|
|
4897
|
+
}
|
|
4898
|
+
}
|
|
4899
|
+
const provider = this.activeProviderInstance;
|
|
4900
|
+
if (provider) {
|
|
4901
|
+
try {
|
|
4902
|
+
await provider.disconnect();
|
|
4903
|
+
}
|
|
4904
|
+
catch (error) {
|
|
4905
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_logError).call(this, (0, errorUtils_js_1.ensureError)(error, 'PerpsController.disconnect'), __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getErrorContext).call(this, 'disconnect'));
|
|
4906
|
+
}
|
|
4907
|
+
}
|
|
4908
|
+
// Clear stale reference so standalone reads don't route through old provider
|
|
4909
|
+
this.activeProviderInstance = null;
|
|
4910
|
+
// Cleanup cached standalone provider (if any) — awaited to prevent races
|
|
4911
|
+
await __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_cleanupStandaloneProvider).call(this);
|
|
4912
|
+
// Note: Feature-flag subscription is NOT cleaned up here.
|
|
4913
|
+
// It is a controller-lifetime concern (set once in the constructor),
|
|
4914
|
+
// not a session-lifetime concern. Unsubscribing here would break
|
|
4915
|
+
// geo-blocking / HIP-3 flag propagation after disconnect → reconnect.
|
|
4916
|
+
// Reset initialization state to ensure proper reconnection
|
|
4917
|
+
this.isInitialized = false;
|
|
4918
|
+
__classPrivateFieldSet(this, _PerpsController_initializationPromise, null, "f");
|
|
4629
4919
|
}, _PerpsController_persistWatchlistToRemote =
|
|
4630
4920
|
/**
|
|
4631
4921
|
* Writes the current local watchlist to AuthenticatedUserStorageService
|