@metamask-previews/assets-controller 9.1.0-preview-e12e4a38f → 9.1.0-preview-4f9d41d
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -2
- package/dist/AssetsController.cjs +309 -136
- package/dist/AssetsController.cjs.map +1 -1
- package/dist/AssetsController.d.cts +11 -8
- package/dist/AssetsController.d.cts.map +1 -1
- package/dist/AssetsController.d.mts +11 -8
- package/dist/AssetsController.d.mts.map +1 -1
- package/dist/AssetsController.mjs +309 -136
- package/dist/AssetsController.mjs.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.cjs +10 -0
- package/dist/data-sources/AccountsApiDataSource.cjs.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.d.cts +8 -0
- package/dist/data-sources/AccountsApiDataSource.d.cts.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.d.mts +8 -0
- package/dist/data-sources/AccountsApiDataSource.d.mts.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.mjs +10 -0
- package/dist/data-sources/AccountsApiDataSource.mjs.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.cjs +36 -60
- package/dist/data-sources/BackendWebsocketDataSource.cjs.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.d.cts +8 -0
- package/dist/data-sources/BackendWebsocketDataSource.d.cts.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.d.mts +8 -0
- package/dist/data-sources/BackendWebsocketDataSource.d.mts.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.mjs +36 -57
- package/dist/data-sources/BackendWebsocketDataSource.mjs.map +1 -1
- package/dist/data-sources/PriceDataSource.cjs +18 -9
- package/dist/data-sources/PriceDataSource.cjs.map +1 -1
- package/dist/data-sources/PriceDataSource.d.cts.map +1 -1
- package/dist/data-sources/PriceDataSource.d.mts.map +1 -1
- package/dist/data-sources/PriceDataSource.mjs +19 -10
- package/dist/data-sources/PriceDataSource.mjs.map +1 -1
- package/dist/data-sources/RpcDataSource.cjs +29 -9
- package/dist/data-sources/RpcDataSource.cjs.map +1 -1
- package/dist/data-sources/RpcDataSource.d.cts +5 -0
- package/dist/data-sources/RpcDataSource.d.cts.map +1 -1
- package/dist/data-sources/RpcDataSource.d.mts +5 -0
- package/dist/data-sources/RpcDataSource.d.mts.map +1 -1
- package/dist/data-sources/RpcDataSource.mjs +29 -9
- package/dist/data-sources/RpcDataSource.mjs.map +1 -1
- package/dist/middlewares/DetectionMiddleware.cjs +22 -1
- package/dist/middlewares/DetectionMiddleware.cjs.map +1 -1
- package/dist/middlewares/DetectionMiddleware.d.cts +3 -0
- package/dist/middlewares/DetectionMiddleware.d.cts.map +1 -1
- package/dist/middlewares/DetectionMiddleware.d.mts +3 -0
- package/dist/middlewares/DetectionMiddleware.d.mts.map +1 -1
- package/dist/middlewares/DetectionMiddleware.mjs +22 -1
- package/dist/middlewares/DetectionMiddleware.mjs.map +1 -1
- package/dist/middlewares/ParallelMiddleware.cjs +7 -0
- package/dist/middlewares/ParallelMiddleware.cjs.map +1 -1
- package/dist/middlewares/ParallelMiddleware.d.cts.map +1 -1
- package/dist/middlewares/ParallelMiddleware.d.mts.map +1 -1
- package/dist/middlewares/ParallelMiddleware.mjs +7 -0
- package/dist/middlewares/ParallelMiddleware.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +18 -9
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +18 -9
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/dedupingBatchFetcher.cjs +11 -0
- package/dist/utils/dedupingBatchFetcher.cjs.map +1 -1
- package/dist/utils/dedupingBatchFetcher.d.cts +7 -0
- package/dist/utils/dedupingBatchFetcher.d.cts.map +1 -1
- package/dist/utils/dedupingBatchFetcher.d.mts +7 -0
- package/dist/utils/dedupingBatchFetcher.d.mts.map +1 -1
- package/dist/utils/dedupingBatchFetcher.mjs +11 -0
- package/dist/utils/dedupingBatchFetcher.mjs.map +1 -1
- package/dist/utils/processAccountActivityBalanceUpdates.cjs +54 -0
- package/dist/utils/processAccountActivityBalanceUpdates.cjs.map +1 -0
- package/dist/utils/processAccountActivityBalanceUpdates.d.cts +13 -0
- package/dist/utils/processAccountActivityBalanceUpdates.d.cts.map +1 -0
- package/dist/utils/processAccountActivityBalanceUpdates.d.mts +13 -0
- package/dist/utils/processAccountActivityBalanceUpdates.d.mts.map +1 -0
- package/dist/utils/processAccountActivityBalanceUpdates.mjs +47 -0
- package/dist/utils/processAccountActivityBalanceUpdates.mjs.map +1 -0
- package/package.json +1 -1
|
@@ -13,7 +13,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
13
13
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
15
|
};
|
|
16
|
-
var _AssetsController_instances, _AssetsController_isEnabled, _AssetsController_isBasicFunctionality, _AssetsController_defaultUpdateInterval, _AssetsController_trace, _AssetsController_captureException, _AssetsController_firstInitFetchReported, _AssetsController_stateSizeReported, _AssetsController_emitTrace, _AssetsController_emitStateSizeTrace, _AssetsController_uiOpen, _AssetsController_keyringUnlocked, _AssetsController_controllerMutex, _AssetsController_accountRefreshMutex, _AssetsController_activeSubscriptions, _AssetsController_enabledChains, _AssetsController_lastKnownAccountIds,
|
|
16
|
+
var _AssetsController_instances, _AssetsController_isEnabled, _AssetsController_isBasicFunctionality, _AssetsController_defaultUpdateInterval, _AssetsController_trace, _AssetsController_captureException, _AssetsController_firstInitFetchReported, _AssetsController_stateSizeReported, _AssetsController_emitTrace, _AssetsController_emitStateSizeTrace, _AssetsController_uiOpen, _AssetsController_keyringUnlocked, _AssetsController_controllerMutex, _AssetsController_accountRefreshMutex, _AssetsController_activeSubscriptions, _AssetsController_enabledChains, _AssetsController_lastKnownAccountIds, _AssetsController_getSelectedAccounts, _AssetsController_backendWebsocketDataSource, _AssetsController_accountsApiDataSource, _AssetsController_snapDataSource, _AssetsController_rpcDataSource, _AssetsController_stakedBalanceDataSource, _AssetsController_allBalanceDataSources_get, _AssetsController_priceDataSource, _AssetsController_detectionMiddleware, _AssetsController_customAssetGraduationMiddleware, _AssetsController_rpcFallbackMiddleware, _AssetsController_tokenDataSource, _AssetsController_unsubscribeBasicFunctionality, _AssetsController_queryApiClient, _AssetsController_onActiveChainsUpdated, _AssetsController_initializeNativeAssetsMap, _AssetsController_initializeState, _AssetsController_extractEnabledChains, _AssetsController_normalizeChainReference, _AssetsController_subscribeToEvents, _AssetsController_onUnapprovedTransactionAdded, _AssetsController_onTransactionConfirmed, _AssetsController_onAccountActivityBalanceUpdated, _AssetsController_updateActive, _AssetsController_handleAccountTreeStateChange, _AssetsController_runAccountTreeRefresh, _AssetsController_runStartupRefresh, _AssetsController_registerActionHandlers, _AssetsController_handleActiveChainsUpdate, _AssetsController_executeMiddlewares, _AssetsController_fetchMissingPricesWithoutCache, _AssetsController_getNativeAssetMap, _AssetsController_isNativeAsset, _AssetsController_getAssetType, _AssetsController_resolveNativeAssetIds, _AssetsController_getNativeAssetIdsForEnabledChains, _AssetsController_getNativeAssetIdsForAccount, _AssetsController_getSlowPipelineChainIds, _AssetsController_ensureNativeBalancesDefaultZero, _AssetsController_ensureDefaultTrackedAssetsSeeded, _AssetsController_updateState, _AssetsController_getAssetsFromState, _AssetsController_shouldHideNativeToken, _AssetsController_tokenStandardToAssetType, _AssetsController_start, _AssetsController_stop, _AssetsController_subscribeAssets, _AssetsController_subscribeAssetsBalance, _AssetsController_subscribeRpcCustomAssetsSupplement, _AssetsController_unsubscribeBySubscriptionKey, _AssetsController_subscribeStakedBalance, _AssetsController_buildChainToAccountsMap, _AssetsController_subscribeDataSource, _AssetsController_unsubscribeDataSource, _AssetsController_buildDataRequest, _AssetsController_getEnabledChainsForAccount, _AssetsController_handleAccountGroupChanged, _AssetsController_handleEnabledNetworksChanged, _AssetsController_handleNetworkAdded, _AssetsController_refreshActiveChainsOnNetworkSwitch, _AssetsController_getSelectedEvmChainIdFromNetworkState, _AssetsController_handleNetworkDidChange, _AssetsController_refreshAssetsAfterNetworkChange, _AssetsController_refreshAssetsAfterNetworkAdded;
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.AssetsController = exports.getDefaultAssetsControllerState = void 0;
|
|
19
19
|
const base_controller_1 = require("@metamask/base-controller");
|
|
@@ -40,6 +40,7 @@ const RpcFallbackMiddleware_1 = require("./middlewares/RpcFallbackMiddleware.cjs
|
|
|
40
40
|
const utils_2 = require("./utils/index.cjs");
|
|
41
41
|
const constants_1 = require("./utils/constants.cjs");
|
|
42
42
|
const customAssetsRpcSupplement_1 = require("./utils/customAssetsRpcSupplement.cjs");
|
|
43
|
+
const processAccountActivityBalanceUpdates_1 = require("./utils/processAccountActivityBalanceUpdates.cjs");
|
|
43
44
|
const NATIVE_ASSETS_QUERY_KEY = ['nativeAssets'];
|
|
44
45
|
// ============================================================================
|
|
45
46
|
// CONTROLLER CONSTANTS
|
|
@@ -62,15 +63,6 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
62
63
|
];
|
|
63
64
|
/** Default polling interval hint for data sources (30 seconds) */
|
|
64
65
|
const DEFAULT_POLLING_INTERVAL_MS = 30000;
|
|
65
|
-
/** Sources whose passive polling must not overwrite recent websocket balances. */
|
|
66
|
-
const POLLING_BALANCE_SOURCES = new Set([
|
|
67
|
-
'AccountsApiDataSource',
|
|
68
|
-
'RpcDataSource',
|
|
69
|
-
'SnapDataSource',
|
|
70
|
-
'StakedBalanceDataSource',
|
|
71
|
-
]);
|
|
72
|
-
/** How long websocket balance updates block stale polling overwrites. */
|
|
73
|
-
const WS_BALANCE_FRESHNESS_MS = 120000;
|
|
74
66
|
// ============================================================================
|
|
75
67
|
// TRACE NAMES — used in Sentry spans (search these strings in Discover)
|
|
76
68
|
// ============================================================================
|
|
@@ -201,11 +193,41 @@ function normalizeResponse(response) {
|
|
|
201
193
|
if (response.updateMode) {
|
|
202
194
|
normalized.updateMode = response.updateMode;
|
|
203
195
|
}
|
|
204
|
-
if (response.
|
|
205
|
-
normalized.
|
|
196
|
+
if (response.replaceCoveredChainBalances) {
|
|
197
|
+
normalized.replaceCoveredChainBalances = true;
|
|
206
198
|
}
|
|
207
199
|
return normalized;
|
|
208
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* Merge account balances from a data-source response into prior state.
|
|
203
|
+
*
|
|
204
|
+
* @param previousBalances - Balances already in state for this account.
|
|
205
|
+
* @param accountBalances - Balances from the incoming response.
|
|
206
|
+
* @param customAssetIds - Custom assets to preserve when replacing covered chains.
|
|
207
|
+
* @param replaceCoveredChains - When true, drop prior balances on chains present
|
|
208
|
+
* in the response before applying it (authoritative chain slice).
|
|
209
|
+
* @returns The merged balance map for the account.
|
|
210
|
+
*/
|
|
211
|
+
function mergeAccountBalances(previousBalances, accountBalances, customAssetIds, replaceCoveredChains) {
|
|
212
|
+
if (!replaceCoveredChains) {
|
|
213
|
+
return { ...previousBalances, ...accountBalances };
|
|
214
|
+
}
|
|
215
|
+
const coveredChains = new Set(Object.keys(accountBalances).map((assetId) => assetId.split('/')[0]));
|
|
216
|
+
const next = {};
|
|
217
|
+
for (const [assetId, balance] of Object.entries(previousBalances)) {
|
|
218
|
+
if (!coveredChains.has(assetId.split('/')[0])) {
|
|
219
|
+
next[assetId] = balance;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
Object.assign(next, accountBalances);
|
|
223
|
+
for (const customId of customAssetIds) {
|
|
224
|
+
if (!Object.prototype.hasOwnProperty.call(next, customId)) {
|
|
225
|
+
const prev = previousBalances[customId];
|
|
226
|
+
next[customId] = prev ?? { amount: '0' };
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return next;
|
|
230
|
+
}
|
|
209
231
|
// ============================================================================
|
|
210
232
|
// CONTROLLER IMPLEMENTATION
|
|
211
233
|
// ============================================================================
|
|
@@ -284,11 +306,6 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
284
306
|
* re-subscriptions when the account set hasn't actually changed.
|
|
285
307
|
*/
|
|
286
308
|
_AssetsController_lastKnownAccountIds.set(this, new Set());
|
|
287
|
-
/**
|
|
288
|
-
* Per `accountId:assetId`, timestamp until which websocket balance updates
|
|
289
|
-
* should not be overwritten by polling/API fetches.
|
|
290
|
-
*/
|
|
291
|
-
_AssetsController_wsBalanceFreshUntil.set(this, new Map());
|
|
292
309
|
_AssetsController_backendWebsocketDataSource.set(this, void 0);
|
|
293
310
|
_AssetsController_accountsApiDataSource.set(this, void 0);
|
|
294
311
|
_AssetsController_snapDataSource.set(this, void 0);
|
|
@@ -437,9 +454,9 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
437
454
|
// creation, RPC is slow on many chains). Results are committed to state
|
|
438
455
|
// immediately so the UI can display balances without waiting for them.
|
|
439
456
|
//
|
|
440
|
-
//
|
|
441
|
-
//
|
|
442
|
-
//
|
|
457
|
+
// Fast/slow pipelines use merge so partial API snapshots cannot wipe
|
|
458
|
+
// tokens missing from the response (e.g. USDC when only native balance
|
|
459
|
+
// is returned). Balances present in the response are still refreshed.
|
|
443
460
|
const fastSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
444
461
|
? [
|
|
445
462
|
(0, ParallelMiddleware_1.createParallelBalanceMiddleware)([
|
|
@@ -459,39 +476,36 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
459
476
|
]
|
|
460
477
|
: [__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f")];
|
|
461
478
|
const { response, durationByDataSource } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, fastSources, request);
|
|
462
|
-
// The fast pipeline only contains a subset of data sources (AccountsApi +
|
|
463
|
-
// StakedBalance), so it must always merge to avoid wiping Snap/RPC
|
|
464
|
-
// balances that the background pipeline hasn't yet replaced.
|
|
465
479
|
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
466
480
|
...response,
|
|
467
481
|
updateMode: 'merge',
|
|
468
|
-
|
|
482
|
+
replaceCoveredChainBalances: true,
|
|
469
483
|
});
|
|
470
484
|
// Background pipeline: snap and RPC run in parallel after the fast path
|
|
471
485
|
// commits to state. Their balances are merged together before detection.
|
|
472
486
|
// Token + price enrichment matches the pre-split behavior: only when basic
|
|
473
487
|
// functionality is on (RPC-only mode must not call token/price APIs).
|
|
474
|
-
const
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
488
|
+
const slowPipelineChainIds = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSlowPipelineChainIds).call(this, chainIds, response);
|
|
489
|
+
if (slowPipelineChainIds.length > 0) {
|
|
490
|
+
const slowSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
491
|
+
? [__classPrivateFieldGet(this, _AssetsController_snapDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")]
|
|
492
|
+
: [__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")];
|
|
493
|
+
const slowRequest = { ...request, chainIds: slowPipelineChainIds };
|
|
494
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, [
|
|
495
|
+
(0, ParallelMiddleware_1.createParallelBalanceMiddleware)(slowSources),
|
|
496
|
+
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
497
|
+
...(__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
498
|
+
? [
|
|
499
|
+
(0, ParallelMiddleware_1.createParallelMiddleware)([
|
|
500
|
+
__classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
|
|
501
|
+
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
|
|
502
|
+
]),
|
|
503
|
+
]
|
|
504
|
+
: []),
|
|
505
|
+
], slowRequest)
|
|
506
|
+
.then(({ response: slowResponse }) => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, { ...slowResponse, updateMode: 'merge' }))
|
|
507
|
+
.catch((error) => log('Background pipeline failed', { error }));
|
|
508
|
+
}
|
|
495
509
|
const durationMs = performance.now() - startTime;
|
|
496
510
|
// Emit trace for every full fetch (Assets Health dashboard)
|
|
497
511
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_FULL_FETCH, {
|
|
@@ -883,7 +897,8 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
883
897
|
// RPC already fetches custom assets on purpose, and Snap handles non-EVM
|
|
884
898
|
// chains the rule does not apply to, so skip the middleware for those.
|
|
885
899
|
const shouldGraduateCustomAssets = sourceId === 'AccountsApiDataSource' ||
|
|
886
|
-
sourceId === 'BackendWebsocketDataSource'
|
|
900
|
+
sourceId === 'BackendWebsocketDataSource' ||
|
|
901
|
+
sourceId === 'AccountActivityService';
|
|
887
902
|
const enrichmentSources = [
|
|
888
903
|
...(shouldGraduateCustomAssets
|
|
889
904
|
? [__classPrivateFieldGet(this, _AssetsController_customAssetGraduationMiddleware, "f")]
|
|
@@ -897,11 +912,10 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
897
912
|
]));
|
|
898
913
|
}
|
|
899
914
|
const { response: enrichedResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, enrichmentSources, pipelineRequest, response);
|
|
900
|
-
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
}
|
|
915
|
+
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
916
|
+
...enrichedResponse,
|
|
917
|
+
replaceCoveredChainBalances: response.replaceCoveredChainBalances,
|
|
918
|
+
});
|
|
905
919
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_UPDATE_PIPELINE, {
|
|
906
920
|
source: sourceId,
|
|
907
921
|
duration_ms: performance.now() - updateStart,
|
|
@@ -949,7 +963,7 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
949
963
|
}
|
|
950
964
|
}
|
|
951
965
|
exports.AssetsController = AssetsController;
|
|
952
|
-
_AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctionality = new WeakMap(), _AssetsController_defaultUpdateInterval = new WeakMap(), _AssetsController_trace = new WeakMap(), _AssetsController_captureException = new WeakMap(), _AssetsController_firstInitFetchReported = new WeakMap(), _AssetsController_stateSizeReported = new WeakMap(), _AssetsController_uiOpen = new WeakMap(), _AssetsController_keyringUnlocked = new WeakMap(), _AssetsController_controllerMutex = new WeakMap(), _AssetsController_accountRefreshMutex = new WeakMap(), _AssetsController_activeSubscriptions = new WeakMap(), _AssetsController_enabledChains = new WeakMap(), _AssetsController_lastKnownAccountIds = new WeakMap(),
|
|
966
|
+
_AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctionality = new WeakMap(), _AssetsController_defaultUpdateInterval = new WeakMap(), _AssetsController_trace = new WeakMap(), _AssetsController_captureException = new WeakMap(), _AssetsController_firstInitFetchReported = new WeakMap(), _AssetsController_stateSizeReported = new WeakMap(), _AssetsController_uiOpen = new WeakMap(), _AssetsController_keyringUnlocked = new WeakMap(), _AssetsController_controllerMutex = new WeakMap(), _AssetsController_accountRefreshMutex = new WeakMap(), _AssetsController_activeSubscriptions = new WeakMap(), _AssetsController_enabledChains = new WeakMap(), _AssetsController_lastKnownAccountIds = new WeakMap(), _AssetsController_backendWebsocketDataSource = new WeakMap(), _AssetsController_accountsApiDataSource = new WeakMap(), _AssetsController_snapDataSource = new WeakMap(), _AssetsController_rpcDataSource = new WeakMap(), _AssetsController_stakedBalanceDataSource = new WeakMap(), _AssetsController_priceDataSource = new WeakMap(), _AssetsController_detectionMiddleware = new WeakMap(), _AssetsController_customAssetGraduationMiddleware = new WeakMap(), _AssetsController_rpcFallbackMiddleware = new WeakMap(), _AssetsController_tokenDataSource = new WeakMap(), _AssetsController_unsubscribeBasicFunctionality = new WeakMap(), _AssetsController_queryApiClient = new WeakMap(), _AssetsController_onActiveChainsUpdated = new WeakMap(), _AssetsController_instances = new WeakSet(), _AssetsController_emitTrace = function _AssetsController_emitTrace(name, data, tags = {
|
|
953
967
|
controller: 'AssetsController',
|
|
954
968
|
}) {
|
|
955
969
|
if (!__classPrivateFieldGet(this, _AssetsController_trace, "f")) {
|
|
@@ -1075,11 +1089,11 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
|
|
|
1075
1089
|
// The base-controller `:stateChange` event is guaranteed to fire
|
|
1076
1090
|
// when init() calls this.update(). #start() is idempotent so
|
|
1077
1091
|
// repeated fires are safe.
|
|
1078
|
-
this.messenger.subscribe('AccountTreeController:
|
|
1092
|
+
this.messenger.subscribe('AccountTreeController:stateChanged', () => {
|
|
1079
1093
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleAccountTreeStateChange).call(this);
|
|
1080
1094
|
});
|
|
1081
1095
|
// Subscribe to network enablement changes (only enabledNetworkMap)
|
|
1082
|
-
this.messenger.subscribe('NetworkEnablementController:
|
|
1096
|
+
this.messenger.subscribe('NetworkEnablementController:stateChanged', ({ enabledNetworkMap }) => {
|
|
1083
1097
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleEnabledNetworksChanged).call(this, enabledNetworkMap).catch(console.error);
|
|
1084
1098
|
});
|
|
1085
1099
|
// When a network is added or removed from NetworkController, refresh
|
|
@@ -1090,13 +1104,20 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
|
|
|
1090
1104
|
// enabled in NetworkEnablementController.
|
|
1091
1105
|
this.messenger.subscribe('NetworkController:networkAdded', (networkConfiguration) => {
|
|
1092
1106
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleNetworkAdded).call(this, networkConfiguration.chainId);
|
|
1093
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m",
|
|
1107
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_refreshAssetsAfterNetworkAdded).call(this, networkConfiguration.chainId).catch((error) => {
|
|
1108
|
+
log('Failed to refresh assets after network added', { error });
|
|
1109
|
+
});
|
|
1094
1110
|
});
|
|
1095
1111
|
this.messenger.subscribe('NetworkController:networkRemoved', () => {
|
|
1096
1112
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_refreshAssetsAfterNetworkChange).call(this);
|
|
1097
1113
|
});
|
|
1114
|
+
// Selected EVM network switch (network picker). Enablement changes are
|
|
1115
|
+
// handled separately via NetworkEnablementController:stateChanged.
|
|
1116
|
+
this.messenger.subscribe('NetworkController:networkDidChange', (networkState) => {
|
|
1117
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleNetworkDidChange).call(this, networkState).catch(console.error);
|
|
1118
|
+
});
|
|
1098
1119
|
// Client + Keyring lifecycle: only run when UI is open AND keyring is unlocked
|
|
1099
|
-
this.messenger.subscribe('ClientController:
|
|
1120
|
+
this.messenger.subscribe('ClientController:stateChanged', (isUiOpen) => {
|
|
1100
1121
|
__classPrivateFieldSet(this, _AssetsController_uiOpen, isUiOpen, "f");
|
|
1101
1122
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateActive).call(this);
|
|
1102
1123
|
}, client_controller_1.clientControllerSelectors.selectIsUiOpen);
|
|
@@ -1113,6 +1134,18 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
|
|
|
1113
1134
|
this.messenger.subscribe('TransactionController:unapprovedTransactionAdded', (transactionMeta) => {
|
|
1114
1135
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_onUnapprovedTransactionAdded).call(this, transactionMeta);
|
|
1115
1136
|
});
|
|
1137
|
+
// Post-tx refresh via the full fetch pipeline (Accounts API + RPC fallback).
|
|
1138
|
+
// RpcDataSource also listens for transactionConfirmed, but only refreshes
|
|
1139
|
+
// chains it owns via an active subscription.
|
|
1140
|
+
this.messenger.subscribe('TransactionController:transactionConfirmed', (transactionMeta) => {
|
|
1141
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_onTransactionConfirmed).call(this, transactionMeta);
|
|
1142
|
+
});
|
|
1143
|
+
// Real-time post-tx balances from AccountActivityService (same WS payload as
|
|
1144
|
+
// TokenBalancesController; BackendWebsocketDataSource may not receive the
|
|
1145
|
+
// callback when AccountActivityService owns the server subscription).
|
|
1146
|
+
this.messenger.subscribe('AccountActivityService:balanceUpdated', (event) => {
|
|
1147
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_onAccountActivityBalanceUpdated).call(this, event);
|
|
1148
|
+
});
|
|
1116
1149
|
}, _AssetsController_onUnapprovedTransactionAdded = function _AssetsController_onUnapprovedTransactionAdded(transactionMeta) {
|
|
1117
1150
|
const hexChainId = transactionMeta.chainId;
|
|
1118
1151
|
if (!hexChainId) {
|
|
@@ -1135,6 +1168,46 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
|
|
|
1135
1168
|
error,
|
|
1136
1169
|
});
|
|
1137
1170
|
});
|
|
1171
|
+
}, _AssetsController_onTransactionConfirmed = function _AssetsController_onTransactionConfirmed(transactionMeta) {
|
|
1172
|
+
const hexChainId = transactionMeta.chainId;
|
|
1173
|
+
if (!hexChainId) {
|
|
1174
|
+
return;
|
|
1175
|
+
}
|
|
1176
|
+
const caipChainId = `eip155:${parseInt(hexChainId, 16)}`;
|
|
1177
|
+
const fromAddress = transactionMeta.txParams.from?.toLowerCase();
|
|
1178
|
+
if (!fromAddress) {
|
|
1179
|
+
return;
|
|
1180
|
+
}
|
|
1181
|
+
const matchedAccount = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((account) => account.address.toLowerCase() === fromAddress);
|
|
1182
|
+
if (!matchedAccount) {
|
|
1183
|
+
return;
|
|
1184
|
+
}
|
|
1185
|
+
this.getAssets([matchedAccount], {
|
|
1186
|
+
chainIds: [caipChainId],
|
|
1187
|
+
forceUpdate: true,
|
|
1188
|
+
}).catch((error) => {
|
|
1189
|
+
log('Failed to refresh assets after transaction confirmed', { error });
|
|
1190
|
+
});
|
|
1191
|
+
}, _AssetsController_onAccountActivityBalanceUpdated = function _AssetsController_onAccountActivityBalanceUpdated({ address, chain, updates, }) {
|
|
1192
|
+
const account = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((a) => a.address.startsWith('0x')
|
|
1193
|
+
? a.address.toLowerCase() === address.toLowerCase()
|
|
1194
|
+
: a.address === address);
|
|
1195
|
+
if (!account) {
|
|
1196
|
+
return;
|
|
1197
|
+
}
|
|
1198
|
+
const chainId = chain;
|
|
1199
|
+
const response = (0, processAccountActivityBalanceUpdates_1.processAccountActivityBalanceUpdates)(updates, account.id, (assetId) => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetType).call(this, assetId));
|
|
1200
|
+
if (!response.assetsBalance) {
|
|
1201
|
+
return;
|
|
1202
|
+
}
|
|
1203
|
+
const request = {
|
|
1204
|
+
accountsWithSupportedChains: [{ account, supportedChains: [chainId] }],
|
|
1205
|
+
chainIds: [chainId],
|
|
1206
|
+
dataTypes: ['balance', 'metadata'],
|
|
1207
|
+
};
|
|
1208
|
+
this.handleAssetsUpdate(response, 'AccountActivityService', request).catch((error) => {
|
|
1209
|
+
log('Failed to apply AccountActivityService balance update', { error });
|
|
1210
|
+
});
|
|
1138
1211
|
}, _AssetsController_updateActive = function _AssetsController_updateActive() {
|
|
1139
1212
|
const shouldRun = __classPrivateFieldGet(this, _AssetsController_uiOpen, "f") && __classPrivateFieldGet(this, _AssetsController_keyringUnlocked, "f");
|
|
1140
1213
|
if (shouldRun) {
|
|
@@ -1190,6 +1263,32 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
|
|
|
1190
1263
|
finally {
|
|
1191
1264
|
releaseLock();
|
|
1192
1265
|
}
|
|
1266
|
+
}, _AssetsController_runStartupRefresh =
|
|
1267
|
+
/**
|
|
1268
|
+
* Force-fetch balances then subscribe. Used on unlock / first startup.
|
|
1269
|
+
*
|
|
1270
|
+
* @param accounts - Selected accounts to refresh.
|
|
1271
|
+
*/
|
|
1272
|
+
async function _AssetsController_runStartupRefresh(accounts) {
|
|
1273
|
+
const releaseLock = await __classPrivateFieldGet(this, _AssetsController_accountRefreshMutex, "f").acquire();
|
|
1274
|
+
try {
|
|
1275
|
+
await this.getAssets(accounts, {
|
|
1276
|
+
chainIds: [...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f")],
|
|
1277
|
+
forceUpdate: true,
|
|
1278
|
+
});
|
|
1279
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
1280
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
1281
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureDefaultTrackedAssetsSeeded).call(this);
|
|
1282
|
+
}
|
|
1283
|
+
catch (error) {
|
|
1284
|
+
log('Failed to fetch assets on startup', error);
|
|
1285
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
1286
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
1287
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureDefaultTrackedAssetsSeeded).call(this);
|
|
1288
|
+
}
|
|
1289
|
+
finally {
|
|
1290
|
+
releaseLock();
|
|
1291
|
+
}
|
|
1193
1292
|
}, _AssetsController_registerActionHandlers = function _AssetsController_registerActionHandlers() {
|
|
1194
1293
|
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
1195
1294
|
}, _AssetsController_handleActiveChainsUpdate = function _AssetsController_handleActiveChainsUpdate(dataSourceId, activeChains, previousChains) {
|
|
@@ -1303,6 +1402,41 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1303
1402
|
});
|
|
1304
1403
|
}
|
|
1305
1404
|
return { response: result.response, durationByDataSource };
|
|
1405
|
+
}, _AssetsController_fetchMissingPricesWithoutCache = function _AssetsController_fetchMissingPricesWithoutCache(accounts, chainIds) {
|
|
1406
|
+
if (!__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this) || accounts.length === 0) {
|
|
1407
|
+
return;
|
|
1408
|
+
}
|
|
1409
|
+
const accountIds = new Set(accounts.map((account) => account.id));
|
|
1410
|
+
const chainFilter = new Set(chainIds);
|
|
1411
|
+
const assetsForPriceUpdate = [];
|
|
1412
|
+
const prices = this.state.assetsPrice;
|
|
1413
|
+
for (const [accountId, accountBalances] of Object.entries(this.state.assetsBalance)) {
|
|
1414
|
+
if (!accountIds.has(accountId)) {
|
|
1415
|
+
continue;
|
|
1416
|
+
}
|
|
1417
|
+
for (const assetId of Object.keys(accountBalances)) {
|
|
1418
|
+
if (!chainFilter.has(assetId.split('/')[0])) {
|
|
1419
|
+
continue;
|
|
1420
|
+
}
|
|
1421
|
+
const normalizedAssetId = (0, utils_2.normalizeAssetId)(assetId);
|
|
1422
|
+
if (prices[normalizedAssetId] ?? prices[assetId]) {
|
|
1423
|
+
continue;
|
|
1424
|
+
}
|
|
1425
|
+
assetsForPriceUpdate.push(normalizedAssetId);
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
if (assetsForPriceUpdate.length === 0) {
|
|
1429
|
+
return;
|
|
1430
|
+
}
|
|
1431
|
+
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f").invalidatePriceCache();
|
|
1432
|
+
this.getAssets(accounts, {
|
|
1433
|
+
forceUpdate: true,
|
|
1434
|
+
dataTypes: ['price'],
|
|
1435
|
+
chainIds,
|
|
1436
|
+
assetsForPriceUpdate,
|
|
1437
|
+
}).catch((error) => {
|
|
1438
|
+
log('Failed to fetch missing prices', { error });
|
|
1439
|
+
});
|
|
1306
1440
|
}, _AssetsController_getNativeAssetMap = function _AssetsController_getNativeAssetMap() {
|
|
1307
1441
|
return (__classPrivateFieldGet(this, _AssetsController_queryApiClient, "f").getCachedData(NATIVE_ASSETS_QUERY_KEY) ?? {});
|
|
1308
1442
|
}, _AssetsController_isNativeAsset = function _AssetsController_isNativeAsset(assetId) {
|
|
@@ -1344,6 +1478,17 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1344
1478
|
return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_resolveNativeAssetIds).call(this, __classPrivateFieldGet(this, _AssetsController_enabledChains, "f"));
|
|
1345
1479
|
}, _AssetsController_getNativeAssetIdsForAccount = function _AssetsController_getNativeAssetIdsForAccount(account) {
|
|
1346
1480
|
return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_resolveNativeAssetIds).call(this, __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getEnabledChainsForAccount).call(this, account));
|
|
1481
|
+
}, _AssetsController_getSlowPipelineChainIds = function _AssetsController_getSlowPipelineChainIds(chainIds, fastResponse) {
|
|
1482
|
+
const accountsApiChains = new Set(__classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f").getActiveChainsSync());
|
|
1483
|
+
return chainIds.filter((chainId) => {
|
|
1484
|
+
if (fastResponse.errors?.[chainId]) {
|
|
1485
|
+
return true;
|
|
1486
|
+
}
|
|
1487
|
+
if (!accountsApiChains.has(chainId)) {
|
|
1488
|
+
return true;
|
|
1489
|
+
}
|
|
1490
|
+
return false;
|
|
1491
|
+
});
|
|
1347
1492
|
}, _AssetsController_ensureNativeBalancesDefaultZero = function _AssetsController_ensureNativeBalancesDefaultZero() {
|
|
1348
1493
|
const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this);
|
|
1349
1494
|
if (accounts.length === 0) {
|
|
@@ -1361,7 +1506,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1361
1506
|
balances[accountId] = {};
|
|
1362
1507
|
}
|
|
1363
1508
|
for (const nativeAssetId of nativeAssetIds) {
|
|
1364
|
-
if (!(
|
|
1509
|
+
if (!Object.prototype.hasOwnProperty.call(balances[accountId], nativeAssetId)) {
|
|
1365
1510
|
balances[accountId][nativeAssetId] = { amount: '0' };
|
|
1366
1511
|
}
|
|
1367
1512
|
}
|
|
@@ -1411,37 +1556,9 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1411
1556
|
}
|
|
1412
1557
|
}
|
|
1413
1558
|
});
|
|
1414
|
-
}, _AssetsController_filterBalancesRespectingWsFreshness = function _AssetsController_filterBalancesRespectingWsFreshness(accountId, accountBalances, sourceId) {
|
|
1415
|
-
if (!sourceId || !POLLING_BALANCE_SOURCES.has(sourceId)) {
|
|
1416
|
-
return accountBalances;
|
|
1417
|
-
}
|
|
1418
|
-
const now = Date.now();
|
|
1419
|
-
const filtered = {};
|
|
1420
|
-
for (const [assetId, balance] of Object.entries(accountBalances)) {
|
|
1421
|
-
const freshUntil = __classPrivateFieldGet(this, _AssetsController_wsBalanceFreshUntil, "f").get(`${accountId}:${assetId}`);
|
|
1422
|
-
if (freshUntil !== undefined && now < freshUntil) {
|
|
1423
|
-
continue;
|
|
1424
|
-
}
|
|
1425
|
-
filtered[assetId] = balance;
|
|
1426
|
-
}
|
|
1427
|
-
return filtered;
|
|
1428
|
-
}, _AssetsController_markWsBalancesFresh = function _AssetsController_markWsBalancesFresh(assetsBalance) {
|
|
1429
|
-
const freshUntil = Date.now() + WS_BALANCE_FRESHNESS_MS;
|
|
1430
|
-
for (const [accountId, balances] of Object.entries(assetsBalance)) {
|
|
1431
|
-
for (const assetId of Object.keys(balances)) {
|
|
1432
|
-
__classPrivateFieldGet(this, _AssetsController_wsBalanceFreshUntil, "f").set(`${accountId}:${assetId}`, freshUntil);
|
|
1433
|
-
}
|
|
1434
|
-
}
|
|
1435
|
-
}, _AssetsController_clearWsBalanceFreshness = function _AssetsController_clearWsBalanceFreshness(assetsBalance) {
|
|
1436
|
-
for (const [accountId, balances] of Object.entries(assetsBalance)) {
|
|
1437
|
-
for (const assetId of Object.keys(balances)) {
|
|
1438
|
-
__classPrivateFieldGet(this, _AssetsController_wsBalanceFreshUntil, "f").delete(`${accountId}:${assetId}`);
|
|
1439
|
-
}
|
|
1440
|
-
}
|
|
1441
1559
|
}, _AssetsController_updateState = async function _AssetsController_updateState(response) {
|
|
1442
1560
|
const normalizedResponse = normalizeResponse(response);
|
|
1443
1561
|
const mode = normalizedResponse.updateMode ?? 'merge';
|
|
1444
|
-
const assetsBalanceToApply = normalizedResponse.assetsBalance;
|
|
1445
1562
|
const releaseLock = await __classPrivateFieldGet(this, _AssetsController_controllerMutex, "f").acquire();
|
|
1446
1563
|
try {
|
|
1447
1564
|
const previousState = this.state;
|
|
@@ -1502,48 +1619,20 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1502
1619
|
}
|
|
1503
1620
|
}
|
|
1504
1621
|
}
|
|
1505
|
-
if (
|
|
1506
|
-
for (const [accountId, accountBalances] of Object.entries(
|
|
1507
|
-
const filteredAccountBalances = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_filterBalancesRespectingWsFreshness).call(this, accountId, accountBalances, normalizedResponse.sourceId);
|
|
1622
|
+
if (normalizedResponse.assetsBalance) {
|
|
1623
|
+
for (const [accountId, accountBalances] of Object.entries(normalizedResponse.assetsBalance)) {
|
|
1508
1624
|
const previousBalances = previousState.assetsBalance[accountId] ?? {};
|
|
1509
1625
|
const customAssetIds = state.customAssets[accountId] ?? [];
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
// are never inadvertently reset to zero.
|
|
1514
|
-
// Merge: response overlays previous balances.
|
|
1515
|
-
const effective = mode === 'merge'
|
|
1516
|
-
? { ...previousBalances, ...filteredAccountBalances }
|
|
1517
|
-
: (() => {
|
|
1518
|
-
// Determine which chain namespaces this response covers.
|
|
1519
|
-
const coveredChains = new Set(Object.keys(filteredAccountBalances).map((assetId) => assetId.split('/')[0]));
|
|
1520
|
-
// Start from previous balances, dropping only entries for
|
|
1521
|
-
// chains this response is authoritative over.
|
|
1522
|
-
const next = {};
|
|
1523
|
-
for (const [assetId, balance] of Object.entries(previousBalances)) {
|
|
1524
|
-
if (!coveredChains.has(assetId.split('/')[0])) {
|
|
1525
|
-
next[assetId] = balance;
|
|
1526
|
-
}
|
|
1527
|
-
}
|
|
1528
|
-
// Apply the response (authoritative for covered chains).
|
|
1529
|
-
Object.assign(next, filteredAccountBalances);
|
|
1530
|
-
// Preserve custom assets that the response omitted.
|
|
1531
|
-
for (const customId of customAssetIds) {
|
|
1532
|
-
if (!(customId in next)) {
|
|
1533
|
-
const prev = previousBalances[customId];
|
|
1534
|
-
next[customId] =
|
|
1535
|
-
prev ?? { amount: '0' };
|
|
1536
|
-
}
|
|
1537
|
-
}
|
|
1538
|
-
return next;
|
|
1539
|
-
})();
|
|
1626
|
+
const replaceCoveredChains = mode === 'full' ||
|
|
1627
|
+
normalizedResponse.replaceCoveredChainBalances === true;
|
|
1628
|
+
const effective = mergeAccountBalances(previousBalances, accountBalances, customAssetIds, replaceCoveredChains);
|
|
1540
1629
|
// Ensure native tokens have an entry (0 if missing) for chains this account supports
|
|
1541
1630
|
const account = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((a) => a.id === accountId);
|
|
1542
1631
|
const nativeAssetIdsForAccount = account
|
|
1543
1632
|
? __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForAccount).call(this, account)
|
|
1544
1633
|
: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForEnabledChains).call(this);
|
|
1545
1634
|
for (const nativeAssetId of nativeAssetIdsForAccount) {
|
|
1546
|
-
if (!(nativeAssetId
|
|
1635
|
+
if (!Object.prototype.hasOwnProperty.call(effective, nativeAssetId)) {
|
|
1547
1636
|
effective[nativeAssetId] = { amount: '0' };
|
|
1548
1637
|
}
|
|
1549
1638
|
}
|
|
@@ -1575,7 +1664,6 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1575
1664
|
balances[accountId] = effective;
|
|
1576
1665
|
}
|
|
1577
1666
|
}
|
|
1578
|
-
// Update prices in state
|
|
1579
1667
|
if (normalizedResponse.assetsPrice) {
|
|
1580
1668
|
for (const [key, value] of Object.entries(normalizedResponse.assetsPrice)) {
|
|
1581
1669
|
prices[key] = value;
|
|
@@ -1638,12 +1726,6 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1638
1726
|
});
|
|
1639
1727
|
}
|
|
1640
1728
|
}
|
|
1641
|
-
// Authoritative fetch on account switch — drop WS freshness locks so API
|
|
1642
|
-
// balances (e.g. receiver +1 USDC) replace stale values from a prior send.
|
|
1643
|
-
if (normalizedResponse.sourceId === 'getAssets:forceUpdate' &&
|
|
1644
|
-
assetsBalanceToApply) {
|
|
1645
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_clearWsBalanceFreshness).call(this, assetsBalanceToApply);
|
|
1646
|
-
}
|
|
1647
1729
|
}
|
|
1648
1730
|
finally {
|
|
1649
1731
|
releaseLock();
|
|
@@ -1742,14 +1824,8 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1742
1824
|
enabledChainCount: chainIds.length,
|
|
1743
1825
|
});
|
|
1744
1826
|
__classPrivateFieldSet(this, _AssetsController_lastKnownAccountIds, new Set(accounts.map((a) => a.id)), "f");
|
|
1745
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m",
|
|
1746
|
-
|
|
1747
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureDefaultTrackedAssetsSeeded).call(this);
|
|
1748
|
-
this.getAssets(accounts, {
|
|
1749
|
-
chainIds,
|
|
1750
|
-
forceUpdate: true,
|
|
1751
|
-
}).catch((error) => {
|
|
1752
|
-
log('Failed to fetch assets', error);
|
|
1827
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_runStartupRefresh).call(this, accounts).catch((error) => {
|
|
1828
|
+
log('Failed to start asset tracking', error);
|
|
1753
1829
|
});
|
|
1754
1830
|
}, _AssetsController_stop = function _AssetsController_stop() {
|
|
1755
1831
|
log('Stopping asset tracking', {
|
|
@@ -1827,7 +1903,13 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1827
1903
|
const seenIds = new Set();
|
|
1828
1904
|
const accountsForSource = assignedChains
|
|
1829
1905
|
.flatMap((chainId) => chainToAccounts.get(chainId) ?? [])
|
|
1830
|
-
.filter((account) =>
|
|
1906
|
+
.filter((account) => {
|
|
1907
|
+
if (seenIds.has(account.id)) {
|
|
1908
|
+
return false;
|
|
1909
|
+
}
|
|
1910
|
+
seenIds.add(account.id);
|
|
1911
|
+
return true;
|
|
1912
|
+
});
|
|
1831
1913
|
if (accountsForSource.length > 0) {
|
|
1832
1914
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeDataSource).call(this, source, accountsForSource, assignedChains);
|
|
1833
1915
|
}
|
|
@@ -2089,11 +2171,102 @@ async function _AssetsController_handleAccountGroupChanged() {
|
|
|
2089
2171
|
caipChainId,
|
|
2090
2172
|
});
|
|
2091
2173
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureDefaultTrackedAssetsSeeded).call(this, [caipChainId]);
|
|
2174
|
+
}, _AssetsController_refreshActiveChainsOnNetworkSwitch =
|
|
2175
|
+
/**
|
|
2176
|
+
* Refresh data-source `activeChains` after an EVM network switch so API/WS/Rpc
|
|
2177
|
+
* chain claiming is not stuck on an empty or stale init-time list.
|
|
2178
|
+
*/
|
|
2179
|
+
async function _AssetsController_refreshActiveChainsOnNetworkSwitch() {
|
|
2180
|
+
await Promise.all([
|
|
2181
|
+
__classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f").refreshActiveChains(),
|
|
2182
|
+
__classPrivateFieldGet(this, _AssetsController_backendWebsocketDataSource, "f").refreshActiveChains(),
|
|
2183
|
+
]);
|
|
2184
|
+
__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f").refreshActiveChainsFromNetworkState();
|
|
2185
|
+
}, _AssetsController_getSelectedEvmChainIdFromNetworkState = function _AssetsController_getSelectedEvmChainIdFromNetworkState(networkState) {
|
|
2186
|
+
try {
|
|
2187
|
+
const networkClient = this.messenger.call('NetworkController:getNetworkClientById', networkState.selectedNetworkClientId);
|
|
2188
|
+
const hexChainId = networkClient.configuration?.chainId;
|
|
2189
|
+
if (!hexChainId) {
|
|
2190
|
+
return undefined;
|
|
2191
|
+
}
|
|
2192
|
+
return `eip155:${parseInt(hexChainId, 16)}`;
|
|
2193
|
+
}
|
|
2194
|
+
catch {
|
|
2195
|
+
return undefined;
|
|
2196
|
+
}
|
|
2197
|
+
}, _AssetsController_handleNetworkDidChange =
|
|
2198
|
+
/**
|
|
2199
|
+
* Refresh subscriptions and fetch balances when the user switches the
|
|
2200
|
+
* selected EVM network in the UI (`NetworkController:networkDidChange`).
|
|
2201
|
+
*
|
|
2202
|
+
* @param networkState - NetworkController state after the switch.
|
|
2203
|
+
*/
|
|
2204
|
+
async function _AssetsController_handleNetworkDidChange(networkState) {
|
|
2205
|
+
if (!__classPrivateFieldGet(this, _AssetsController_uiOpen, "f") || !__classPrivateFieldGet(this, _AssetsController_keyringUnlocked, "f") || !__classPrivateFieldGet(this, _AssetsController_isEnabled, "f").call(this)) {
|
|
2206
|
+
return;
|
|
2207
|
+
}
|
|
2208
|
+
const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this);
|
|
2209
|
+
if (accounts.length === 0) {
|
|
2210
|
+
return;
|
|
2211
|
+
}
|
|
2212
|
+
const selectedChainId = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedEvmChainIdFromNetworkState).call(this, networkState);
|
|
2213
|
+
if (!selectedChainId) {
|
|
2214
|
+
return;
|
|
2215
|
+
}
|
|
2216
|
+
log('Selected EVM network switched', {
|
|
2217
|
+
selectedNetworkClientId: networkState.selectedNetworkClientId,
|
|
2218
|
+
selectedChainId,
|
|
2219
|
+
});
|
|
2220
|
+
const releaseLock = await __classPrivateFieldGet(this, _AssetsController_accountRefreshMutex, "f").acquire();
|
|
2221
|
+
try {
|
|
2222
|
+
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_refreshActiveChainsOnNetworkSwitch).call(this);
|
|
2223
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
2224
|
+
await this.getAssets(accounts, {
|
|
2225
|
+
chainIds: [selectedChainId],
|
|
2226
|
+
forceUpdate: true,
|
|
2227
|
+
dataTypes: ['balance', 'metadata', 'price'],
|
|
2228
|
+
});
|
|
2229
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
2230
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_fetchMissingPricesWithoutCache).call(this, accounts, [selectedChainId]);
|
|
2231
|
+
}
|
|
2232
|
+
finally {
|
|
2233
|
+
releaseLock();
|
|
2234
|
+
}
|
|
2092
2235
|
}, _AssetsController_refreshAssetsAfterNetworkChange = function _AssetsController_refreshAssetsAfterNetworkChange() {
|
|
2093
|
-
|
|
2236
|
+
const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this);
|
|
2237
|
+
if (accounts.length === 0) {
|
|
2238
|
+
return;
|
|
2239
|
+
}
|
|
2240
|
+
this.getAssets(accounts, {
|
|
2094
2241
|
forceUpdate: true,
|
|
2242
|
+
dataTypes: ['balance', 'metadata'],
|
|
2095
2243
|
}).catch((error) => {
|
|
2096
2244
|
log('Failed to refresh assets after network change', { error });
|
|
2097
2245
|
});
|
|
2246
|
+
}, _AssetsController_refreshAssetsAfterNetworkAdded =
|
|
2247
|
+
/**
|
|
2248
|
+
* Refresh balances and fetch missing prices after a network is added.
|
|
2249
|
+
*
|
|
2250
|
+
* @param hexChainId - Hex chain id of the newly-added network.
|
|
2251
|
+
*/
|
|
2252
|
+
async function _AssetsController_refreshAssetsAfterNetworkAdded(hexChainId) {
|
|
2253
|
+
const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this);
|
|
2254
|
+
if (accounts.length === 0) {
|
|
2255
|
+
return;
|
|
2256
|
+
}
|
|
2257
|
+
let caipChainId;
|
|
2258
|
+
try {
|
|
2259
|
+
caipChainId = `eip155:${parseInt(hexChainId, 16)}`;
|
|
2260
|
+
}
|
|
2261
|
+
catch {
|
|
2262
|
+
return;
|
|
2263
|
+
}
|
|
2264
|
+
await this.getAssets(accounts, {
|
|
2265
|
+
chainIds: [caipChainId],
|
|
2266
|
+
forceUpdate: true,
|
|
2267
|
+
dataTypes: ['balance', 'metadata', 'price'],
|
|
2268
|
+
});
|
|
2269
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
2270
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_fetchMissingPricesWithoutCache).call(this, accounts, [caipChainId]);
|
|
2098
2271
|
};
|
|
2099
2272
|
//# sourceMappingURL=AssetsController.cjs.map
|