@metamask-previews/assets-controller 9.1.0-preview-9298fa429 → 9.1.0-preview-574b60e35
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 +6 -6
- package/dist/AssetsController.cjs +130 -150
- package/dist/AssetsController.cjs.map +1 -1
- package/dist/AssetsController.d.cts +7 -10
- package/dist/AssetsController.d.cts.map +1 -1
- package/dist/AssetsController.d.mts +7 -10
- package/dist/AssetsController.d.mts.map +1 -1
- package/dist/AssetsController.mjs +130 -150
- package/dist/AssetsController.mjs.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.cjs +1 -1
- package/dist/data-sources/AccountsApiDataSource.cjs.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.mjs +1 -1
- package/dist/data-sources/AccountsApiDataSource.mjs.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.cjs +60 -26
- package/dist/data-sources/BackendWebsocketDataSource.cjs.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.d.cts.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.d.mts.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.mjs +57 -26
- package/dist/data-sources/BackendWebsocketDataSource.mjs.map +1 -1
- package/dist/data-sources/PriceDataSource.cjs +0 -2
- 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 +0 -2
- package/dist/data-sources/PriceDataSource.mjs.map +1 -1
- package/dist/data-sources/RpcDataSource.cjs +2 -3
- package/dist/data-sources/RpcDataSource.cjs.map +1 -1
- package/dist/data-sources/RpcDataSource.d.cts.map +1 -1
- package/dist/data-sources/RpcDataSource.d.mts.map +1 -1
- package/dist/data-sources/RpcDataSource.mjs +2 -3
- package/dist/data-sources/RpcDataSource.mjs.map +1 -1
- package/dist/data-sources/SnapDataSource.cjs +3 -3
- package/dist/data-sources/SnapDataSource.cjs.map +1 -1
- package/dist/data-sources/SnapDataSource.mjs +3 -3
- package/dist/data-sources/SnapDataSource.mjs.map +1 -1
- package/dist/middlewares/ParallelMiddleware.cjs +0 -9
- 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 -9
- package/dist/middlewares/ParallelMiddleware.mjs.map +1 -1
- package/dist/selectors/balance.cjs +5 -1
- package/dist/selectors/balance.cjs.map +1 -1
- package/dist/selectors/balance.d.cts.map +1 -1
- package/dist/selectors/balance.d.mts.map +1 -1
- package/dist/selectors/balance.mjs +5 -1
- package/dist/selectors/balance.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +10 -8
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +10 -8
- package/dist/types.d.mts.map +1 -1
- package/dist/types.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
package/CHANGELOG.md
CHANGED
|
@@ -7,19 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Add `MERGE_BALANCES_IGNORE_LIST` is `balances.ts` selectors with Arc ERC20 USDC to ignore in balance total ([#9277](https://github.com/MetaMask/core/pull/9277))
|
|
13
|
+
|
|
10
14
|
### Changed
|
|
11
15
|
|
|
12
|
-
- **BREAKING:** `AssetsController` messenger must now allow `AccountActivityService:balanceUpdated` so unified `assetsBalance` state receives real-time websocket balance updates when `AccountActivityService` owns the server subscription ([#9273](https://github.com/MetaMask/core/pull/9273))
|
|
13
16
|
- Bump `@metamask/transaction-controller` from `^68.1.1` to `^68.2.0` ([#9253](https://github.com/MetaMask/core/pull/9253))
|
|
14
17
|
|
|
15
18
|
### Fixed
|
|
16
19
|
|
|
17
|
-
- Fix stale token balances after transactions when switching accounts or when websocket subscriptions reconnect; `AssetsController` now fetches before re-subscribing on account switch
|
|
20
|
+
- Fix stale token balances after transactions when switching accounts or when websocket subscriptions reconnect; `AssetsController` now fetches before re-subscribing on account switch, serializes overlapping refresh work, treats `getAssets({ forceUpdate: true })` as authoritative over recent websocket freshness guards, and prevents passive polling from overwriting websocket balances for 120 seconds ([#9265](https://github.com/MetaMask/core/pull/9265))
|
|
18
21
|
- `AccountsApiDataSource` bypasses the TanStack Query balance cache when `forceUpdate` is true so forced refreshes return up-to-date balances instead of 60-second cached values ([#9265](https://github.com/MetaMask/core/pull/9265))
|
|
19
|
-
- `BackendWebsocketDataSource` re-subscribes when subscribed accounts change (case-insensitive EVM address matching), serializes subscribe/unsubscribe to prevent races on account switch, and registers channel callbacks
|
|
20
|
-
- Remove the 120-second websocket balance freshness guard that blocked force-refresh and polling updates from correcting stale websocket balances ([#9273](https://github.com/MetaMask/core/pull/9273))
|
|
21
|
-
- Add `update` balance update mode so fetch and force-refresh pipelines patch balances without removing tokens omitted from partial API snapshots; `getAssets({ forceUpdate: true })`, `AccountsApiDataSource`, and `SnapDataSource` use this mode ([#9273](https://github.com/MetaMask/core/pull/9273))
|
|
22
|
-
- `BackendWebsocketDataSource` registers subscription handlers before the subscribe handshake so in-flight account-activity notifications are not dropped, cleans up subscription state on subscribe failure, and resolves balance updates from stored subscription state when notifications arrive with stale subscription IDs ([#9273](https://github.com/MetaMask/core/pull/9273))
|
|
22
|
+
- `BackendWebsocketDataSource` re-subscribes when subscribed accounts change (case-insensitive EVM address matching), serializes subscribe/unsubscribe to prevent races on account switch, and registers optional channel callbacks for more reliable notification delivery ([#9265](https://github.com/MetaMask/core/pull/9265))
|
|
23
23
|
|
|
24
24
|
## [9.1.0]
|
|
25
25
|
|
|
@@ -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, _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,
|
|
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_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;
|
|
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,7 +40,6 @@ 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");
|
|
44
43
|
const NATIVE_ASSETS_QUERY_KEY = ['nativeAssets'];
|
|
45
44
|
// ============================================================================
|
|
46
45
|
// CONTROLLER CONSTANTS
|
|
@@ -63,6 +62,15 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
63
62
|
];
|
|
64
63
|
/** Default polling interval hint for data sources (30 seconds) */
|
|
65
64
|
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;
|
|
66
74
|
// ============================================================================
|
|
67
75
|
// TRACE NAMES — used in Sentry spans (search these strings in Discover)
|
|
68
76
|
// ============================================================================
|
|
@@ -193,6 +201,9 @@ function normalizeResponse(response) {
|
|
|
193
201
|
if (response.updateMode) {
|
|
194
202
|
normalized.updateMode = response.updateMode;
|
|
195
203
|
}
|
|
204
|
+
if (response.sourceId) {
|
|
205
|
+
normalized.sourceId = response.sourceId;
|
|
206
|
+
}
|
|
196
207
|
return normalized;
|
|
197
208
|
}
|
|
198
209
|
// ============================================================================
|
|
@@ -273,6 +284,11 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
273
284
|
* re-subscriptions when the account set hasn't actually changed.
|
|
274
285
|
*/
|
|
275
286
|
_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());
|
|
276
292
|
_AssetsController_backendWebsocketDataSource.set(this, void 0);
|
|
277
293
|
_AssetsController_accountsApiDataSource.set(this, void 0);
|
|
278
294
|
_AssetsController_snapDataSource.set(this, void 0);
|
|
@@ -421,9 +437,9 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
421
437
|
// creation, RPC is slow on many chains). Results are committed to state
|
|
422
438
|
// immediately so the UI can display balances without waiting for them.
|
|
423
439
|
//
|
|
424
|
-
//
|
|
425
|
-
//
|
|
426
|
-
//
|
|
440
|
+
// Both the fast and background pipelines use 'merge' mode because neither
|
|
441
|
+
// alone represents the full set of data sources. Using 'full' in either
|
|
442
|
+
// would wipe balances from the sources handled by the other pipeline.
|
|
427
443
|
const fastSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
428
444
|
? [
|
|
429
445
|
(0, ParallelMiddleware_1.createParallelBalanceMiddleware)([
|
|
@@ -443,32 +459,39 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
443
459
|
]
|
|
444
460
|
: [__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f")];
|
|
445
461
|
const { response, durationByDataSource } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, fastSources, request);
|
|
446
|
-
|
|
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
|
+
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
466
|
+
...response,
|
|
467
|
+
updateMode: 'merge',
|
|
468
|
+
sourceId: 'getAssets:forceUpdate',
|
|
469
|
+
});
|
|
447
470
|
// Background pipeline: snap and RPC run in parallel after the fast path
|
|
448
471
|
// commits to state. Their balances are merged together before detection.
|
|
449
472
|
// Token + price enrichment matches the pre-split behavior: only when basic
|
|
450
473
|
// functionality is on (RPC-only mode must not call token/price APIs).
|
|
451
|
-
const
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
__classPrivateFieldGet(this,
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
474
|
+
const slowSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
475
|
+
? [__classPrivateFieldGet(this, _AssetsController_snapDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")]
|
|
476
|
+
: [__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")];
|
|
477
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, [
|
|
478
|
+
(0, ParallelMiddleware_1.createParallelBalanceMiddleware)(slowSources),
|
|
479
|
+
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
480
|
+
...(__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
481
|
+
? [
|
|
482
|
+
(0, ParallelMiddleware_1.createParallelMiddleware)([
|
|
483
|
+
__classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
|
|
484
|
+
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
|
|
485
|
+
]),
|
|
486
|
+
]
|
|
487
|
+
: []),
|
|
488
|
+
], request)
|
|
489
|
+
.then(({ response: slowResponse }) => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
490
|
+
...slowResponse,
|
|
491
|
+
updateMode: 'merge',
|
|
492
|
+
sourceId: 'getAssets:forceUpdate',
|
|
493
|
+
}))
|
|
494
|
+
.catch((error) => log('Background pipeline failed', { error }));
|
|
472
495
|
const durationMs = performance.now() - startTime;
|
|
473
496
|
// Emit trace for every full fetch (Assets Health dashboard)
|
|
474
497
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_FULL_FETCH, {
|
|
@@ -860,8 +883,7 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
860
883
|
// RPC already fetches custom assets on purpose, and Snap handles non-EVM
|
|
861
884
|
// chains the rule does not apply to, so skip the middleware for those.
|
|
862
885
|
const shouldGraduateCustomAssets = sourceId === 'AccountsApiDataSource' ||
|
|
863
|
-
sourceId === 'BackendWebsocketDataSource'
|
|
864
|
-
sourceId === 'AccountActivityService';
|
|
886
|
+
sourceId === 'BackendWebsocketDataSource';
|
|
865
887
|
const enrichmentSources = [
|
|
866
888
|
...(shouldGraduateCustomAssets
|
|
867
889
|
? [__classPrivateFieldGet(this, _AssetsController_customAssetGraduationMiddleware, "f")]
|
|
@@ -875,7 +897,11 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
875
897
|
]));
|
|
876
898
|
}
|
|
877
899
|
const { response: enrichedResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, enrichmentSources, pipelineRequest, response);
|
|
878
|
-
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, enrichedResponse);
|
|
900
|
+
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, { ...enrichedResponse, sourceId });
|
|
901
|
+
if (sourceId === 'BackendWebsocketDataSource' &&
|
|
902
|
+
enrichedResponse.assetsBalance) {
|
|
903
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_markWsBalancesFresh).call(this, enrichedResponse.assetsBalance);
|
|
904
|
+
}
|
|
879
905
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_UPDATE_PIPELINE, {
|
|
880
906
|
source: sourceId,
|
|
881
907
|
duration_ms: performance.now() - updateStart,
|
|
@@ -923,7 +949,7 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
923
949
|
}
|
|
924
950
|
}
|
|
925
951
|
exports.AssetsController = AssetsController;
|
|
926
|
-
_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 = {
|
|
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(), _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 = {
|
|
927
953
|
controller: 'AssetsController',
|
|
928
954
|
}) {
|
|
929
955
|
if (!__classPrivateFieldGet(this, _AssetsController_trace, "f")) {
|
|
@@ -1049,11 +1075,11 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
|
|
|
1049
1075
|
// The base-controller `:stateChange` event is guaranteed to fire
|
|
1050
1076
|
// when init() calls this.update(). #start() is idempotent so
|
|
1051
1077
|
// repeated fires are safe.
|
|
1052
|
-
this.messenger.subscribe('AccountTreeController:
|
|
1078
|
+
this.messenger.subscribe('AccountTreeController:stateChange', () => {
|
|
1053
1079
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleAccountTreeStateChange).call(this);
|
|
1054
1080
|
});
|
|
1055
1081
|
// Subscribe to network enablement changes (only enabledNetworkMap)
|
|
1056
|
-
this.messenger.subscribe('NetworkEnablementController:
|
|
1082
|
+
this.messenger.subscribe('NetworkEnablementController:stateChange', ({ enabledNetworkMap }) => {
|
|
1057
1083
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleEnabledNetworksChanged).call(this, enabledNetworkMap).catch(console.error);
|
|
1058
1084
|
});
|
|
1059
1085
|
// When a network is added or removed from NetworkController, refresh
|
|
@@ -1070,7 +1096,7 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
|
|
|
1070
1096
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_refreshAssetsAfterNetworkChange).call(this);
|
|
1071
1097
|
});
|
|
1072
1098
|
// Client + Keyring lifecycle: only run when UI is open AND keyring is unlocked
|
|
1073
|
-
this.messenger.subscribe('ClientController:
|
|
1099
|
+
this.messenger.subscribe('ClientController:stateChange', (isUiOpen) => {
|
|
1074
1100
|
__classPrivateFieldSet(this, _AssetsController_uiOpen, isUiOpen, "f");
|
|
1075
1101
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateActive).call(this);
|
|
1076
1102
|
}, client_controller_1.clientControllerSelectors.selectIsUiOpen);
|
|
@@ -1087,12 +1113,6 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
|
|
|
1087
1113
|
this.messenger.subscribe('TransactionController:unapprovedTransactionAdded', (transactionMeta) => {
|
|
1088
1114
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_onUnapprovedTransactionAdded).call(this, transactionMeta);
|
|
1089
1115
|
});
|
|
1090
|
-
// Real-time post-tx balances from AccountActivityService (same WS payload as
|
|
1091
|
-
// TokenBalancesController; BackendWebsocketDataSource may not receive the
|
|
1092
|
-
// callback when AccountActivityService owns the server subscription).
|
|
1093
|
-
this.messenger.subscribe('AccountActivityService:balanceUpdated', (event) => {
|
|
1094
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_onAccountActivityBalanceUpdated).call(this, event);
|
|
1095
|
-
});
|
|
1096
1116
|
}, _AssetsController_onUnapprovedTransactionAdded = function _AssetsController_onUnapprovedTransactionAdded(transactionMeta) {
|
|
1097
1117
|
const hexChainId = transactionMeta.chainId;
|
|
1098
1118
|
if (!hexChainId) {
|
|
@@ -1115,26 +1135,6 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
|
|
|
1115
1135
|
error,
|
|
1116
1136
|
});
|
|
1117
1137
|
});
|
|
1118
|
-
}, _AssetsController_onAccountActivityBalanceUpdated = function _AssetsController_onAccountActivityBalanceUpdated({ address, chain, updates, }) {
|
|
1119
|
-
const account = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((a) => a.address.startsWith('0x')
|
|
1120
|
-
? a.address.toLowerCase() === address.toLowerCase()
|
|
1121
|
-
: a.address === address);
|
|
1122
|
-
if (!account) {
|
|
1123
|
-
return;
|
|
1124
|
-
}
|
|
1125
|
-
const chainId = chain;
|
|
1126
|
-
const response = (0, processAccountActivityBalanceUpdates_1.processAccountActivityBalanceUpdates)(updates, account.id, (assetId) => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetType).call(this, assetId));
|
|
1127
|
-
if (!response.assetsBalance) {
|
|
1128
|
-
return;
|
|
1129
|
-
}
|
|
1130
|
-
const request = {
|
|
1131
|
-
accountsWithSupportedChains: [{ account, supportedChains: [chainId] }],
|
|
1132
|
-
chainIds: [chainId],
|
|
1133
|
-
dataTypes: ['balance', 'metadata'],
|
|
1134
|
-
};
|
|
1135
|
-
this.handleAssetsUpdate(response, 'AccountActivityService', request).catch((error) => {
|
|
1136
|
-
log('Failed to apply AccountActivityService balance update', { error });
|
|
1137
|
-
});
|
|
1138
1138
|
}, _AssetsController_updateActive = function _AssetsController_updateActive() {
|
|
1139
1139
|
const shouldRun = __classPrivateFieldGet(this, _AssetsController_uiOpen, "f") && __classPrivateFieldGet(this, _AssetsController_keyringUnlocked, "f");
|
|
1140
1140
|
if (shouldRun) {
|
|
@@ -1344,17 +1344,6 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1344
1344
|
return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_resolveNativeAssetIds).call(this, __classPrivateFieldGet(this, _AssetsController_enabledChains, "f"));
|
|
1345
1345
|
}, _AssetsController_getNativeAssetIdsForAccount = function _AssetsController_getNativeAssetIdsForAccount(account) {
|
|
1346
1346
|
return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_resolveNativeAssetIds).call(this, __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getEnabledChainsForAccount).call(this, account));
|
|
1347
|
-
}, _AssetsController_getSlowPipelineChainIds = function _AssetsController_getSlowPipelineChainIds(chainIds, fastResponse) {
|
|
1348
|
-
const accountsApiChains = new Set(__classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f").getActiveChainsSync());
|
|
1349
|
-
return chainIds.filter((chainId) => {
|
|
1350
|
-
if (fastResponse.errors?.[chainId]) {
|
|
1351
|
-
return true;
|
|
1352
|
-
}
|
|
1353
|
-
if (!accountsApiChains.has(chainId)) {
|
|
1354
|
-
return true;
|
|
1355
|
-
}
|
|
1356
|
-
return false;
|
|
1357
|
-
});
|
|
1358
1347
|
}, _AssetsController_ensureNativeBalancesDefaultZero = function _AssetsController_ensureNativeBalancesDefaultZero() {
|
|
1359
1348
|
const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this);
|
|
1360
1349
|
if (accounts.length === 0) {
|
|
@@ -1372,7 +1361,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1372
1361
|
balances[accountId] = {};
|
|
1373
1362
|
}
|
|
1374
1363
|
for (const nativeAssetId of nativeAssetIds) {
|
|
1375
|
-
if (!
|
|
1364
|
+
if (!(nativeAssetId in balances[accountId])) {
|
|
1376
1365
|
balances[accountId][nativeAssetId] = { amount: '0' };
|
|
1377
1366
|
}
|
|
1378
1367
|
}
|
|
@@ -1422,9 +1411,37 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1422
1411
|
}
|
|
1423
1412
|
}
|
|
1424
1413
|
});
|
|
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
|
+
}
|
|
1425
1441
|
}, _AssetsController_updateState = async function _AssetsController_updateState(response) {
|
|
1426
1442
|
const normalizedResponse = normalizeResponse(response);
|
|
1427
1443
|
const mode = normalizedResponse.updateMode ?? 'merge';
|
|
1444
|
+
const assetsBalanceToApply = normalizedResponse.assetsBalance;
|
|
1428
1445
|
const releaseLock = await __classPrivateFieldGet(this, _AssetsController_controllerMutex, "f").acquire();
|
|
1429
1446
|
try {
|
|
1430
1447
|
const previousState = this.state;
|
|
@@ -1440,43 +1457,29 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1440
1457
|
const balances = state.assetsBalance;
|
|
1441
1458
|
const prices = state.assetsPrice;
|
|
1442
1459
|
if (normalizedResponse.assetsInfo) {
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
// but seed entries that are missing so RPC-only chains (e.g.
|
|
1446
|
-
// Avalanche) can render native balances on first fetch.
|
|
1447
|
-
for (const [key, value] of Object.entries(normalizedResponse.assetsInfo)) {
|
|
1448
|
-
if (metadata[key]) {
|
|
1449
|
-
continue;
|
|
1450
|
-
}
|
|
1451
|
-
metadata[key] = value;
|
|
1460
|
+
for (const [key, value] of Object.entries(normalizedResponse.assetsInfo)) {
|
|
1461
|
+
if (!(0, lodash_1.isEqual)(previousState.assetsInfo[key], value)) {
|
|
1452
1462
|
changedMetadata.push(key);
|
|
1453
1463
|
}
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
for
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
decimals: existing.decimals ?? incoming.decimals,
|
|
1474
|
-
image: existing.image ?? incoming.image,
|
|
1475
|
-
};
|
|
1476
|
-
}
|
|
1477
|
-
else {
|
|
1478
|
-
metadata[key] = value;
|
|
1479
|
-
}
|
|
1464
|
+
const existing = metadata[key];
|
|
1465
|
+
const incoming = value;
|
|
1466
|
+
// When the API returns no symbol or name for this token, it has no
|
|
1467
|
+
// real knowledge of it (e.g. a user-deployed token not indexed by
|
|
1468
|
+
// the API). Preserve richer metadata already in state (e.g. from
|
|
1469
|
+
// pendingMetadata set by addCustomAsset) so that the correct
|
|
1470
|
+
// decimals/symbol/name/image are not overwritten with empty values.
|
|
1471
|
+
if (existing && !incoming.symbol && !incoming.name) {
|
|
1472
|
+
metadata[key] = {
|
|
1473
|
+
...existing,
|
|
1474
|
+
...incoming,
|
|
1475
|
+
symbol: existing.symbol,
|
|
1476
|
+
name: existing.name,
|
|
1477
|
+
decimals: existing.decimals ?? incoming.decimals,
|
|
1478
|
+
image: existing.image ?? incoming.image,
|
|
1479
|
+
};
|
|
1480
|
+
}
|
|
1481
|
+
else {
|
|
1482
|
+
metadata[key] = value;
|
|
1480
1483
|
}
|
|
1481
1484
|
}
|
|
1482
1485
|
}
|
|
@@ -1499,21 +1502,21 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1499
1502
|
}
|
|
1500
1503
|
}
|
|
1501
1504
|
}
|
|
1502
|
-
if (
|
|
1503
|
-
for (const [accountId, accountBalances] of Object.entries(
|
|
1505
|
+
if (assetsBalanceToApply) {
|
|
1506
|
+
for (const [accountId, accountBalances] of Object.entries(assetsBalanceToApply)) {
|
|
1507
|
+
const filteredAccountBalances = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_filterBalancesRespectingWsFreshness).call(this, accountId, accountBalances, normalizedResponse.sourceId);
|
|
1504
1508
|
const previousBalances = previousState.assetsBalance[accountId] ?? {};
|
|
1505
1509
|
const customAssetIds = state.customAssets[accountId] ?? [];
|
|
1506
1510
|
// Full: response is authoritative for the chains it covered;
|
|
1507
1511
|
// balances for chains not in the response are preserved from
|
|
1508
1512
|
// previous state so unsupported chains (e.g. Ink on AccountsAPI)
|
|
1509
1513
|
// are never inadvertently reset to zero.
|
|
1510
|
-
// Merge
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
? { ...previousBalances, ...accountBalances }
|
|
1514
|
+
// Merge: response overlays previous balances.
|
|
1515
|
+
const effective = mode === 'merge'
|
|
1516
|
+
? { ...previousBalances, ...filteredAccountBalances }
|
|
1514
1517
|
: (() => {
|
|
1515
1518
|
// Determine which chain namespaces this response covers.
|
|
1516
|
-
const coveredChains = new Set(Object.keys(
|
|
1519
|
+
const coveredChains = new Set(Object.keys(filteredAccountBalances).map((assetId) => assetId.split('/')[0]));
|
|
1517
1520
|
// Start from previous balances, dropping only entries for
|
|
1518
1521
|
// chains this response is authoritative over.
|
|
1519
1522
|
const next = {};
|
|
@@ -1523,10 +1526,10 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1523
1526
|
}
|
|
1524
1527
|
}
|
|
1525
1528
|
// Apply the response (authoritative for covered chains).
|
|
1526
|
-
Object.assign(next,
|
|
1529
|
+
Object.assign(next, filteredAccountBalances);
|
|
1527
1530
|
// Preserve custom assets that the response omitted.
|
|
1528
1531
|
for (const customId of customAssetIds) {
|
|
1529
|
-
if (!
|
|
1532
|
+
if (!(customId in next)) {
|
|
1530
1533
|
const prev = previousBalances[customId];
|
|
1531
1534
|
next[customId] =
|
|
1532
1535
|
prev ?? { amount: '0' };
|
|
@@ -1534,25 +1537,13 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1534
1537
|
}
|
|
1535
1538
|
return next;
|
|
1536
1539
|
})();
|
|
1537
|
-
// Chains present in this partial response (e.g. Accounts API returned
|
|
1538
|
-
// ERC-20 zeros but omitted native after a max send).
|
|
1539
|
-
const coveredChainsInResponse = new Set(Object.keys(accountBalances).map((assetId) => assetId.split('/')[0]));
|
|
1540
1540
|
// Ensure native tokens have an entry (0 if missing) for chains this account supports
|
|
1541
1541
|
const account = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((a) => a.id === accountId);
|
|
1542
1542
|
const nativeAssetIdsForAccount = account
|
|
1543
1543
|
? __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForAccount).call(this, account)
|
|
1544
1544
|
: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForEnabledChains).call(this);
|
|
1545
1545
|
for (const nativeAssetId of nativeAssetIdsForAccount) {
|
|
1546
|
-
|
|
1547
|
-
if (!Object.prototype.hasOwnProperty.call(effective, nativeAssetId)) {
|
|
1548
|
-
effective[nativeAssetId] = { amount: '0' };
|
|
1549
|
-
}
|
|
1550
|
-
else if (mode === 'update' &&
|
|
1551
|
-
coveredChainsInResponse.has(nativeChain) &&
|
|
1552
|
-
!Object.prototype.hasOwnProperty.call(accountBalances, nativeAssetId)) {
|
|
1553
|
-
// Update-mode overlay keeps previous native when the response
|
|
1554
|
-
// omits it. If the API returned any balance on this chain,
|
|
1555
|
-
// treat omitted native as zero instead of a stale pre-tx amount.
|
|
1546
|
+
if (!(nativeAssetId in effective)) {
|
|
1556
1547
|
effective[nativeAssetId] = { amount: '0' };
|
|
1557
1548
|
}
|
|
1558
1549
|
}
|
|
@@ -1584,21 +1575,10 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1584
1575
|
balances[accountId] = effective;
|
|
1585
1576
|
}
|
|
1586
1577
|
}
|
|
1587
|
-
// Update prices in state
|
|
1588
|
-
// balance-only refreshes do not clobber existing price data.
|
|
1578
|
+
// Update prices in state
|
|
1589
1579
|
if (normalizedResponse.assetsPrice) {
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
if (prices[key]) {
|
|
1593
|
-
continue;
|
|
1594
|
-
}
|
|
1595
|
-
prices[key] = value;
|
|
1596
|
-
}
|
|
1597
|
-
}
|
|
1598
|
-
else {
|
|
1599
|
-
for (const [key, value] of Object.entries(normalizedResponse.assetsPrice)) {
|
|
1600
|
-
prices[key] = value;
|
|
1601
|
-
}
|
|
1580
|
+
for (const [key, value] of Object.entries(normalizedResponse.assetsPrice)) {
|
|
1581
|
+
prices[key] = value;
|
|
1602
1582
|
}
|
|
1603
1583
|
}
|
|
1604
1584
|
});
|
|
@@ -1658,6 +1638,12 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1658
1638
|
});
|
|
1659
1639
|
}
|
|
1660
1640
|
}
|
|
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
|
+
}
|
|
1661
1647
|
}
|
|
1662
1648
|
finally {
|
|
1663
1649
|
releaseLock();
|
|
@@ -1841,13 +1827,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1841
1827
|
const seenIds = new Set();
|
|
1842
1828
|
const accountsForSource = assignedChains
|
|
1843
1829
|
.flatMap((chainId) => chainToAccounts.get(chainId) ?? [])
|
|
1844
|
-
.filter((account) =>
|
|
1845
|
-
if (seenIds.has(account.id)) {
|
|
1846
|
-
return false;
|
|
1847
|
-
}
|
|
1848
|
-
seenIds.add(account.id);
|
|
1849
|
-
return true;
|
|
1850
|
-
});
|
|
1830
|
+
.filter((account) => !seenIds.has(account.id) && (seenIds.add(account.id), true));
|
|
1851
1831
|
if (accountsForSource.length > 0) {
|
|
1852
1832
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeDataSource).call(this, source, accountsForSource, assignedChains);
|
|
1853
1833
|
}
|