@metamask-previews/assets-controller 9.1.0-preview-2226dd478 → 9.1.0-preview-53326764b

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.
Files changed (60) hide show
  1. package/CHANGELOG.md +6 -2
  2. package/dist/AssetsController.cjs +176 -105
  3. package/dist/AssetsController.cjs.map +1 -1
  4. package/dist/AssetsController.d.cts +11 -8
  5. package/dist/AssetsController.d.cts.map +1 -1
  6. package/dist/AssetsController.d.mts +11 -8
  7. package/dist/AssetsController.d.mts.map +1 -1
  8. package/dist/AssetsController.mjs +176 -105
  9. package/dist/AssetsController.mjs.map +1 -1
  10. package/dist/data-sources/AccountsApiDataSource.cjs +10 -0
  11. package/dist/data-sources/AccountsApiDataSource.cjs.map +1 -1
  12. package/dist/data-sources/AccountsApiDataSource.d.cts +8 -0
  13. package/dist/data-sources/AccountsApiDataSource.d.cts.map +1 -1
  14. package/dist/data-sources/AccountsApiDataSource.d.mts +8 -0
  15. package/dist/data-sources/AccountsApiDataSource.d.mts.map +1 -1
  16. package/dist/data-sources/AccountsApiDataSource.mjs +10 -0
  17. package/dist/data-sources/AccountsApiDataSource.mjs.map +1 -1
  18. package/dist/data-sources/BackendWebsocketDataSource.cjs +36 -60
  19. package/dist/data-sources/BackendWebsocketDataSource.cjs.map +1 -1
  20. package/dist/data-sources/BackendWebsocketDataSource.d.cts +8 -0
  21. package/dist/data-sources/BackendWebsocketDataSource.d.cts.map +1 -1
  22. package/dist/data-sources/BackendWebsocketDataSource.d.mts +8 -0
  23. package/dist/data-sources/BackendWebsocketDataSource.d.mts.map +1 -1
  24. package/dist/data-sources/BackendWebsocketDataSource.mjs +36 -57
  25. package/dist/data-sources/BackendWebsocketDataSource.mjs.map +1 -1
  26. package/dist/data-sources/PriceDataSource.cjs +2 -0
  27. package/dist/data-sources/PriceDataSource.cjs.map +1 -1
  28. package/dist/data-sources/PriceDataSource.d.cts.map +1 -1
  29. package/dist/data-sources/PriceDataSource.d.mts.map +1 -1
  30. package/dist/data-sources/PriceDataSource.mjs +2 -0
  31. package/dist/data-sources/PriceDataSource.mjs.map +1 -1
  32. package/dist/data-sources/RpcDataSource.cjs +29 -9
  33. package/dist/data-sources/RpcDataSource.cjs.map +1 -1
  34. package/dist/data-sources/RpcDataSource.d.cts +5 -0
  35. package/dist/data-sources/RpcDataSource.d.cts.map +1 -1
  36. package/dist/data-sources/RpcDataSource.d.mts +5 -0
  37. package/dist/data-sources/RpcDataSource.d.mts.map +1 -1
  38. package/dist/data-sources/RpcDataSource.mjs +29 -9
  39. package/dist/data-sources/RpcDataSource.mjs.map +1 -1
  40. package/dist/middlewares/ParallelMiddleware.cjs +4 -0
  41. package/dist/middlewares/ParallelMiddleware.cjs.map +1 -1
  42. package/dist/middlewares/ParallelMiddleware.d.cts.map +1 -1
  43. package/dist/middlewares/ParallelMiddleware.d.mts.map +1 -1
  44. package/dist/middlewares/ParallelMiddleware.mjs +4 -0
  45. package/dist/middlewares/ParallelMiddleware.mjs.map +1 -1
  46. package/dist/types.cjs.map +1 -1
  47. package/dist/types.d.cts +2 -8
  48. package/dist/types.d.cts.map +1 -1
  49. package/dist/types.d.mts +2 -8
  50. package/dist/types.d.mts.map +1 -1
  51. package/dist/types.mjs.map +1 -1
  52. package/dist/utils/processAccountActivityBalanceUpdates.cjs +54 -0
  53. package/dist/utils/processAccountActivityBalanceUpdates.cjs.map +1 -0
  54. package/dist/utils/processAccountActivityBalanceUpdates.d.cts +13 -0
  55. package/dist/utils/processAccountActivityBalanceUpdates.d.cts.map +1 -0
  56. package/dist/utils/processAccountActivityBalanceUpdates.d.mts +13 -0
  57. package/dist/utils/processAccountActivityBalanceUpdates.d.mts.map +1 -0
  58. package/dist/utils/processAccountActivityBalanceUpdates.mjs +47 -0
  59. package/dist/utils/processAccountActivityBalanceUpdates.mjs.map +1 -0
  60. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -9,13 +9,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ### Changed
