@metamask-previews/assets-controller 9.1.0-preview-bd7b53f49 → 9.1.0-preview-e0ee14da7
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 +2 -8
- package/dist/AssetsController.cjs +136 -309
- package/dist/AssetsController.cjs.map +1 -1
- package/dist/AssetsController.d.cts +8 -11
- package/dist/AssetsController.d.cts.map +1 -1
- package/dist/AssetsController.d.mts +8 -11
- package/dist/AssetsController.d.mts.map +1 -1
- package/dist/AssetsController.mjs +136 -309
- package/dist/AssetsController.mjs.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.cjs +0 -10
- package/dist/data-sources/AccountsApiDataSource.cjs.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.d.cts +0 -8
- package/dist/data-sources/AccountsApiDataSource.d.cts.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.d.mts +0 -8
- package/dist/data-sources/AccountsApiDataSource.d.mts.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.mjs +0 -10
- package/dist/data-sources/AccountsApiDataSource.mjs.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.cjs +60 -36
- package/dist/data-sources/BackendWebsocketDataSource.cjs.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.d.cts +0 -8
- package/dist/data-sources/BackendWebsocketDataSource.d.cts.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.d.mts +0 -8
- package/dist/data-sources/BackendWebsocketDataSource.d.mts.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.mjs +57 -36
- package/dist/data-sources/BackendWebsocketDataSource.mjs.map +1 -1
- package/dist/data-sources/PriceDataSource.cjs +9 -18
- 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 +10 -19
- package/dist/data-sources/PriceDataSource.mjs.map +1 -1
- package/dist/data-sources/RpcDataSource.cjs +9 -29
- package/dist/data-sources/RpcDataSource.cjs.map +1 -1
- package/dist/data-sources/RpcDataSource.d.cts +0 -5
- package/dist/data-sources/RpcDataSource.d.cts.map +1 -1
- package/dist/data-sources/RpcDataSource.d.mts +0 -5
- package/dist/data-sources/RpcDataSource.d.mts.map +1 -1
- package/dist/data-sources/RpcDataSource.mjs +9 -29
- package/dist/data-sources/RpcDataSource.mjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.cts +2 -2
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.mts +2 -2
- package/dist/data-sources/evm-rpc-services/services/StakedBalanceFetcher.d.cts +2 -2
- package/dist/data-sources/evm-rpc-services/services/StakedBalanceFetcher.d.mts +2 -2
- package/dist/data-sources/evm-rpc-services/services/TokenDetector.d.cts +2 -2
- package/dist/data-sources/evm-rpc-services/services/TokenDetector.d.mts +2 -2
- package/dist/middlewares/DetectionMiddleware.cjs +1 -22
- package/dist/middlewares/DetectionMiddleware.cjs.map +1 -1
- package/dist/middlewares/DetectionMiddleware.d.cts +0 -3
- package/dist/middlewares/DetectionMiddleware.d.cts.map +1 -1
- package/dist/middlewares/DetectionMiddleware.d.mts +0 -3
- package/dist/middlewares/DetectionMiddleware.d.mts.map +1 -1
- package/dist/middlewares/DetectionMiddleware.mjs +1 -22
- package/dist/middlewares/DetectionMiddleware.mjs.map +1 -1
- package/dist/middlewares/ParallelMiddleware.cjs +0 -7
- 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 +0 -7
- package/dist/middlewares/ParallelMiddleware.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +9 -18
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +9 -18
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/dedupingBatchFetcher.cjs +0 -11
- package/dist/utils/dedupingBatchFetcher.cjs.map +1 -1
- package/dist/utils/dedupingBatchFetcher.d.cts +0 -7
- package/dist/utils/dedupingBatchFetcher.d.cts.map +1 -1
- package/dist/utils/dedupingBatchFetcher.d.mts +0 -7
- package/dist/utils/dedupingBatchFetcher.d.mts.map +1 -1
- package/dist/utils/dedupingBatchFetcher.mjs +0 -11
- package/dist/utils/dedupingBatchFetcher.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/utils/processAccountActivityBalanceUpdates.cjs +0 -54
- package/dist/utils/processAccountActivityBalanceUpdates.cjs.map +0 -1
- package/dist/utils/processAccountActivityBalanceUpdates.d.cts +0 -13
- package/dist/utils/processAccountActivityBalanceUpdates.d.cts.map +0 -1
- package/dist/utils/processAccountActivityBalanceUpdates.d.mts +0 -13
- package/dist/utils/processAccountActivityBalanceUpdates.d.mts.map +0 -1
- package/dist/utils/processAccountActivityBalanceUpdates.mjs +0 -47
- package/dist/utils/processAccountActivityBalanceUpdates.mjs.map +0 -1
|
@@ -9,7 +9,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
9
9
|
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");
|
|
10
10
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
11
|
};
|
|
12
|
-
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,
|
|
12
|
+
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_wsBalanceFreshUntil, _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_updateActive, _AssetsController_handleAccountTreeStateChange, _AssetsController_runAccountTreeRefresh, _AssetsController_registerActionHandlers, _AssetsController_handleActiveChainsUpdate, _AssetsController_executeMiddlewares, _AssetsController_getNativeAssetMap, _AssetsController_isNativeAsset, _AssetsController_getAssetType, _AssetsController_resolveNativeAssetIds, _AssetsController_getNativeAssetIdsForEnabledChains, _AssetsController_getNativeAssetIdsForAccount, _AssetsController_ensureNativeBalancesDefaultZero, _AssetsController_ensureDefaultTrackedAssetsSeeded, _AssetsController_filterBalancesRespectingWsFreshness, _AssetsController_markWsBalancesFresh, _AssetsController_clearWsBalanceFreshness, _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_refreshAssetsAfterNetworkChange;
|
|
13
13
|
import { BaseController } from "@metamask/base-controller";
|
|
14
14
|
import { clientControllerSelectors } from "@metamask/client-controller";
|
|
15
15
|
import { isCaipChainId, isStrictHexString, KnownCaipNamespace, parseCaipAssetType, parseCaipChainId } from "@metamask/utils";
|
|
@@ -35,7 +35,6 @@ import { RpcFallbackMiddleware } from "./middlewares/RpcFallbackMiddleware.mjs";
|
|
|
35
35
|
import { normalizeAmountString, normalizeAssetId, formatExchangeRatesForBridge, formatStateForTransactionPay, buildNativeAssetsFromConstant, buildNativeAssetsFromApi } from "./utils/index.mjs";
|
|
36
36
|
import { ZERO_ADDRESS } from "./utils/constants.mjs";
|
|
37
37
|
import { pickRpcCustomAssetsSupplement } from "./utils/customAssetsRpcSupplement.mjs";
|
|
38
|
-
import { processAccountActivityBalanceUpdates } from "./utils/processAccountActivityBalanceUpdates.mjs";
|
|
39
38
|
const NATIVE_ASSETS_QUERY_KEY = ['nativeAssets'];
|
|
40
39
|
// ============================================================================
|
|
41
40
|
// CONTROLLER CONSTANTS
|
|
@@ -58,6 +57,15 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
58
57
|
];
|
|
59
58
|
/** Default polling interval hint for data sources (30 seconds) */
|
|
60
59
|
const DEFAULT_POLLING_INTERVAL_MS = 30000;
|
|
60
|
+
/** Sources whose passive polling must not overwrite recent websocket balances. */
|
|
61
|
+
const POLLING_BALANCE_SOURCES = new Set([
|
|
62
|
+
'AccountsApiDataSource',
|
|
63
|
+
'RpcDataSource',
|
|
64
|
+
'SnapDataSource',
|
|
65
|
+
'StakedBalanceDataSource',
|
|
66
|
+
]);
|
|
67
|
+
/** How long websocket balance updates block stale polling overwrites. */
|
|
68
|
+
const WS_BALANCE_FRESHNESS_MS = 120000;
|
|
61
69
|
// ============================================================================
|
|
62
70
|
// TRACE NAMES — used in Sentry spans (search these strings in Discover)
|
|
63
71
|
// ============================================================================
|
|
@@ -187,41 +195,11 @@ function normalizeResponse(response) {
|
|
|
187
195
|
if (response.updateMode) {
|
|
188
196
|
normalized.updateMode = response.updateMode;
|
|
189
197
|
}
|
|
190
|
-
if (response.
|
|
191
|
-
normalized.
|
|
198
|
+
if (response.sourceId) {
|
|
199
|
+
normalized.sourceId = response.sourceId;
|
|
192
200
|
}
|
|
193
201
|
return normalized;
|
|
194
202
|
}
|
|
195
|
-
/**
|
|
196
|
-
* Merge account balances from a data-source response into prior state.
|
|
197
|
-
*
|
|
198
|
-
* @param previousBalances - Balances already in state for this account.
|
|
199
|
-
* @param accountBalances - Balances from the incoming response.
|
|
200
|
-
* @param customAssetIds - Custom assets to preserve when replacing covered chains.
|
|
201
|
-
* @param replaceCoveredChains - When true, drop prior balances on chains present
|
|
202
|
-
* in the response before applying it (authoritative chain slice).
|
|
203
|
-
* @returns The merged balance map for the account.
|
|
204
|
-
*/
|
|
205
|
-
function mergeAccountBalances(previousBalances, accountBalances, customAssetIds, replaceCoveredChains) {
|
|
206
|
-
if (!replaceCoveredChains) {
|
|
207
|
-
return { ...previousBalances, ...accountBalances };
|
|
208
|
-
}
|
|
209
|
-
const coveredChains = new Set(Object.keys(accountBalances).map((assetId) => assetId.split('/')[0]));
|
|
210
|
-
const next = {};
|
|
211
|
-
for (const [assetId, balance] of Object.entries(previousBalances)) {
|
|
212
|
-
if (!coveredChains.has(assetId.split('/')[0])) {
|
|
213
|
-
next[assetId] = balance;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
Object.assign(next, accountBalances);
|
|
217
|
-
for (const customId of customAssetIds) {
|
|
218
|
-
if (!Object.prototype.hasOwnProperty.call(next, customId)) {
|
|
219
|
-
const prev = previousBalances[customId];
|
|
220
|
-
next[customId] = prev ?? { amount: '0' };
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
return next;
|
|
224
|
-
}
|
|
225
203
|
// ============================================================================
|
|
226
204
|
// CONTROLLER IMPLEMENTATION
|
|
227
205
|
// ============================================================================
|
|
@@ -300,6 +278,11 @@ export class AssetsController extends BaseController {
|
|
|
300
278
|
* re-subscriptions when the account set hasn't actually changed.
|
|
301
279
|
*/
|
|
302
280
|
_AssetsController_lastKnownAccountIds.set(this, new Set());
|
|
281
|
+
/**
|
|
282
|
+
* Per `accountId:assetId`, timestamp until which websocket balance updates
|
|
283
|
+
* should not be overwritten by polling/API fetches.
|
|
284
|
+
*/
|
|
285
|
+
_AssetsController_wsBalanceFreshUntil.set(this, new Map());
|
|
303
286
|
_AssetsController_backendWebsocketDataSource.set(this, void 0);
|
|
304
287
|
_AssetsController_accountsApiDataSource.set(this, void 0);
|
|
305
288
|
_AssetsController_snapDataSource.set(this, void 0);
|
|
@@ -448,9 +431,9 @@ export class AssetsController extends BaseController {
|
|
|
448
431
|
// creation, RPC is slow on many chains). Results are committed to state
|
|
449
432
|
// immediately so the UI can display balances without waiting for them.
|
|
450
433
|
//
|
|
451
|
-
//
|
|
452
|
-
//
|
|
453
|
-
//
|
|
434
|
+
// Both the fast and background pipelines use 'merge' mode because neither
|
|
435
|
+
// alone represents the full set of data sources. Using 'full' in either
|
|
436
|
+
// would wipe balances from the sources handled by the other pipeline.
|
|
454
437
|
const fastSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
455
438
|
? [
|
|
456
439
|
createParallelBalanceMiddleware([
|
|
@@ -470,36 +453,39 @@ export class AssetsController extends BaseController {
|
|
|
470
453
|
]
|
|
471
454
|
: [__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f")];
|
|
472
455
|
const { response, durationByDataSource } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, fastSources, request);
|
|
456
|
+
// The fast pipeline only contains a subset of data sources (AccountsApi +
|
|
457
|
+
// StakedBalance), so it must always merge to avoid wiping Snap/RPC
|
|
458
|
+
// balances that the background pipeline hasn't yet replaced.
|
|
473
459
|
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
474
460
|
...response,
|
|
475
461
|
updateMode: 'merge',
|
|
476
|
-
|
|
462
|
+
sourceId: 'getAssets:forceUpdate',
|
|
477
463
|
});
|
|
478
464
|
// Background pipeline: snap and RPC run in parallel after the fast path
|
|
479
465
|
// commits to state. Their balances are merged together before detection.
|
|
480
466
|
// Token + price enrichment matches the pre-split behavior: only when basic
|
|
481
467
|
// functionality is on (RPC-only mode must not call token/price APIs).
|
|
482
|
-
const
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
__classPrivateFieldGet(this,
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
468
|
+
const slowSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
469
|
+
? [__classPrivateFieldGet(this, _AssetsController_snapDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")]
|
|
470
|
+
: [__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")];
|
|
471
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, [
|
|
472
|
+
createParallelBalanceMiddleware(slowSources),
|
|
473
|
+
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
474
|
+
...(__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
475
|
+
? [
|
|
476
|
+
createParallelMiddleware([
|
|
477
|
+
__classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
|
|
478
|
+
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
|
|
479
|
+
]),
|
|
480
|
+
]
|
|
481
|
+
: []),
|
|
482
|
+
], request)
|
|
483
|
+
.then(({ response: slowResponse }) => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
484
|
+
...slowResponse,
|
|
485
|
+
updateMode: 'merge',
|
|
486
|
+
sourceId: 'getAssets:forceUpdate',
|
|
487
|
+
}))
|
|
488
|
+
.catch((error) => log('Background pipeline failed', { error }));
|
|
503
489
|
const durationMs = performance.now() - startTime;
|
|
504
490
|
// Emit trace for every full fetch (Assets Health dashboard)
|
|
505
491
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_FULL_FETCH, {
|
|
@@ -891,8 +877,7 @@ export class AssetsController extends BaseController {
|
|
|
891
877
|
// RPC already fetches custom assets on purpose, and Snap handles non-EVM
|
|
892
878
|
// chains the rule does not apply to, so skip the middleware for those.
|
|
893
879
|
const shouldGraduateCustomAssets = sourceId === 'AccountsApiDataSource' ||
|
|
894
|
-
sourceId === 'BackendWebsocketDataSource'
|
|
895
|
-
sourceId === 'AccountActivityService';
|
|
880
|
+
sourceId === 'BackendWebsocketDataSource';
|
|
896
881
|
const enrichmentSources = [
|
|
897
882
|
...(shouldGraduateCustomAssets
|
|
898
883
|
? [__classPrivateFieldGet(this, _AssetsController_customAssetGraduationMiddleware, "f")]
|
|
@@ -906,10 +891,11 @@ export class AssetsController extends BaseController {
|
|
|
906
891
|
]));
|
|
907
892
|
}
|
|
908
893
|
const { response: enrichedResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, enrichmentSources, pipelineRequest, response);
|
|
909
|
-
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
894
|
+
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, { ...enrichedResponse, sourceId });
|
|
895
|
+
if (sourceId === 'BackendWebsocketDataSource' &&
|
|
896
|
+
enrichedResponse.assetsBalance) {
|
|
897
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_markWsBalancesFresh).call(this, enrichedResponse.assetsBalance);
|
|
898
|
+
}
|
|
913
899
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_UPDATE_PIPELINE, {
|
|
914
900
|
source: sourceId,
|
|
915
901
|
duration_ms: performance.now() - updateStart,
|
|
@@ -956,7 +942,7 @@ export class AssetsController extends BaseController {
|
|
|
956
942
|
this.messenger.unregisterActionHandler('AssetsController:setSelectedCurrency');
|
|
957
943
|
}
|
|
958
944
|
}
|
|
959
|
-
_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 = {
|
|
945
|
+
_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_wsBalanceFreshUntil = 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 = {
|
|
960
946
|
controller: 'AssetsController',
|
|
961
947
|
}) {
|
|
962
948
|
if (!__classPrivateFieldGet(this, _AssetsController_trace, "f")) {
|
|
@@ -1082,11 +1068,11 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
|
|
|
1082
1068
|
// The base-controller `:stateChange` event is guaranteed to fire
|
|
1083
1069
|
// when init() calls this.update(). #start() is idempotent so
|
|
1084
1070
|
// repeated fires are safe.
|
|
1085
|
-
this.messenger.subscribe('AccountTreeController:
|
|
1071
|
+
this.messenger.subscribe('AccountTreeController:stateChange', () => {
|
|
1086
1072
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleAccountTreeStateChange).call(this);
|
|
1087
1073
|
});
|
|
1088
1074
|
// Subscribe to network enablement changes (only enabledNetworkMap)
|
|
1089
|
-
this.messenger.subscribe('NetworkEnablementController:
|
|
1075
|
+
this.messenger.subscribe('NetworkEnablementController:stateChange', ({ enabledNetworkMap }) => {
|
|
1090
1076
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleEnabledNetworksChanged).call(this, enabledNetworkMap).catch(console.error);
|
|
1091
1077
|
});
|
|
1092
1078
|
// When a network is added or removed from NetworkController, refresh
|
|
@@ -1097,20 +1083,13 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
|
|
|
1097
1083
|
// enabled in NetworkEnablementController.
|
|
1098
1084
|
this.messenger.subscribe('NetworkController:networkAdded', (networkConfiguration) => {
|
|
1099
1085
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleNetworkAdded).call(this, networkConfiguration.chainId);
|
|
1100
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m",
|
|
1101
|
-
log('Failed to refresh assets after network added', { error });
|
|
1102
|
-
});
|
|
1086
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_refreshAssetsAfterNetworkChange).call(this);
|
|
1103
1087
|
});
|
|
1104
1088
|
this.messenger.subscribe('NetworkController:networkRemoved', () => {
|
|
1105
1089
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_refreshAssetsAfterNetworkChange).call(this);
|
|
1106
1090
|
});
|
|
1107
|
-
// Selected EVM network switch (network picker). Enablement changes are
|
|
1108
|
-
// handled separately via NetworkEnablementController:stateChanged.
|
|
1109
|
-
this.messenger.subscribe('NetworkController:networkDidChange', (networkState) => {
|
|
1110
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleNetworkDidChange).call(this, networkState).catch(console.error);
|
|
1111
|
-
});
|
|
1112
1091
|
// Client + Keyring lifecycle: only run when UI is open AND keyring is unlocked
|
|
1113
|
-
this.messenger.subscribe('ClientController:
|
|
1092
|
+
this.messenger.subscribe('ClientController:stateChange', (isUiOpen) => {
|
|
1114
1093
|
__classPrivateFieldSet(this, _AssetsController_uiOpen, isUiOpen, "f");
|
|
1115
1094
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateActive).call(this);
|
|
1116
1095
|
}, clientControllerSelectors.selectIsUiOpen);
|
|
@@ -1127,18 +1106,6 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
|
|
|
1127
1106
|
this.messenger.subscribe('TransactionController:unapprovedTransactionAdded', (transactionMeta) => {
|
|
1128
1107
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_onUnapprovedTransactionAdded).call(this, transactionMeta);
|
|
1129
1108
|
});
|
|
1130
|
-
// Post-tx refresh via the full fetch pipeline (Accounts API + RPC fallback).
|
|
1131
|
-
// RpcDataSource also listens for transactionConfirmed, but only refreshes
|
|
1132
|
-
// chains it owns via an active subscription.
|
|
1133
|
-
this.messenger.subscribe('TransactionController:transactionConfirmed', (transactionMeta) => {
|
|
1134
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_onTransactionConfirmed).call(this, transactionMeta);
|
|
1135
|
-
});
|
|
1136
|
-
// Real-time post-tx balances from AccountActivityService (same WS payload as
|
|
1137
|
-
// TokenBalancesController; BackendWebsocketDataSource may not receive the
|
|
1138
|
-
// callback when AccountActivityService owns the server subscription).
|
|
1139
|
-
this.messenger.subscribe('AccountActivityService:balanceUpdated', (event) => {
|
|
1140
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_onAccountActivityBalanceUpdated).call(this, event);
|
|
1141
|
-
});
|
|
1142
1109
|
}, _AssetsController_onUnapprovedTransactionAdded = function _AssetsController_onUnapprovedTransactionAdded(transactionMeta) {
|
|
1143
1110
|
const hexChainId = transactionMeta.chainId;
|
|
1144
1111
|
if (!hexChainId) {
|
|
@@ -1161,46 +1128,6 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
|
|
|
1161
1128
|
error,
|
|
1162
1129
|
});
|
|
1163
1130
|
});
|
|
1164
|
-
}, _AssetsController_onTransactionConfirmed = function _AssetsController_onTransactionConfirmed(transactionMeta) {
|
|
1165
|
-
const hexChainId = transactionMeta.chainId;
|
|
1166
|
-
if (!hexChainId) {
|
|
1167
|
-
return;
|
|
1168
|
-
}
|
|
1169
|
-
const caipChainId = `eip155:${parseInt(hexChainId, 16)}`;
|
|
1170
|
-
const fromAddress = transactionMeta.txParams.from?.toLowerCase();
|
|
1171
|
-
if (!fromAddress) {
|
|
1172
|
-
return;
|
|
1173
|
-
}
|
|
1174
|
-
const matchedAccount = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((account) => account.address.toLowerCase() === fromAddress);
|
|
1175
|
-
if (!matchedAccount) {
|
|
1176
|
-
return;
|
|
1177
|
-
}
|
|
1178
|
-
this.getAssets([matchedAccount], {
|
|
1179
|
-
chainIds: [caipChainId],
|
|
1180
|
-
forceUpdate: true,
|
|
1181
|
-
}).catch((error) => {
|
|
1182
|
-
log('Failed to refresh assets after transaction confirmed', { error });
|
|
1183
|
-
});
|
|
1184
|
-
}, _AssetsController_onAccountActivityBalanceUpdated = function _AssetsController_onAccountActivityBalanceUpdated({ address, chain, updates, }) {
|
|
1185
|
-
const account = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((a) => a.address.startsWith('0x')
|
|
1186
|
-
? a.address.toLowerCase() === address.toLowerCase()
|
|
1187
|
-
: a.address === address);
|
|
1188
|
-
if (!account) {
|
|
1189
|
-
return;
|
|
1190
|
-
}
|
|
1191
|
-
const chainId = chain;
|
|
1192
|
-
const response = processAccountActivityBalanceUpdates(updates, account.id, (assetId) => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetType).call(this, assetId));
|
|
1193
|
-
if (!response.assetsBalance) {
|
|
1194
|
-
return;
|
|
1195
|
-
}
|
|
1196
|
-
const request = {
|
|
1197
|
-
accountsWithSupportedChains: [{ account, supportedChains: [chainId] }],
|
|
1198
|
-
chainIds: [chainId],
|
|
1199
|
-
dataTypes: ['balance', 'metadata'],
|
|
1200
|
-
};
|
|
1201
|
-
this.handleAssetsUpdate(response, 'AccountActivityService', request).catch((error) => {
|
|
1202
|
-
log('Failed to apply AccountActivityService balance update', { error });
|
|
1203
|
-
});
|
|
1204
1131
|
}, _AssetsController_updateActive = function _AssetsController_updateActive() {
|
|
1205
1132
|
const shouldRun = __classPrivateFieldGet(this, _AssetsController_uiOpen, "f") && __classPrivateFieldGet(this, _AssetsController_keyringUnlocked, "f");
|
|
1206
1133
|
if (shouldRun) {
|
|
@@ -1256,32 +1183,6 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
|
|
|
1256
1183
|
finally {
|
|
1257
1184
|
releaseLock();
|
|
1258
1185
|
}
|
|
1259
|
-
}, _AssetsController_runStartupRefresh =
|
|
1260
|
-
/**
|
|
1261
|
-
* Force-fetch balances then subscribe. Used on unlock / first startup.
|
|
1262
|
-
*
|
|
1263
|
-
* @param accounts - Selected accounts to refresh.
|
|
1264
|
-
*/
|
|
1265
|
-
async function _AssetsController_runStartupRefresh(accounts) {
|
|
1266
|
-
const releaseLock = await __classPrivateFieldGet(this, _AssetsController_accountRefreshMutex, "f").acquire();
|
|
1267
|
-
try {
|
|
1268
|
-
await this.getAssets(accounts, {
|
|
1269
|
-
chainIds: [...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f")],
|
|
1270
|
-
forceUpdate: true,
|
|
1271
|
-
});
|
|
1272
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
1273
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
1274
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureDefaultTrackedAssetsSeeded).call(this);
|
|
1275
|
-
}
|
|
1276
|
-
catch (error) {
|
|
1277
|
-
log('Failed to fetch assets on startup', error);
|
|
1278
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
1279
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
1280
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureDefaultTrackedAssetsSeeded).call(this);
|
|
1281
|
-
}
|
|
1282
|
-
finally {
|
|
1283
|
-
releaseLock();
|
|
1284
|
-
}
|
|
1285
1186
|
}, _AssetsController_registerActionHandlers = function _AssetsController_registerActionHandlers() {
|
|
1286
1187
|
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
1287
1188
|
}, _AssetsController_handleActiveChainsUpdate = function _AssetsController_handleActiveChainsUpdate(dataSourceId, activeChains, previousChains) {
|
|
@@ -1395,41 +1296,6 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1395
1296
|
});
|
|
1396
1297
|
}
|
|
1397
1298
|
return { response: result.response, durationByDataSource };
|
|
1398
|
-
}, _AssetsController_fetchMissingPricesWithoutCache = function _AssetsController_fetchMissingPricesWithoutCache(accounts, chainIds) {
|
|
1399
|
-
if (!__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this) || accounts.length === 0) {
|
|
1400
|
-
return;
|
|
1401
|
-
}
|
|
1402
|
-
const accountIds = new Set(accounts.map((account) => account.id));
|
|
1403
|
-
const chainFilter = new Set(chainIds);
|
|
1404
|
-
const assetsForPriceUpdate = [];
|
|
1405
|
-
const prices = this.state.assetsPrice;
|
|
1406
|
-
for (const [accountId, accountBalances] of Object.entries(this.state.assetsBalance)) {
|
|
1407
|
-
if (!accountIds.has(accountId)) {
|
|
1408
|
-
continue;
|
|
1409
|
-
}
|
|
1410
|
-
for (const assetId of Object.keys(accountBalances)) {
|
|
1411
|
-
if (!chainFilter.has(assetId.split('/')[0])) {
|
|
1412
|
-
continue;
|
|
1413
|
-
}
|
|
1414
|
-
const normalizedAssetId = normalizeAssetId(assetId);
|
|
1415
|
-
if (prices[normalizedAssetId] ?? prices[assetId]) {
|
|
1416
|
-
continue;
|
|
1417
|
-
}
|
|
1418
|
-
assetsForPriceUpdate.push(normalizedAssetId);
|
|
1419
|
-
}
|
|
1420
|
-
}
|
|
1421
|
-
if (assetsForPriceUpdate.length === 0) {
|
|
1422
|
-
return;
|
|
1423
|
-
}
|
|
1424
|
-
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f").invalidatePriceCache();
|
|
1425
|
-
this.getAssets(accounts, {
|
|
1426
|
-
forceUpdate: true,
|
|
1427
|
-
dataTypes: ['price'],
|
|
1428
|
-
chainIds,
|
|
1429
|
-
assetsForPriceUpdate,
|
|
1430
|
-
}).catch((error) => {
|
|
1431
|
-
log('Failed to fetch missing prices', { error });
|
|
1432
|
-
});
|
|
1433
1299
|
}, _AssetsController_getNativeAssetMap = function _AssetsController_getNativeAssetMap() {
|
|
1434
1300
|
return (__classPrivateFieldGet(this, _AssetsController_queryApiClient, "f").getCachedData(NATIVE_ASSETS_QUERY_KEY) ?? {});
|
|
1435
1301
|
}, _AssetsController_isNativeAsset = function _AssetsController_isNativeAsset(assetId) {
|
|
@@ -1471,17 +1337,6 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1471
1337
|
return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_resolveNativeAssetIds).call(this, __classPrivateFieldGet(this, _AssetsController_enabledChains, "f"));
|
|
1472
1338
|
}, _AssetsController_getNativeAssetIdsForAccount = function _AssetsController_getNativeAssetIdsForAccount(account) {
|
|
1473
1339
|
return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_resolveNativeAssetIds).call(this, __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getEnabledChainsForAccount).call(this, account));
|
|
1474
|
-
}, _AssetsController_getSlowPipelineChainIds = function _AssetsController_getSlowPipelineChainIds(chainIds, fastResponse) {
|
|
1475
|
-
const accountsApiChains = new Set(__classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f").getActiveChainsSync());
|
|
1476
|
-
return chainIds.filter((chainId) => {
|
|
1477
|
-
if (fastResponse.errors?.[chainId]) {
|
|
1478
|
-
return true;
|
|
1479
|
-
}
|
|
1480
|
-
if (!accountsApiChains.has(chainId)) {
|
|
1481
|
-
return true;
|
|
1482
|
-
}
|
|
1483
|
-
return false;
|
|
1484
|
-
});
|
|
1485
1340
|
}, _AssetsController_ensureNativeBalancesDefaultZero = function _AssetsController_ensureNativeBalancesDefaultZero() {
|
|
1486
1341
|
const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this);
|
|
1487
1342
|
if (accounts.length === 0) {
|
|
@@ -1499,7 +1354,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1499
1354
|
balances[accountId] = {};
|
|
1500
1355
|
}
|
|
1501
1356
|
for (const nativeAssetId of nativeAssetIds) {
|
|
1502
|
-
if (!
|
|
1357
|
+
if (!(nativeAssetId in balances[accountId])) {
|
|
1503
1358
|
balances[accountId][nativeAssetId] = { amount: '0' };
|
|
1504
1359
|
}
|
|
1505
1360
|
}
|
|
@@ -1549,9 +1404,37 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1549
1404
|
}
|
|
1550
1405
|
}
|
|
1551
1406
|
});
|
|
1407
|
+
}, _AssetsController_filterBalancesRespectingWsFreshness = function _AssetsController_filterBalancesRespectingWsFreshness(accountId, accountBalances, sourceId) {
|
|
1408
|
+
if (!sourceId || !POLLING_BALANCE_SOURCES.has(sourceId)) {
|
|
1409
|
+
return accountBalances;
|
|
1410
|
+
}
|
|
1411
|
+
const now = Date.now();
|
|
1412
|
+
const filtered = {};
|
|
1413
|
+
for (const [assetId, balance] of Object.entries(accountBalances)) {
|
|
1414
|
+
const freshUntil = __classPrivateFieldGet(this, _AssetsController_wsBalanceFreshUntil, "f").get(`${accountId}:${assetId}`);
|
|
1415
|
+
if (freshUntil !== undefined && now < freshUntil) {
|
|
1416
|
+
continue;
|
|
1417
|
+
}
|
|
1418
|
+
filtered[assetId] = balance;
|
|
1419
|
+
}
|
|
1420
|
+
return filtered;
|
|
1421
|
+
}, _AssetsController_markWsBalancesFresh = function _AssetsController_markWsBalancesFresh(assetsBalance) {
|
|
1422
|
+
const freshUntil = Date.now() + WS_BALANCE_FRESHNESS_MS;
|
|
1423
|
+
for (const [accountId, balances] of Object.entries(assetsBalance)) {
|
|
1424
|
+
for (const assetId of Object.keys(balances)) {
|
|
1425
|
+
__classPrivateFieldGet(this, _AssetsController_wsBalanceFreshUntil, "f").set(`${accountId}:${assetId}`, freshUntil);
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
}, _AssetsController_clearWsBalanceFreshness = function _AssetsController_clearWsBalanceFreshness(assetsBalance) {
|
|
1429
|
+
for (const [accountId, balances] of Object.entries(assetsBalance)) {
|
|
1430
|
+
for (const assetId of Object.keys(balances)) {
|
|
1431
|
+
__classPrivateFieldGet(this, _AssetsController_wsBalanceFreshUntil, "f").delete(`${accountId}:${assetId}`);
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1552
1434
|
}, _AssetsController_updateState = async function _AssetsController_updateState(response) {
|
|
1553
1435
|
const normalizedResponse = normalizeResponse(response);
|
|
1554
1436
|
const mode = normalizedResponse.updateMode ?? 'merge';
|
|
1437
|
+
const assetsBalanceToApply = normalizedResponse.assetsBalance;
|
|
1555
1438
|
const releaseLock = await __classPrivateFieldGet(this, _AssetsController_controllerMutex, "f").acquire();
|
|
1556
1439
|
try {
|
|
1557
1440
|
const previousState = this.state;
|
|
@@ -1612,20 +1495,48 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1612
1495
|
}
|
|
1613
1496
|
}
|
|
1614
1497
|
}
|
|
1615
|
-
if (
|
|
1616
|
-
for (const [accountId, accountBalances] of Object.entries(
|
|
1498
|
+
if (assetsBalanceToApply) {
|
|
1499
|
+
for (const [accountId, accountBalances] of Object.entries(assetsBalanceToApply)) {
|
|
1500
|
+
const filteredAccountBalances = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_filterBalancesRespectingWsFreshness).call(this, accountId, accountBalances, normalizedResponse.sourceId);
|
|
1617
1501
|
const previousBalances = previousState.assetsBalance[accountId] ?? {};
|
|
1618
1502
|
const customAssetIds = state.customAssets[accountId] ?? [];
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1503
|
+
// Full: response is authoritative for the chains it covered;
|
|
1504
|
+
// balances for chains not in the response are preserved from
|
|
1505
|
+
// previous state so unsupported chains (e.g. Ink on AccountsAPI)
|
|
1506
|
+
// are never inadvertently reset to zero.
|
|
1507
|
+
// Merge: response overlays previous balances.
|
|
1508
|
+
const effective = mode === 'merge'
|
|
1509
|
+
? { ...previousBalances, ...filteredAccountBalances }
|
|
1510
|
+
: (() => {
|
|
1511
|
+
// Determine which chain namespaces this response covers.
|
|
1512
|
+
const coveredChains = new Set(Object.keys(filteredAccountBalances).map((assetId) => assetId.split('/')[0]));
|
|
1513
|
+
// Start from previous balances, dropping only entries for
|
|
1514
|
+
// chains this response is authoritative over.
|
|
1515
|
+
const next = {};
|
|
1516
|
+
for (const [assetId, balance] of Object.entries(previousBalances)) {
|
|
1517
|
+
if (!coveredChains.has(assetId.split('/')[0])) {
|
|
1518
|
+
next[assetId] = balance;
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
// Apply the response (authoritative for covered chains).
|
|
1522
|
+
Object.assign(next, filteredAccountBalances);
|
|
1523
|
+
// Preserve custom assets that the response omitted.
|
|
1524
|
+
for (const customId of customAssetIds) {
|
|
1525
|
+
if (!(customId in next)) {
|
|
1526
|
+
const prev = previousBalances[customId];
|
|
1527
|
+
next[customId] =
|
|
1528
|
+
prev ?? { amount: '0' };
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
return next;
|
|
1532
|
+
})();
|
|
1622
1533
|
// Ensure native tokens have an entry (0 if missing) for chains this account supports
|
|
1623
1534
|
const account = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((a) => a.id === accountId);
|
|
1624
1535
|
const nativeAssetIdsForAccount = account
|
|
1625
1536
|
? __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForAccount).call(this, account)
|
|
1626
1537
|
: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForEnabledChains).call(this);
|
|
1627
1538
|
for (const nativeAssetId of nativeAssetIdsForAccount) {
|
|
1628
|
-
if (!
|
|
1539
|
+
if (!(nativeAssetId in effective)) {
|
|
1629
1540
|
effective[nativeAssetId] = { amount: '0' };
|
|
1630
1541
|
}
|
|
1631
1542
|
}
|
|
@@ -1657,6 +1568,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1657
1568
|
balances[accountId] = effective;
|
|
1658
1569
|
}
|
|
1659
1570
|
}
|
|
1571
|
+
// Update prices in state
|
|
1660
1572
|
if (normalizedResponse.assetsPrice) {
|
|
1661
1573
|
for (const [key, value] of Object.entries(normalizedResponse.assetsPrice)) {
|
|
1662
1574
|
prices[key] = value;
|
|
@@ -1719,6 +1631,12 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1719
1631
|
});
|
|
1720
1632
|
}
|
|
1721
1633
|
}
|
|
1634
|
+
// Authoritative fetch on account switch — drop WS freshness locks so API
|
|
1635
|
+
// balances (e.g. receiver +1 USDC) replace stale values from a prior send.
|
|
1636
|
+
if (normalizedResponse.sourceId === 'getAssets:forceUpdate' &&
|
|
1637
|
+
assetsBalanceToApply) {
|
|
1638
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_clearWsBalanceFreshness).call(this, assetsBalanceToApply);
|
|
1639
|
+
}
|
|
1722
1640
|
}
|
|
1723
1641
|
finally {
|
|
1724
1642
|
releaseLock();
|
|
@@ -1817,8 +1735,14 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1817
1735
|
enabledChainCount: chainIds.length,
|
|
1818
1736
|
});
|
|
1819
1737
|
__classPrivateFieldSet(this, _AssetsController_lastKnownAccountIds, new Set(accounts.map((a) => a.id)), "f");
|
|
1820
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m",
|
|
1821
|
-
|
|
1738
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
1739
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
1740
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureDefaultTrackedAssetsSeeded).call(this);
|
|
1741
|
+
this.getAssets(accounts, {
|
|
1742
|
+
chainIds,
|
|
1743
|
+
forceUpdate: true,
|
|
1744
|
+
}).catch((error) => {
|
|
1745
|
+
log('Failed to fetch assets', error);
|
|
1822
1746
|
});
|
|
1823
1747
|
}, _AssetsController_stop = function _AssetsController_stop() {
|
|
1824
1748
|
log('Stopping asset tracking', {
|
|
@@ -1896,13 +1820,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1896
1820
|
const seenIds = new Set();
|
|
1897
1821
|
const accountsForSource = assignedChains
|
|
1898
1822
|
.flatMap((chainId) => chainToAccounts.get(chainId) ?? [])
|
|
1899
|
-
.filter((account) =>
|
|
1900
|
-
if (seenIds.has(account.id)) {
|
|
1901
|
-
return false;
|
|
1902
|
-
}
|
|
1903
|
-
seenIds.add(account.id);
|
|
1904
|
-
return true;
|
|
1905
|
-
});
|
|
1823
|
+
.filter((account) => !seenIds.has(account.id) && (seenIds.add(account.id), true));
|
|
1906
1824
|
if (accountsForSource.length > 0) {
|
|
1907
1825
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeDataSource).call(this, source, accountsForSource, assignedChains);
|
|
1908
1826
|
}
|
|
@@ -2164,102 +2082,11 @@ async function _AssetsController_handleAccountGroupChanged() {
|
|
|
2164
2082
|
caipChainId,
|
|
2165
2083
|
});
|
|
2166
2084
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureDefaultTrackedAssetsSeeded).call(this, [caipChainId]);
|
|
2167
|
-
}, _AssetsController_refreshActiveChainsOnNetworkSwitch =
|
|
2168
|
-
/**
|
|
2169
|
-
* Refresh data-source `activeChains` after an EVM network switch so API/WS/Rpc
|
|
2170
|
-
* chain claiming is not stuck on an empty or stale init-time list.
|
|
2171
|
-
*/
|
|
2172
|
-
async function _AssetsController_refreshActiveChainsOnNetworkSwitch() {
|
|
2173
|
-
await Promise.all([
|
|
2174
|
-
__classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f").refreshActiveChains(),
|
|
2175
|
-
__classPrivateFieldGet(this, _AssetsController_backendWebsocketDataSource, "f").refreshActiveChains(),
|
|
2176
|
-
]);
|
|
2177
|
-
__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f").refreshActiveChainsFromNetworkState();
|
|
2178
|
-
}, _AssetsController_getSelectedEvmChainIdFromNetworkState = function _AssetsController_getSelectedEvmChainIdFromNetworkState(networkState) {
|
|
2179
|
-
try {
|
|
2180
|
-
const networkClient = this.messenger.call('NetworkController:getNetworkClientById', networkState.selectedNetworkClientId);
|
|
2181
|
-
const hexChainId = networkClient.configuration?.chainId;
|
|
2182
|
-
if (!hexChainId) {
|
|
2183
|
-
return undefined;
|
|
2184
|
-
}
|
|
2185
|
-
return `eip155:${parseInt(hexChainId, 16)}`;
|
|
2186
|
-
}
|
|
2187
|
-
catch {
|
|
2188
|
-
return undefined;
|
|
2189
|
-
}
|
|
2190
|
-
}, _AssetsController_handleNetworkDidChange =
|
|
2191
|
-
/**
|
|
2192
|
-
* Refresh subscriptions and fetch balances when the user switches the
|
|
2193
|
-
* selected EVM network in the UI (`NetworkController:networkDidChange`).
|
|
2194
|
-
*
|
|
2195
|
-
* @param networkState - NetworkController state after the switch.
|
|
2196
|
-
*/
|
|
2197
|
-
async function _AssetsController_handleNetworkDidChange(networkState) {
|
|
2198
|
-
if (!__classPrivateFieldGet(this, _AssetsController_uiOpen, "f") || !__classPrivateFieldGet(this, _AssetsController_keyringUnlocked, "f") || !__classPrivateFieldGet(this, _AssetsController_isEnabled, "f").call(this)) {
|
|
2199
|
-
return;
|
|
2200
|
-
}
|
|
2201
|
-
const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this);
|
|
2202
|
-
if (accounts.length === 0) {
|
|
2203
|
-
return;
|
|
2204
|
-
}
|
|
2205
|
-
const selectedChainId = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedEvmChainIdFromNetworkState).call(this, networkState);
|
|
2206
|
-
if (!selectedChainId) {
|
|
2207
|
-
return;
|
|
2208
|
-
}
|
|
2209
|
-
log('Selected EVM network switched', {
|
|
2210
|
-
selectedNetworkClientId: networkState.selectedNetworkClientId,
|
|
2211
|
-
selectedChainId,
|
|
2212
|
-
});
|
|
2213
|
-
const releaseLock = await __classPrivateFieldGet(this, _AssetsController_accountRefreshMutex, "f").acquire();
|
|
2214
|
-
try {
|
|
2215
|
-
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_refreshActiveChainsOnNetworkSwitch).call(this);
|
|
2216
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
|
|
2217
|
-
await this.getAssets(accounts, {
|
|
2218
|
-
chainIds: [selectedChainId],
|
|
2219
|
-
forceUpdate: true,
|
|
2220
|
-
dataTypes: ['balance', 'metadata', 'price'],
|
|
2221
|
-
});
|
|
2222
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
2223
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_fetchMissingPricesWithoutCache).call(this, accounts, [selectedChainId]);
|
|
2224
|
-
}
|
|
2225
|
-
finally {
|
|
2226
|
-
releaseLock();
|
|
2227
|
-
}
|
|
2228
2085
|
}, _AssetsController_refreshAssetsAfterNetworkChange = function _AssetsController_refreshAssetsAfterNetworkChange() {
|
|
2229
|
-
|
|
2230
|
-
if (accounts.length === 0) {
|
|
2231
|
-
return;
|
|
2232
|
-
}
|
|
2233
|
-
this.getAssets(accounts, {
|
|
2086
|
+
this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this), {
|
|
2234
2087
|
forceUpdate: true,
|
|
2235
|
-
dataTypes: ['balance', 'metadata'],
|
|
2236
2088
|
}).catch((error) => {
|
|
2237
2089
|
log('Failed to refresh assets after network change', { error });
|
|
2238
2090
|
});
|
|
2239
|
-
}, _AssetsController_refreshAssetsAfterNetworkAdded =
|
|
2240
|
-
/**
|
|
2241
|
-
* Refresh balances and fetch missing prices after a network is added.
|
|
2242
|
-
*
|
|
2243
|
-
* @param hexChainId - Hex chain id of the newly-added network.
|
|
2244
|
-
*/
|
|
2245
|
-
async function _AssetsController_refreshAssetsAfterNetworkAdded(hexChainId) {
|
|
2246
|
-
const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this);
|
|
2247
|
-
if (accounts.length === 0) {
|
|
2248
|
-
return;
|
|
2249
|
-
}
|
|
2250
|
-
let caipChainId;
|
|
2251
|
-
try {
|
|
2252
|
-
caipChainId = `eip155:${parseInt(hexChainId, 16)}`;
|
|
2253
|
-
}
|
|
2254
|
-
catch {
|
|
2255
|
-
return;
|
|
2256
|
-
}
|
|
2257
|
-
await this.getAssets(accounts, {
|
|
2258
|
-
chainIds: [caipChainId],
|
|
2259
|
-
forceUpdate: true,
|
|
2260
|
-
dataTypes: ['balance', 'metadata', 'price'],
|
|
2261
|
-
});
|
|
2262
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
|
|
2263
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_fetchMissingPricesWithoutCache).call(this, accounts, [caipChainId]);
|
|
2264
2091
|
};
|
|
2265
2092
|
//# sourceMappingURL=AssetsController.mjs.map
|