@metamask-previews/perps-controller 8.3.0-preview-55f166437 → 8.3.0-preview-e80844493
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 +13 -0
- package/dist/PerpsController-method-action-types.cjs.map +1 -1
- package/dist/PerpsController-method-action-types.d.cts +11 -2
- package/dist/PerpsController-method-action-types.d.cts.map +1 -1
- package/dist/PerpsController-method-action-types.d.mts +11 -2
- 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 +221 -8
- package/dist/PerpsController.cjs.map +1 -1
- package/dist/PerpsController.d.cts +26 -3
- package/dist/PerpsController.d.cts.map +1 -1
- package/dist/PerpsController.d.mts +26 -3
- package/dist/PerpsController.d.mts.map +1 -1
- package/dist/PerpsController.mjs +219 -7
- package/dist/PerpsController.mjs.map +1 -1
- package/dist/types/messenger.cjs.map +1 -1
- package/dist/types/messenger.d.cts +2 -1
- package/dist/types/messenger.d.cts.map +1 -1
- package/dist/types/messenger.d.mts +2 -1
- package/dist/types/messenger.d.mts.map +1 -1
- package/dist/types/messenger.mjs.map +1 -1
- package/package.json +2 -1
package/dist/PerpsController.cjs
CHANGED
|
@@ -10,9 +10,9 @@ 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_isMYXProviderEnabled, _PerpsController_standaloneProvider, _PerpsController_handlersRegistered, _PerpsController_standaloneProviderIsTestnet, _PerpsController_standaloneProviderHip3Version, _PerpsController_eligibilityCheckDeferred, _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;
|
|
13
|
+
var _PerpsController_instances, _a, _PerpsController_initializationPromise, _PerpsController_isReinitializing, _PerpsController_myxRegistrationPromise, _PerpsController_blockedRegionListVersion, _PerpsController_hip3Enabled, _PerpsController_hip3AllowlistMarkets, _PerpsController_hip3BlocklistMarkets, _PerpsController_hip3ConfigSource, _PerpsController_priceDeviationLimit, _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
|
-
exports.PerpsController = exports.getDefaultPerpsControllerState = exports.InitializationState = exports.PERPS_ERROR_CODES = exports.resolveMyxAuthConfig = exports.firstNonEmpty = void 0;
|
|
15
|
+
exports.PerpsController = exports.getDefaultPerpsControllerState = exports.InitializationState = exports.PERPS_ERROR_CODES = exports.resolveMyxAuthConfig = exports.resolveWatchlistExchangeKey = exports.firstNonEmpty = void 0;
|
|
16
16
|
const base_controller_1 = require("@metamask/base-controller");
|
|
17
17
|
const controller_utils_1 = require("@metamask/controller-utils");
|
|
18
18
|
const uuid_1 = require("uuid");
|
|
@@ -52,6 +52,26 @@ function firstNonEmpty(...vals) {
|
|
|
52
52
|
return (vals.find((val) => val !== null && val !== undefined && val !== '') ?? '');
|
|
53
53
|
}
|
|
54
54
|
exports.firstNonEmpty = firstNonEmpty;
|
|
55
|
+
/**
|
|
56
|
+
* Maps an active provider mode to the corresponding exchange key used in the
|
|
57
|
+
* AUS {@link PerpsWatchlistMarkets} schema.
|
|
58
|
+
*
|
|
59
|
+
* Returns `null` for modes that are not yet represented in the AUS schema
|
|
60
|
+
* (e.g. `'aggregated'`), which signals callers to skip remote sync and fall
|
|
61
|
+
* back to local state only. Add new entries here as additional DEX providers
|
|
62
|
+
* gain AUS watchlist support.
|
|
63
|
+
*
|
|
64
|
+
* @param activeProvider - The current active provider mode from controller state.
|
|
65
|
+
* @returns The matching `PerpsWatchlistMarkets` key, or `null` if unsupported.
|
|
66
|
+
*/
|
|
67
|
+
function resolveWatchlistExchangeKey(activeProvider) {
|
|
68
|
+
const map = {
|
|
69
|
+
hyperliquid: 'hyperliquid',
|
|
70
|
+
myx: 'myx',
|
|
71
|
+
};
|
|
72
|
+
return map[activeProvider] ?? null;
|
|
73
|
+
}
|
|
74
|
+
exports.resolveWatchlistExchangeKey = resolveWatchlistExchangeKey;
|
|
55
75
|
/**
|
|
56
76
|
* Resolves MYX auth config from provider credentials, handling
|
|
57
77
|
* testnet/mainnet fallback logic.
|
|
@@ -480,6 +500,20 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
480
500
|
_PerpsController_standaloneProviderIsTestnet.set(this, null);
|
|
481
501
|
_PerpsController_standaloneProviderHip3Version.set(this, null);
|
|
482
502
|
_PerpsController_eligibilityCheckDeferred.set(this, void 0);
|
|
503
|
+
/**
|
|
504
|
+
* Serial promise queue for all AUS watchlist operations (hydration and
|
|
505
|
+
* individual toggles). Chaining every operation onto this field ensures
|
|
506
|
+
* that:
|
|
507
|
+
*
|
|
508
|
+
* - A toggle that fires immediately after init() always runs *after* the
|
|
509
|
+
* init hydration finishes (Bug 3).
|
|
510
|
+
* - Concurrent toggles are serialised so the last PUT reflects all changes
|
|
511
|
+
* rather than racing with each other (Bug 4).
|
|
512
|
+
*
|
|
513
|
+
* Errors from individual operations are swallowed inside the queue so that
|
|
514
|
+
* a failed operation does not stall subsequent ones.
|
|
515
|
+
*/
|
|
516
|
+
_PerpsController_ausQueue.set(this, Promise.resolve());
|
|
483
517
|
// Store options for dependency injection (allows core package to inject platform-specific services)
|
|
484
518
|
_PerpsController_options.set(this, void 0);
|
|
485
519
|
// Service instances (instantiated with platform dependencies)
|
|
@@ -2946,12 +2980,21 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2946
2980
|
});
|
|
2947
2981
|
}
|
|
2948
2982
|
/**
|
|
2949
|
-
* Toggle watchlist status for a market
|
|
2950
|
-
*
|
|
2983
|
+
* Toggle watchlist status for a market.
|
|
2984
|
+
*
|
|
2985
|
+
* Updates local state immediately (optimistic UI) and then syncs the new
|
|
2986
|
+
* watchlist to AuthenticatedUserStorageService. If the remote write fails,
|
|
2987
|
+
* the local state is reverted so it stays consistent with AUS.
|
|
2988
|
+
*
|
|
2989
|
+
* When the user is unauthenticated, or the active provider is not yet
|
|
2990
|
+
* supported by the AUS schema, the controller continues operating with
|
|
2991
|
+
* local-persisted state only — no error is surfaced to the caller.
|
|
2992
|
+
*
|
|
2993
|
+
* Watchlist markets are stored per network (testnet/mainnet).
|
|
2951
2994
|
*
|
|
2952
2995
|
* @param symbol - The trading pair symbol.
|
|
2953
2996
|
*/
|
|
2954
|
-
toggleWatchlistMarket(symbol) {
|
|
2997
|
+
async toggleWatchlistMarket(symbol) {
|
|
2955
2998
|
const currentNetwork = this.state.isTestnet ? 'testnet' : 'mainnet';
|
|
2956
2999
|
const currentWatchlist = this.state.watchlistMarkets[currentNetwork];
|
|
2957
3000
|
const isWatchlisted = currentWatchlist.includes(symbol);
|
|
@@ -2961,16 +3004,47 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
2961
3004
|
symbol,
|
|
2962
3005
|
action: isWatchlisted ? 'remove' : 'add',
|
|
2963
3006
|
});
|
|
3007
|
+
// Step 1: Optimistic local state update — UI reflects change immediately.
|
|
2964
3008
|
this.update((state) => {
|
|
2965
3009
|
if (isWatchlisted) {
|
|
2966
|
-
// Remove from watchlist
|
|
2967
3010
|
state.watchlistMarkets[currentNetwork] = currentWatchlist.filter((marketSymbol) => marketSymbol !== symbol);
|
|
2968
3011
|
}
|
|
2969
3012
|
else {
|
|
2970
|
-
// Add to watchlist
|
|
2971
3013
|
state.watchlistMarkets[currentNetwork] = [...currentWatchlist, symbol];
|
|
2972
3014
|
}
|
|
2973
3015
|
});
|
|
3016
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getMetrics).call(this).trackPerpsEvent(types_1.PerpsAnalyticsEvent.UiInteraction, {
|
|
3017
|
+
[eventNames_1.PERPS_EVENT_PROPERTY.INTERACTION_TYPE]: eventNames_1.PERPS_EVENT_VALUE.INTERACTION_TYPE.FAVORITE_TOGGLED,
|
|
3018
|
+
[eventNames_1.PERPS_EVENT_PROPERTY.ASSET]: symbol,
|
|
3019
|
+
[eventNames_1.PERPS_EVENT_PROPERTY.ACTION_TYPE]: isWatchlisted
|
|
3020
|
+
? eventNames_1.PERPS_EVENT_VALUE.ACTION_TYPE.UNFAVORITE_MARKET
|
|
3021
|
+
: eventNames_1.PERPS_EVENT_VALUE.ACTION_TYPE.FAVORITE_MARKET,
|
|
3022
|
+
[eventNames_1.PERPS_EVENT_PROPERTY.FAVORITES_COUNT]: this.state.watchlistMarkets[currentNetwork].length,
|
|
3023
|
+
});
|
|
3024
|
+
// Step 2: Persist to AUS; revert local state if the write fails.
|
|
3025
|
+
// Enqueue behind #ausQueue so that:
|
|
3026
|
+
// - concurrent toggles serialize their GET-merge-PUT sequences, and
|
|
3027
|
+
// - any in-flight init hydration completes before we issue a write.
|
|
3028
|
+
try {
|
|
3029
|
+
await new Promise((resolve, reject) => {
|
|
3030
|
+
__classPrivateFieldSet(this, _PerpsController_ausQueue, __classPrivateFieldGet(this, _PerpsController_ausQueue, "f")
|
|
3031
|
+
.then(() => __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_persistWatchlistToRemote).call(this, currentNetwork))
|
|
3032
|
+
.then(resolve, reject)
|
|
3033
|
+
// Swallow the error on the queue chain so later operations can run.
|
|
3034
|
+
.catch(() => undefined), "f");
|
|
3035
|
+
});
|
|
3036
|
+
}
|
|
3037
|
+
catch (error) {
|
|
3038
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_logError).call(this, (0, errorUtils_1.ensureError)(error, 'PerpsController.toggleWatchlistMarket'), __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getErrorContext).call(this, 'toggleWatchlistMarket', {
|
|
3039
|
+
symbol,
|
|
3040
|
+
network: currentNetwork,
|
|
3041
|
+
action: isWatchlisted ? 'remove' : 'add',
|
|
3042
|
+
}));
|
|
3043
|
+
// Revert the optimistic update.
|
|
3044
|
+
this.update((state) => {
|
|
3045
|
+
state.watchlistMarkets[currentNetwork] = currentWatchlist;
|
|
3046
|
+
});
|
|
3047
|
+
}
|
|
2974
3048
|
}
|
|
2975
3049
|
/**
|
|
2976
3050
|
* Check if a market is in the watchlist on the current network
|
|
@@ -3026,7 +3100,7 @@ class PerpsController extends base_controller_1.BaseController {
|
|
|
3026
3100
|
}
|
|
3027
3101
|
}
|
|
3028
3102
|
exports.PerpsController = PerpsController;
|
|
3029
|
-
_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_standaloneProvider = new WeakMap(), _PerpsController_handlersRegistered = new WeakMap(), _PerpsController_standaloneProviderIsTestnet = new WeakMap(), _PerpsController_standaloneProviderHip3Version = new WeakMap(), _PerpsController_eligibilityCheckDeferred = 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() {
|
|
3103
|
+
_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_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() {
|
|
3030
3104
|
const myx = __classPrivateFieldGet(this, _PerpsController_options, "f").clientConfig?.providerCredentials?.myx;
|
|
3031
3105
|
// Local env-var override (MM_PERPS_MYX_PROVIDER_ENABLED) always wins —
|
|
3032
3106
|
// matches the UI selector (resolvePerpsMyxProviderEnabled) so controller
|
|
@@ -3284,6 +3358,13 @@ async function _PerpsController_performInitialization() {
|
|
|
3284
3358
|
timestamp: new Date().toISOString(),
|
|
3285
3359
|
attempts: attempt,
|
|
3286
3360
|
});
|
|
3361
|
+
// Hydrate watchlist from AUS (non-blocking — transient failures are
|
|
3362
|
+
// caught inside and must not prevent init from completing).
|
|
3363
|
+
// Assigning to #ausQueue ensures subsequent toggleWatchlistMarket
|
|
3364
|
+
// calls wait for hydration before running their own GET-merge-PUT.
|
|
3365
|
+
__classPrivateFieldSet(this, _PerpsController_ausQueue, __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_syncWatchlistFromRemote).call(this).catch(() => {
|
|
3366
|
+
// Errors are already logged inside #syncWatchlistFromRemote.
|
|
3367
|
+
}), "f");
|
|
3287
3368
|
return; // Exit retry loop on success
|
|
3288
3369
|
}
|
|
3289
3370
|
catch (error) {
|
|
@@ -3763,6 +3844,138 @@ async function _PerpsController_performUserDataPreload() {
|
|
|
3763
3844
|
});
|
|
3764
3845
|
__classPrivateFieldSet(this, _PerpsController_isPreloadingUserData, false, "f");
|
|
3765
3846
|
}
|
|
3847
|
+
}, _PerpsController_persistWatchlistToRemote =
|
|
3848
|
+
/**
|
|
3849
|
+
* Writes the current local watchlist to AuthenticatedUserStorageService
|
|
3850
|
+
* using a read-merge-write strategy to avoid overwriting other preferences.
|
|
3851
|
+
*
|
|
3852
|
+
* Skips silently when:
|
|
3853
|
+
* - The active provider has no AUS exchange key (e.g. `'aggregated'`).
|
|
3854
|
+
* - The remote preferences blob does not yet exist (returns `null` / 404).
|
|
3855
|
+
* In that case, `NotificationServicesController.createOnChainTriggers` is
|
|
3856
|
+
* the canonical owner that creates the initial blob.
|
|
3857
|
+
*
|
|
3858
|
+
* Throws on remote write failure so the caller can decide whether to revert.
|
|
3859
|
+
*
|
|
3860
|
+
* @param network - Which network's list to sync ('testnet' | 'mainnet').
|
|
3861
|
+
*/
|
|
3862
|
+
async function _PerpsController_persistWatchlistToRemote(network) {
|
|
3863
|
+
const exchangeKey = resolveWatchlistExchangeKey(this.state.activeProvider);
|
|
3864
|
+
if (!exchangeKey) {
|
|
3865
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Skipping AUS watchlist sync — provider not mapped', { activeProvider: this.state.activeProvider });
|
|
3866
|
+
return;
|
|
3867
|
+
}
|
|
3868
|
+
const prefs = await this.messenger.call('AuthenticatedUserStorageService:getNotificationPreferences');
|
|
3869
|
+
if (!prefs) {
|
|
3870
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Skipping AUS watchlist write — preferences blob not yet initialised', { exchangeKey, network });
|
|
3871
|
+
return;
|
|
3872
|
+
}
|
|
3873
|
+
const existingWatchlist = prefs.perps
|
|
3874
|
+
.watchlistMarkets ?? {
|
|
3875
|
+
hyperliquid: { testnet: [], mainnet: [] },
|
|
3876
|
+
myx: { testnet: [], mainnet: [] },
|
|
3877
|
+
};
|
|
3878
|
+
const nextWatchlistMarkets = {
|
|
3879
|
+
...existingWatchlist,
|
|
3880
|
+
[exchangeKey]: {
|
|
3881
|
+
...existingWatchlist[exchangeKey],
|
|
3882
|
+
[network]: this.state.watchlistMarkets[network],
|
|
3883
|
+
},
|
|
3884
|
+
};
|
|
3885
|
+
const nextPrefs = {
|
|
3886
|
+
...prefs,
|
|
3887
|
+
perps: {
|
|
3888
|
+
...prefs.perps,
|
|
3889
|
+
watchlistMarkets: nextWatchlistMarkets,
|
|
3890
|
+
},
|
|
3891
|
+
};
|
|
3892
|
+
await this.messenger.call('AuthenticatedUserStorageService:putNotificationPreferences', nextPrefs);
|
|
3893
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Watchlist synced to AUS', {
|
|
3894
|
+
exchangeKey,
|
|
3895
|
+
network,
|
|
3896
|
+
count: this.state.watchlistMarkets[network].length,
|
|
3897
|
+
});
|
|
3898
|
+
}, _PerpsController_syncWatchlistFromRemote =
|
|
3899
|
+
/**
|
|
3900
|
+
* Hydrates `state.watchlistMarkets` from AuthenticatedUserStorageService on
|
|
3901
|
+
* controller initialisation.
|
|
3902
|
+
*
|
|
3903
|
+
* AUS is the source of truth; local state is used as an offline cache.
|
|
3904
|
+
* This method also handles the one-time migration from local-only state to
|
|
3905
|
+
* AUS for users who had a watchlist before AUS sync was introduced.
|
|
3906
|
+
*
|
|
3907
|
+
* All remote errors are swallowed so a transient network failure does not
|
|
3908
|
+
* block the rest of `init()`.
|
|
3909
|
+
*/
|
|
3910
|
+
async function _PerpsController_syncWatchlistFromRemote() {
|
|
3911
|
+
const exchangeKey = resolveWatchlistExchangeKey(this.state.activeProvider);
|
|
3912
|
+
if (!exchangeKey) {
|
|
3913
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Skipping AUS watchlist hydration — provider not mapped', { activeProvider: this.state.activeProvider });
|
|
3914
|
+
return;
|
|
3915
|
+
}
|
|
3916
|
+
try {
|
|
3917
|
+
const prefs = await this.messenger.call('AuthenticatedUserStorageService:getNotificationPreferences');
|
|
3918
|
+
if (!prefs) {
|
|
3919
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: No AUS preferences blob — using local watchlist');
|
|
3920
|
+
return;
|
|
3921
|
+
}
|
|
3922
|
+
const remoteExchangeWatchlist = prefs.perps.watchlistMarkets?.[exchangeKey];
|
|
3923
|
+
// AUS is the source of truth: an absent exchange key means this device
|
|
3924
|
+
// has not been migrated yet — push any local favorites up once.
|
|
3925
|
+
// A present key (even with empty arrays) must be honored as-is,
|
|
3926
|
+
// including an intentional remote clear.
|
|
3927
|
+
if (remoteExchangeWatchlist === undefined) {
|
|
3928
|
+
// Blob exists but has no watchlist for this exchange yet.
|
|
3929
|
+
// If local state has any markets, push them up as a one-time migration.
|
|
3930
|
+
const { testnet, mainnet } = this.state.watchlistMarkets;
|
|
3931
|
+
const hasLocalMarkets = testnet.length > 0 || mainnet.length > 0;
|
|
3932
|
+
if (hasLocalMarkets) {
|
|
3933
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Migrating local watchlist to AUS', {
|
|
3934
|
+
exchangeKey,
|
|
3935
|
+
testnetCount: testnet.length,
|
|
3936
|
+
mainnetCount: mainnet.length,
|
|
3937
|
+
});
|
|
3938
|
+
// Push testnet and mainnet together via a single read-merge-write.
|
|
3939
|
+
// Start from existing remote watchlistMarkets (or empty fallback) so
|
|
3940
|
+
// that other exchanges already stored in AUS are not overwritten.
|
|
3941
|
+
const existingWatchlist = prefs.perps
|
|
3942
|
+
.watchlistMarkets ?? {
|
|
3943
|
+
hyperliquid: { testnet: [], mainnet: [] },
|
|
3944
|
+
myx: { testnet: [], mainnet: [] },
|
|
3945
|
+
};
|
|
3946
|
+
const nextWatchlistMarkets = {
|
|
3947
|
+
...existingWatchlist,
|
|
3948
|
+
[exchangeKey]: { testnet, mainnet },
|
|
3949
|
+
};
|
|
3950
|
+
const nextPrefs = {
|
|
3951
|
+
...prefs,
|
|
3952
|
+
perps: {
|
|
3953
|
+
...prefs.perps,
|
|
3954
|
+
watchlistMarkets: nextWatchlistMarkets,
|
|
3955
|
+
},
|
|
3956
|
+
};
|
|
3957
|
+
await this.messenger.call('AuthenticatedUserStorageService:putNotificationPreferences', nextPrefs);
|
|
3958
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Local watchlist migrated to AUS', {
|
|
3959
|
+
exchangeKey,
|
|
3960
|
+
});
|
|
3961
|
+
}
|
|
3962
|
+
}
|
|
3963
|
+
else {
|
|
3964
|
+
// AUS has an entry for this exchange — hydrate local state from it.
|
|
3965
|
+
this.update((state) => {
|
|
3966
|
+
state.watchlistMarkets.testnet = remoteExchangeWatchlist.testnet;
|
|
3967
|
+
state.watchlistMarkets.mainnet = remoteExchangeWatchlist.mainnet;
|
|
3968
|
+
});
|
|
3969
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_debugLog).call(this, 'PerpsController: Watchlist hydrated from AUS', {
|
|
3970
|
+
exchangeKey,
|
|
3971
|
+
testnetCount: remoteExchangeWatchlist.testnet.length,
|
|
3972
|
+
mainnetCount: remoteExchangeWatchlist.mainnet.length,
|
|
3973
|
+
});
|
|
3974
|
+
}
|
|
3975
|
+
}
|
|
3976
|
+
catch (error) {
|
|
3977
|
+
__classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_logError).call(this, (0, errorUtils_1.ensureError)(error, 'PerpsController.syncWatchlistFromRemote'), __classPrivateFieldGet(this, _PerpsController_instances, "m", _PerpsController_getErrorContext).call(this, 'syncWatchlistFromRemote'));
|
|
3978
|
+
}
|
|
3766
3979
|
};
|
|
3767
3980
|
// ============================================================================
|
|
3768
3981
|
// Market Data Preload (client-agnostic background caching)
|