11
11
 
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))
12
13
  - Bump `@metamask/transaction-controller` from `^68.1.1` to `^68.2.0` ([#9253](https://github.com/MetaMask/core/pull/9253))
13
14
 
14
15
  ### Fixed
15
16
 
16
- - 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))
17
+ - Fix stale token balances after transactions when switching accounts or when websocket subscriptions reconnect; `AssetsController` now fetches before re-subscribing on account switch and serializes overlapping refresh work ([#9265](https://github.com/MetaMask/core/pull/9265))
17
18
  - `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))
18
- - `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))
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 as a fallback when server `subscriptionId` values do not match ([#9265](https://github.com/MetaMask/core/pull/9265))
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
+ - `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
+ - `AssetsController` refreshes data-source `activeChains`, re-subscribes, and force-fetches balances for the newly selected EVM chain when the user switches networks via `NetworkController:networkDidChange`
19
23
 
20
24
  ## [9.1.0]
21
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_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;
16
+ var _AssetsController_instances, _AssetsController_isEnabled, _AssetsController_isBasicFunctionality, _AssetsController_defaultUpdateInterval, _AssetsController_trace, _AssetsController_captureException, _AssetsController_firstInitFetchReported, _AssetsController_stateSizeReported, _AssetsController_emitTrace, _AssetsController_emitStateSizeTrace, _AssetsController_uiOpen, _AssetsController_keyringUnlocked, _AssetsController_controllerMutex, _AssetsController_accountRefreshMutex, _AssetsController_activeSubscriptions, _AssetsController_enabledChains, _AssetsController_lastKnownAccountIds, _AssetsController_getSelectedAccounts, _AssetsController_backendWebsocketDataSource, _AssetsController_accountsApiDataSource, _AssetsController_snapDataSource, _AssetsController_rpcDataSource, _AssetsController_stakedBalanceDataSource, _AssetsController_allBalanceDataSources_get, _AssetsController_priceDataSource, _AssetsController_detectionMiddleware, _AssetsController_customAssetGraduationMiddleware, _AssetsController_rpcFallbackMiddleware, _AssetsController_tokenDataSource, _AssetsController_unsubscribeBasicFunctionality, _AssetsController_queryApiClient, _AssetsController_onActiveChainsUpdated, _AssetsController_initializeNativeAssetsMap, _AssetsController_initializeState, _AssetsController_extractEnabledChains, _AssetsController_normalizeChainReference, _AssetsController_subscribeToEvents, _AssetsController_onUnapprovedTransactionAdded, _AssetsController_onTransactionConfirmed, _AssetsController_onAccountActivityBalanceUpdated, _AssetsController_updateActive, _AssetsController_handleAccountTreeStateChange, _AssetsController_runAccountTreeRefresh, _AssetsController_registerActionHandlers, _AssetsController_handleActiveChainsUpdate, _AssetsController_executeMiddlewares, _AssetsController_getNativeAssetMap, _AssetsController_isNativeAsset, _AssetsController_getAssetType, _AssetsController_resolveNativeAssetIds, _AssetsController_getNativeAssetIdsForEnabledChains, _AssetsController_getNativeAssetIdsForAccount, _AssetsController_getSlowPipelineChainIds, _AssetsController_ensureNativeBalancesDefaultZero, _AssetsController_ensureDefaultTrackedAssetsSeeded, _AssetsController_updateState, _AssetsController_getAssetsFromState, _AssetsController_shouldHideNativeToken, _AssetsController_tokenStandardToAssetType, _AssetsController_start, _AssetsController_stop, _AssetsController_subscribeAssets, _AssetsController_subscribeAssetsBalance, _AssetsController_subscribeRpcCustomAssetsSupplement, _AssetsController_unsubscribeBySubscriptionKey, _AssetsController_subscribeStakedBalance, _AssetsController_buildChainToAccountsMap, _AssetsController_subscribeDataSource, _AssetsController_unsubscribeDataSource, _AssetsController_buildDataRequest, _AssetsController_getEnabledChainsForAccount, _AssetsController_handleAccountGroupChanged, _AssetsController_handleEnabledNetworksChanged, _AssetsController_handleNetworkAdded, _AssetsController_refreshActiveChainsOnNetworkSwitch, _AssetsController_getSelectedEvmChainIdFromNetworkState, _AssetsController_handleNetworkDidChange, _AssetsController_refreshAssetsAfterNetworkChange;
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.AssetsController = exports.getDefaultAssetsControllerState = void 0;
19
19
  const base_controller_1 = require("@metamask/base-controller");
@@ -40,6 +40,7 @@ const RpcFallbackMiddleware_1 = require("./middlewares/RpcFallbackMiddleware.cjs
40
40
  const utils_2 = require("./utils/index.cjs");
41
41
  const constants_1 = require("./utils/constants.cjs");
42
42
  const customAssetsRpcSupplement_1 = require("./utils/customAssetsRpcSupplement.cjs");
43
+ const processAccountActivityBalanceUpdates_1 = require("./utils/processAccountActivityBalanceUpdates.cjs");
43
44
  const NATIVE_ASSETS_QUERY_KEY = ['nativeAssets'];
44
45
  // ============================================================================
45
46
  // CONTROLLER CONSTANTS
@@ -62,15 +63,6 @@ const MESSENGER_EXPOSED_METHODS = [
62
63
  ];
63
64
  /** Default polling interval hint for data sources (30 seconds) */
64
65
  const DEFAULT_POLLING_INTERVAL_MS = 30000;
65
- /** Sources whose passive polling must not overwrite recent websocket balances. */
66
- const POLLING_BALANCE_SOURCES = new Set([
67
- 'AccountsApiDataSource',
68
- 'RpcDataSource',
69
- 'SnapDataSource',
70
- 'StakedBalanceDataSource',
71
- ]);
72
- /** How long websocket balance updates block stale polling overwrites. */
73
- const WS_BALANCE_FRESHNESS_MS = 120000;
74
66
  // ============================================================================
75
67
  // TRACE NAMES — used in Sentry spans (search these strings in Discover)
76
68
  // ============================================================================
@@ -201,9 +193,6 @@ function normalizeResponse(response) {
201
193
  if (response.updateMode) {
202
194
  normalized.updateMode = response.updateMode;
203
195
  }
204
- if (response.sourceId) {
205
- normalized.sourceId = response.sourceId;
206
- }
207
196
  return normalized;
208
197
  }
209
198
  // ============================================================================
@@ -284,11 +273,6 @@ class AssetsController extends base_controller_1.BaseController {
284
273
  * re-subscriptions when the account set hasn't actually changed.
285
274
  */
286
275
  _AssetsController_lastKnownAccountIds.set(this, new Set());
287
- /**
288
- * Per `accountId:assetId`, timestamp until which websocket balance updates
289
- * should not be overwritten by polling/API fetches.
290
- */
291
- _AssetsController_wsBalanceFreshUntil.set(this, new Map());
292
276
  _AssetsController_backendWebsocketDataSource.set(this, void 0);
293
277
  _AssetsController_accountsApiDataSource.set(this, void 0);
294
278
  _AssetsController_snapDataSource.set(this, void 0);
@@ -437,9 +421,9 @@ class AssetsController extends base_controller_1.BaseController {
437
421
  // creation, RPC is slow on many chains). Results are committed to state
438
422
  // immediately so the UI can display balances without waiting for them.
439
423
  //
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.
424
+ // Fast/slow pipelines use merge so partial API snapshots cannot wipe
425
+ // tokens missing from the response (e.g. USDC when only native balance
426
+ // is returned). Balances present in the response are still refreshed.
443
427
  const fastSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
444
428
  ? [
445
429
  (0, ParallelMiddleware_1.createParallelBalanceMiddleware)([
@@ -459,39 +443,32 @@ class AssetsController extends base_controller_1.BaseController {
459
443
  ]
460
444
  : [__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f")];
461
445
  const { response, durationByDataSource } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, fastSources, request);
462
- // The fast pipeline only contains a subset of data sources (AccountsApi +
463
- // StakedBalance), so it must always merge to avoid wiping Snap/RPC
464
- // balances that the background pipeline hasn't yet replaced.
465
- await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
466
- ...response,
467
- updateMode: 'merge',
468
- sourceId: 'getAssets:forceUpdate',
469
- });
446
+ await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, { ...response, updateMode: 'merge' });
470
447
  // Background pipeline: snap and RPC run in parallel after the fast path
471
448
  // commits to state. Their balances are merged together before detection.
472
449
  // Token + price enrichment matches the pre-split behavior: only when basic
473
450
  // functionality is on (RPC-only mode must not call token/price APIs).
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 }));
451
+ const slowPipelineChainIds = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSlowPipelineChainIds).call(this, chainIds, response);
452
+ if (slowPipelineChainIds.length > 0) {
453
+ const slowSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
454
+ ? [__classPrivateFieldGet(this, _AssetsController_snapDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")]
455
+ : [__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")];
456
+ const slowRequest = { ...request, chainIds: slowPipelineChainIds };
457
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, [
458
+ (0, ParallelMiddleware_1.createParallelBalanceMiddleware)(slowSources),
459
+ __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
460
+ ...(__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
461
+ ? [
462
+ (0, ParallelMiddleware_1.createParallelMiddleware)([
463
+ __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
464
+ __classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
465
+ ]),
466
+ ]
467
+ : []),
468
+ ], slowRequest)
469
+ .then(({ response: slowResponse }) => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, { ...slowResponse, updateMode: 'merge' }))
470
+ .catch((error) => log('Background pipeline failed', { error }));
471
+ }
495
472
  const durationMs = performance.now() - startTime;
496
473
  // Emit trace for every full fetch (Assets Health dashboard)
497
474
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_FULL_FETCH, {
@@ -883,7 +860,8 @@ class AssetsController extends base_controller_1.BaseController {
883
860
  // RPC already fetches custom assets on purpose, and Snap handles non-EVM
884
861
  // chains the rule does not apply to, so skip the middleware for those.
885
862
  const shouldGraduateCustomAssets = sourceId === 'AccountsApiDataSource' ||
886
- sourceId === 'BackendWebsocketDataSource';
863
+ sourceId === 'BackendWebsocketDataSource' ||
864
+ sourceId === 'AccountActivityService';
887
865
  const enrichmentSources = [
888
866
  ...(shouldGraduateCustomAssets
889
867
  ? [__classPrivateFieldGet(this, _AssetsController_customAssetGraduationMiddleware, "f")]
@@ -897,11 +875,7 @@ class AssetsController extends base_controller_1.BaseController {
897
875
  ]));
898
876
  }
899
877
  const { response: enrichedResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, enrichmentSources, pipelineRequest, response);
900
- await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, { ...enrichedResponse, sourceId });
901
- if (sourceId === 'BackendWebsocketDataSource' &&
902
- enrichedResponse.assetsBalance) {
903
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_markWsBalancesFresh).call(this, enrichedResponse.assetsBalance);
904
- }
878
+ await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, enrichedResponse);
905
879
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_UPDATE_PIPELINE, {
906
880
  source: sourceId,
907
881
  duration_ms: performance.now() - updateStart,
@@ -949,7 +923,7 @@ class AssetsController extends base_controller_1.BaseController {
949
923
  }
950
924
  }
951
925
  exports.AssetsController = AssetsController;
952
- _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctionality = new WeakMap(), _AssetsController_defaultUpdateInterval = new WeakMap(), _AssetsController_trace = new WeakMap(), _AssetsController_captureException = new WeakMap(), _AssetsController_firstInitFetchReported = new WeakMap(), _AssetsController_stateSizeReported = new WeakMap(), _AssetsController_uiOpen = new WeakMap(), _AssetsController_keyringUnlocked = new WeakMap(), _AssetsController_controllerMutex = new WeakMap(), _AssetsController_accountRefreshMutex = new WeakMap(), _AssetsController_activeSubscriptions = new WeakMap(), _AssetsController_enabledChains = new WeakMap(), _AssetsController_lastKnownAccountIds = new WeakMap(), _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 = {
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 = {
953
927
  controller: 'AssetsController',
954
928
  }) {
955
929
  if (!__classPrivateFieldGet(this, _AssetsController_trace, "f")) {
@@ -1075,11 +1049,11 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
1075
1049
  // The base-controller `:stateChange` event is guaranteed to fire
1076
1050
  // when init() calls this.update(). #start() is idempotent so
1077
1051
  // repeated fires are safe.
1078
- this.messenger.subscribe('AccountTreeController:stateChange', () => {
1052
+ this.messenger.subscribe('AccountTreeController:stateChanged', () => {
1079
1053
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleAccountTreeStateChange).call(this);
1080
1054
  });
1081
1055
  // Subscribe to network enablement changes (only enabledNetworkMap)
1082
- this.messenger.subscribe('NetworkEnablementController:stateChange', ({ enabledNetworkMap }) => {
1056
+ this.messenger.subscribe('NetworkEnablementController:stateChanged', ({ enabledNetworkMap }) => {
1083
1057
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleEnabledNetworksChanged).call(this, enabledNetworkMap).catch(console.error);
1084
1058
  });
1085
1059
  // When a network is added or removed from NetworkController, refresh
@@ -1095,8 +1069,13 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
1095
1069
  this.messenger.subscribe('NetworkController:networkRemoved', () => {
1096
1070
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_refreshAssetsAfterNetworkChange).call(this);
1097
1071
  });
1072
+ // Selected EVM network switch (network picker). Enablement changes are
1073
+ // handled separately via NetworkEnablementController:stateChanged.
1074
+ this.messenger.subscribe('NetworkController:networkDidChange', (networkState) => {
1075
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleNetworkDidChange).call(this, networkState).catch(console.error);
1076
+ });
1098
1077
  // Client + Keyring lifecycle: only run when UI is open AND keyring is unlocked
1099
- this.messenger.subscribe('ClientController:stateChange', (isUiOpen) => {
1078
+ this.messenger.subscribe('ClientController:stateChanged', (isUiOpen) => {
1100
1079
  __classPrivateFieldSet(this, _AssetsController_uiOpen, isUiOpen, "f");
1101
1080
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateActive).call(this);
1102
1081
  }, client_controller_1.clientControllerSelectors.selectIsUiOpen);
@@ -1113,6 +1092,18 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
1113
1092
  this.messenger.subscribe('TransactionController:unapprovedTransactionAdded', (transactionMeta) => {
1114
1093
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_onUnapprovedTransactionAdded).call(this, transactionMeta);
1115
1094
  });
1095
+ // Post-tx refresh via the full fetch pipeline (Accounts API + RPC fallback).
1096
+ // RpcDataSource also listens for transactionConfirmed, but only refreshes
1097
+ // chains it owns via an active subscription.
1098
+ this.messenger.subscribe('TransactionController:transactionConfirmed', (transactionMeta) => {
1099
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_onTransactionConfirmed).call(this, transactionMeta);
1100
+ });
1101
+ // Real-time post-tx balances from AccountActivityService (same WS payload as
1102
+ // TokenBalancesController; BackendWebsocketDataSource may not receive the
1103
+ // callback when AccountActivityService owns the server subscription).
1104
+ this.messenger.subscribe('AccountActivityService:balanceUpdated', (event) => {
1105
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_onAccountActivityBalanceUpdated).call(this, event);
1106
+ });
1116
1107
  }, _AssetsController_onUnapprovedTransactionAdded = function _AssetsController_onUnapprovedTransactionAdded(transactionMeta) {
1117
1108
  const hexChainId = transactionMeta.chainId;
1118
1109
  if (!hexChainId) {
@@ -1135,6 +1126,46 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
1135
1126
  error,
1136
1127
  });
1137
1128
  });
1129
+ }, _AssetsController_onTransactionConfirmed = function _AssetsController_onTransactionConfirmed(transactionMeta) {
1130
+ const hexChainId = transactionMeta.chainId;
1131
+ if (!hexChainId) {
1132
+ return;
1133
+ }
1134
+ const caipChainId = `eip155:${parseInt(hexChainId, 16)}`;
1135
+ const fromAddress = transactionMeta.txParams.from?.toLowerCase();
1136
+ if (!fromAddress) {
1137
+ return;
1138
+ }
1139
+ const matchedAccount = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((account) => account.address.toLowerCase() === fromAddress);
1140
+ if (!matchedAccount) {
1141
+ return;
1142
+ }
1143
+ this.getAssets([matchedAccount], {
1144
+ chainIds: [caipChainId],
1145
+ forceUpdate: true,
1146
+ }).catch((error) => {
1147
+ log('Failed to refresh assets after transaction confirmed', { error });
1148
+ });
1149
+ }, _AssetsController_onAccountActivityBalanceUpdated = function _AssetsController_onAccountActivityBalanceUpdated({ address, chain, updates, }) {
1150
+ const account = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((a) => a.address.startsWith('0x')
1151
+ ? a.address.toLowerCase() === address.toLowerCase()
1152
+ : a.address === address);
1153
+ if (!account) {
1154
+ return;
1155
+ }
1156
+ const chainId = chain;
1157
+ const response = (0, processAccountActivityBalanceUpdates_1.processAccountActivityBalanceUpdates)(updates, account.id, (assetId) => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetType).call(this, assetId));
1158
+ if (!response.assetsBalance) {
1159
+ return;
1160
+ }
1161
+ const request = {
1162
+ accountsWithSupportedChains: [{ account, supportedChains: [chainId] }],
1163
+ chainIds: [chainId],
1164
+ dataTypes: ['balance', 'metadata'],
1165
+ };
1166
+ this.handleAssetsUpdate(response, 'AccountActivityService', request).catch((error) => {
1167
+ log('Failed to apply AccountActivityService balance update', { error });
1168
+ });
1138
1169
  }, _AssetsController_updateActive = function _AssetsController_updateActive() {
1139
1170
  const shouldRun = __classPrivateFieldGet(this, _AssetsController_uiOpen, "f") && __classPrivateFieldGet(this, _AssetsController_keyringUnlocked, "f");
1140
1171
  if (shouldRun) {
@@ -1344,6 +1375,17 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1344
1375
  return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_resolveNativeAssetIds).call(this, __classPrivateFieldGet(this, _AssetsController_enabledChains, "f"));
1345
1376
  }, _AssetsController_getNativeAssetIdsForAccount = function _AssetsController_getNativeAssetIdsForAccount(account) {
1346
1377
  return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_resolveNativeAssetIds).call(this, __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getEnabledChainsForAccount).call(this, account));
1378
+ }, _AssetsController_getSlowPipelineChainIds = function _AssetsController_getSlowPipelineChainIds(chainIds, fastResponse) {
1379
+ const accountsApiChains = new Set(__classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f").getActiveChainsSync());
1380
+ return chainIds.filter((chainId) => {
1381
+ if (fastResponse.errors?.[chainId]) {
1382
+ return true;
1383
+ }
1384
+ if (!accountsApiChains.has(chainId)) {
1385
+ return true;
1386
+ }
1387
+ return false;
1388
+ });
1347
1389
  }, _AssetsController_ensureNativeBalancesDefaultZero = function _AssetsController_ensureNativeBalancesDefaultZero() {
1348
1390
  const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this);
1349
1391
  if (accounts.length === 0) {
@@ -1361,7 +1403,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1361
1403
  balances[accountId] = {};
1362
1404
  }
1363
1405
  for (const nativeAssetId of nativeAssetIds) {
1364
- if (!(nativeAssetId in balances[accountId])) {
1406
+ if (!Object.prototype.hasOwnProperty.call(balances[accountId], nativeAssetId)) {
1365
1407
  balances[accountId][nativeAssetId] = { amount: '0' };
1366
1408
  }
1367
1409
  }
@@ -1411,37 +1453,9 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1411
1453
  }
1412
1454
  }
1413
1455
  });
1414
- }, _AssetsController_filterBalancesRespectingWsFreshness = function _AssetsController_filterBalancesRespectingWsFreshness(accountId, accountBalances, sourceId) {
1415
- if (!sourceId || !POLLING_BALANCE_SOURCES.has(sourceId)) {
1416
- return accountBalances;
1417
- }
1418
- const now = Date.now();
1419
- const filtered = {};
1420
- for (const [assetId, balance] of Object.entries(accountBalances)) {
1421
- const freshUntil = __classPrivateFieldGet(this, _AssetsController_wsBalanceFreshUntil, "f").get(`${accountId}:${assetId}`);
1422
- if (freshUntil !== undefined && now < freshUntil) {
1423
- continue;
1424
- }
1425
- filtered[assetId] = balance;
1426
- }
1427
- return filtered;
1428
- }, _AssetsController_markWsBalancesFresh = function _AssetsController_markWsBalancesFresh(assetsBalance) {
1429
- const freshUntil = Date.now() + WS_BALANCE_FRESHNESS_MS;
1430
- for (const [accountId, balances] of Object.entries(assetsBalance)) {
1431
- for (const assetId of Object.keys(balances)) {
1432
- __classPrivateFieldGet(this, _AssetsController_wsBalanceFreshUntil, "f").set(`${accountId}:${assetId}`, freshUntil);
1433
- }
1434
- }
1435
- }, _AssetsController_clearWsBalanceFreshness = function _AssetsController_clearWsBalanceFreshness(assetsBalance) {
1436
- for (const [accountId, balances] of Object.entries(assetsBalance)) {
1437
- for (const assetId of Object.keys(balances)) {
1438
- __classPrivateFieldGet(this, _AssetsController_wsBalanceFreshUntil, "f").delete(`${accountId}:${assetId}`);
1439
- }
1440
- }
1441
1456
  }, _AssetsController_updateState = async function _AssetsController_updateState(response) {
1442
1457
  const normalizedResponse = normalizeResponse(response);
1443
1458
  const mode = normalizedResponse.updateMode ?? 'merge';
1444
- const assetsBalanceToApply = normalizedResponse.assetsBalance;
1445
1459
  const releaseLock = await __classPrivateFieldGet(this, _AssetsController_controllerMutex, "f").acquire();
1446
1460
  try {
1447
1461
  const previousState = this.state;
@@ -1502,9 +1516,8 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1502
1516
  }
1503
1517
  }
1504
1518
  }
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);
1519
+ if (normalizedResponse.assetsBalance) {
1520
+ for (const [accountId, accountBalances] of Object.entries(normalizedResponse.assetsBalance)) {
1508
1521
  const previousBalances = previousState.assetsBalance[accountId] ?? {};
1509
1522
  const customAssetIds = state.customAssets[accountId] ?? [];
1510
1523
  // Full: response is authoritative for the chains it covered;
@@ -1513,10 +1526,10 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1513
1526
  // are never inadvertently reset to zero.
1514
1527
  // Merge: response overlays previous balances.
1515
1528
  const effective = mode === 'merge'
1516
- ? { ...previousBalances, ...filteredAccountBalances }
1529
+ ? { ...previousBalances, ...accountBalances }
1517
1530
  : (() => {
1518
1531
  // Determine which chain namespaces this response covers.
1519
- const coveredChains = new Set(Object.keys(filteredAccountBalances).map((assetId) => assetId.split('/')[0]));
1532
+ const coveredChains = new Set(Object.keys(accountBalances).map((assetId) => assetId.split('/')[0]));
1520
1533
  // Start from previous balances, dropping only entries for
1521
1534
  // chains this response is authoritative over.
1522
1535
  const next = {};
@@ -1526,10 +1539,10 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1526
1539
  }
1527
1540
  }
1528
1541
  // Apply the response (authoritative for covered chains).
1529
- Object.assign(next, filteredAccountBalances);
1542
+ Object.assign(next, accountBalances);
1530
1543
  // Preserve custom assets that the response omitted.
1531
1544
  for (const customId of customAssetIds) {
1532
- if (!(customId in next)) {
1545
+ if (!Object.prototype.hasOwnProperty.call(next, customId)) {
1533
1546
  const prev = previousBalances[customId];
1534
1547
  next[customId] =
1535
1548
  prev ?? { amount: '0' };
@@ -1543,7 +1556,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1543
1556
  ? __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForAccount).call(this, account)
1544
1557
  : __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForEnabledChains).call(this);
1545
1558
  for (const nativeAssetId of nativeAssetIdsForAccount) {
1546
- if (!(nativeAssetId in effective)) {
1559
+ if (!Object.prototype.hasOwnProperty.call(effective, nativeAssetId)) {
1547
1560
  effective[nativeAssetId] = { amount: '0' };
1548
1561
  }
1549
1562
  }
@@ -1575,7 +1588,6 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1575
1588
  balances[accountId] = effective;
1576
1589
  }
1577
1590
  }
1578
- // Update prices in state
1579
1591
  if (normalizedResponse.assetsPrice) {
1580
1592
  for (const [key, value] of Object.entries(normalizedResponse.assetsPrice)) {
1581
1593
  prices[key] = value;
@@ -1638,12 +1650,6 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1638
1650
  });
1639
1651
  }
1640
1652
  }
1641
- // Authoritative fetch on account switch — drop WS freshness locks so API
1642
- // balances (e.g. receiver +1 USDC) replace stale values from a prior send.
1643
- if (normalizedResponse.sourceId === 'getAssets:forceUpdate' &&
1644
- assetsBalanceToApply) {
1645
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_clearWsBalanceFreshness).call(this, assetsBalanceToApply);
1646
- }
1647
1653
  }
1648
1654
  finally {
1649
1655
  releaseLock();
@@ -1827,7 +1833,13 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1827
1833
  const seenIds = new Set();
1828
1834
  const accountsForSource = assignedChains
1829
1835
  .flatMap((chainId) => chainToAccounts.get(chainId) ?? [])
1830
- .filter((account) => !seenIds.has(account.id) && (seenIds.add(account.id), true));
1836
+ .filter((account) => {
1837
+ if (seenIds.has(account.id)) {
1838
+ return false;
1839
+ }
1840
+ seenIds.add(account.id);
1841
+ return true;
1842
+ });
1831
1843
  if (accountsForSource.length > 0) {
1832
1844
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeDataSource).call(this, source, accountsForSource, assignedChains);
1833
1845
  }
@@ -2089,6 +2101,65 @@ async function _AssetsController_handleAccountGroupChanged() {
2089
2101
  caipChainId,
2090
2102
  });
2091
2103
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureDefaultTrackedAssetsSeeded).call(this, [caipChainId]);
2104
+ }, _AssetsController_refreshActiveChainsOnNetworkSwitch =
2105
+ /**
2106
+ * Refresh data-source `activeChains` after an EVM network switch so API/WS/Rpc
2107
+ * chain claiming is not stuck on an empty or stale init-time list.
2108
+ */
2109
+ async function _AssetsController_refreshActiveChainsOnNetworkSwitch() {
2110
+ await Promise.all([
2111
+ __classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f").refreshActiveChains(),
2112
+ __classPrivateFieldGet(this, _AssetsController_backendWebsocketDataSource, "f").refreshActiveChains(),
2113
+ ]);
2114
+ __classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f").refreshActiveChainsFromNetworkState();
2115
+ }, _AssetsController_getSelectedEvmChainIdFromNetworkState = function _AssetsController_getSelectedEvmChainIdFromNetworkState(networkState) {
2116
+ try {
2117
+ const networkClient = this.messenger.call('NetworkController:getNetworkClientById', networkState.selectedNetworkClientId);
2118
+ const hexChainId = networkClient.configuration?.chainId;
2119
+ if (!hexChainId) {
2120
+ return undefined;
2121
+ }
2122
+ return `eip155:${parseInt(hexChainId, 16)}`;
2123
+ }
2124
+ catch {
2125
+ return undefined;
2126
+ }
2127
+ }, _AssetsController_handleNetworkDidChange =
2128
+ /**
2129
+ * Refresh subscriptions and fetch balances when the user switches the
2130
+ * selected EVM network in the UI (`NetworkController:networkDidChange`).
2131
+ *
2132
+ * @param networkState - NetworkController state after the switch.
2133
+ */
2134
+ async function _AssetsController_handleNetworkDidChange(networkState) {
2135
+ if (!__classPrivateFieldGet(this, _AssetsController_uiOpen, "f") || !__classPrivateFieldGet(this, _AssetsController_keyringUnlocked, "f") || !__classPrivateFieldGet(this, _AssetsController_isEnabled, "f").call(this)) {
2136
+ return;
2137
+ }
2138
+ const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this);
2139
+ if (accounts.length === 0) {
2140
+ return;
2141
+ }
2142
+ const selectedChainId = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedEvmChainIdFromNetworkState).call(this, networkState);
2143
+ if (!selectedChainId) {
2144
+ return;
2145
+ }
2146
+ log('Selected EVM network switched', {
2147
+ selectedNetworkClientId: networkState.selectedNetworkClientId,
2148
+ selectedChainId,
2149
+ });
2150
+ const releaseLock = await __classPrivateFieldGet(this, _AssetsController_accountRefreshMutex, "f").acquire();
2151
+ try {
2152
+ await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_refreshActiveChainsOnNetworkSwitch).call(this);
2153
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
2154
+ await this.getAssets(accounts, {
2155
+ chainIds: [selectedChainId],
2156
+ forceUpdate: true,
2157
+ });
2158
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
2159
+ }
2160
+ finally {
2161
+ releaseLock();
2162
+ }
2092
2163
  }, _AssetsController_refreshAssetsAfterNetworkChange = function _AssetsController_refreshAssetsAfterNetworkChange() {
2093
2164
  this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this), {
2094
2165
  forceUpdate: true,