@metamask-previews/assets-controller 14.0.3-preview-fe4b3be11 → 14.0.3-preview-8bfa290fb

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 (74) hide show
  1. package/CHANGELOG.md +6 -4
  2. package/dist/AssetsController.cjs +273 -592
  3. package/dist/AssetsController.cjs.map +1 -1
  4. package/dist/AssetsController.d.cts +10 -7
  5. package/dist/AssetsController.d.cts.map +1 -1
  6. package/dist/AssetsController.d.mts +10 -7
  7. package/dist/AssetsController.d.mts.map +1 -1
  8. package/dist/AssetsController.mjs +273 -592
  9. package/dist/AssetsController.mjs.map +1 -1
  10. package/dist/data-sources/AbstractDataSource.cjs +0 -23
  11. package/dist/data-sources/AbstractDataSource.cjs.map +1 -1
  12. package/dist/data-sources/AbstractDataSource.d.cts +1 -13
  13. package/dist/data-sources/AbstractDataSource.d.cts.map +1 -1
  14. package/dist/data-sources/AbstractDataSource.d.mts +1 -13
  15. package/dist/data-sources/AbstractDataSource.d.mts.map +1 -1
  16. package/dist/data-sources/AbstractDataSource.mjs +0 -23
  17. package/dist/data-sources/AbstractDataSource.mjs.map +1 -1
  18. package/dist/data-sources/AccountActivityDataSource.cjs +0 -2
  19. package/dist/data-sources/AccountActivityDataSource.cjs.map +1 -1
  20. package/dist/data-sources/AccountActivityDataSource.d.cts.map +1 -1
  21. package/dist/data-sources/AccountActivityDataSource.d.mts.map +1 -1
  22. package/dist/data-sources/AccountActivityDataSource.mjs +0 -2
  23. package/dist/data-sources/AccountActivityDataSource.mjs.map +1 -1
  24. package/dist/data-sources/AccountsApiDataSource.cjs +31 -144
  25. package/dist/data-sources/AccountsApiDataSource.cjs.map +1 -1
  26. package/dist/data-sources/AccountsApiDataSource.d.cts +2 -18
  27. package/dist/data-sources/AccountsApiDataSource.d.cts.map +1 -1
  28. package/dist/data-sources/AccountsApiDataSource.d.mts +2 -18
  29. package/dist/data-sources/AccountsApiDataSource.d.mts.map +1 -1
  30. package/dist/data-sources/AccountsApiDataSource.mjs +32 -145
  31. package/dist/data-sources/AccountsApiDataSource.mjs.map +1 -1
  32. package/dist/data-sources/RpcDataSource.cjs +24 -163
  33. package/dist/data-sources/RpcDataSource.cjs.map +1 -1
  34. package/dist/data-sources/RpcDataSource.d.cts +0 -17
  35. package/dist/data-sources/RpcDataSource.d.cts.map +1 -1
  36. package/dist/data-sources/RpcDataSource.d.mts +0 -17
  37. package/dist/data-sources/RpcDataSource.d.mts.map +1 -1
  38. package/dist/data-sources/RpcDataSource.mjs +25 -164
  39. package/dist/data-sources/RpcDataSource.mjs.map +1 -1
  40. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.cjs +12 -21
  41. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.cjs.map +1 -1
  42. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.cts +2 -7
  43. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.cts.map +1 -1
  44. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.mts +2 -7
  45. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.mts.map +1 -1
  46. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.mjs +12 -21
  47. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.mjs.map +1 -1
  48. package/dist/data-sources/evm-rpc-services/types/state.cjs.map +1 -1
  49. package/dist/data-sources/evm-rpc-services/types/state.d.cts +2 -3
  50. package/dist/data-sources/evm-rpc-services/types/state.d.cts.map +1 -1
  51. package/dist/data-sources/evm-rpc-services/types/state.d.mts +2 -3
  52. package/dist/data-sources/evm-rpc-services/types/state.d.mts.map +1 -1
  53. package/dist/data-sources/evm-rpc-services/types/state.mjs.map +1 -1
  54. package/dist/middlewares/ParallelMiddleware.cjs +0 -9
  55. package/dist/middlewares/ParallelMiddleware.cjs.map +1 -1
  56. package/dist/middlewares/ParallelMiddleware.d.cts.map +1 -1
  57. package/dist/middlewares/ParallelMiddleware.d.mts.map +1 -1
  58. package/dist/middlewares/ParallelMiddleware.mjs +0 -9
  59. package/dist/middlewares/ParallelMiddleware.mjs.map +1 -1
  60. package/dist/middlewares/RpcFallbackMiddleware.cjs +128 -158
  61. package/dist/middlewares/RpcFallbackMiddleware.cjs.map +1 -1
  62. package/dist/middlewares/RpcFallbackMiddleware.d.cts +14 -10
  63. package/dist/middlewares/RpcFallbackMiddleware.d.cts.map +1 -1
  64. package/dist/middlewares/RpcFallbackMiddleware.d.mts +14 -10
  65. package/dist/middlewares/RpcFallbackMiddleware.d.mts.map +1 -1
  66. package/dist/middlewares/RpcFallbackMiddleware.mjs +128 -158
  67. package/dist/middlewares/RpcFallbackMiddleware.mjs.map +1 -1
  68. package/dist/types.cjs.map +1 -1
  69. package/dist/types.d.cts +26 -28
  70. package/dist/types.d.cts.map +1 -1
  71. package/dist/types.d.mts +26 -28
  72. package/dist/types.d.mts.map +1 -1
  73. package/dist/types.mjs.map +1 -1
  74. package/package.json +2 -2
@@ -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_emitStateSizeTrace, _AssetsController_controllerMutex, _AssetsController_accountRefreshMutex, _AssetsController_activeSubscriptions, _AssetsController_enabledChains, _AssetsController_getSelectedAccounts, _AssetsController_isAccountTreeInitialized, _AssetsController_isUiOpen, _AssetsController_isKeyringUnlocked, _AssetsController_accountActivityDataSource, _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_refreshAssetsForTransaction, _AssetsController_runSpamCleanup, _AssetsController_updateActive, _AssetsController_runStartupRefresh, _AssetsController_registerActionHandlers, _AssetsController_handleActiveChainsUpdate, _AssetsController_executeMiddlewares, _AssetsController_buildForceUpdateRequestV5, _AssetsController_buildForceUpdateRequestV6, _AssetsController_forceUpdateAssetsV5, _AssetsController_forceUpdateAssetsV6, _AssetsController_runFastFetchV5, _AssetsController_runFastFetchV6, _AssetsController_runBackgroundFetch, _AssetsController_emitFastFetchTraces, _AssetsController_assertNonEmptyAccountId, _AssetsController_normalizeAssetIdOrThrow, _AssetsController_getHiddenAssetIds, _AssetsController_isBalanceV6Enabled, _AssetsController_fetchMissingPricesWithoutCache, _AssetsController_getNativeAssetMap, _AssetsController_isNativeAsset, _AssetsController_getAssetType, _AssetsController_resolveNativeAssetIds, _AssetsController_getNativeAssetIdsForEnabledChains, _AssetsController_getNativeAssetIdsForAccount, _AssetsController_getSlowPipelineChainIds, _AssetsController_ensureNativeBalancesDefaultZero, _AssetsController_ensureDefaultTrackedAssetsSeeded, _AssetsController_updateState, _AssetsController_getAssetsFromState, _AssetsController_getAssetFromState, _AssetsController_shouldHideNativeToken, _AssetsController_tokenStandardToAssetType, _AssetsController_start, _AssetsController_stop, _AssetsController_subscribeAssets, _AssetsController_subscribeAssetsBalance, _AssetsController_subscribeAssetsBalanceV5, _AssetsController_subscribeAssetsBalanceV6, _AssetsController_subscribeRpcCustomAssetsSupplement, _AssetsController_unsubscribeBySubscriptionKey, _AssetsController_subscribeStakedBalance, _AssetsController_buildChainToAccountsMap, _AssetsController_subscribeDataSource, _AssetsController_unsubscribeDataSource, _AssetsController_buildDataRequest, _AssetsController_getEnabledChainsForAccount, _AssetsController_handleAccountGroupChanged, _AssetsController_handleEnabledNetworksChanged, _AssetsController_handleNetworkAdded, _AssetsController_refreshActiveChainsOnNetworkSwitch, _AssetsController_getSelectedEvmChainIdFromNetworkState, _AssetsController_handleNetworkDidChange, _AssetsController_refreshAssetsAfterNetworkChange, _AssetsController_refreshAssetsAfterNetworkAdded, _AssetsController_handleAssetsUpdateV5, _AssetsController_handleAssetsUpdateV6, _AssetsController_getUpdatePipelineRequest, _AssetsController_getUpdateTraceData, _AssetsController_emitUpdateTrace;
12
+ var _AssetsController_instances, _AssetsController_isEnabled, _AssetsController_isBasicFunctionality, _AssetsController_defaultUpdateInterval, _AssetsController_trace, _AssetsController_captureException, _AssetsController_firstInitFetchReported, _AssetsController_stateSizeReported, _AssetsController_emitStateSizeTrace, _AssetsController_controllerMutex, _AssetsController_accountRefreshMutex, _AssetsController_activeSubscriptions, _AssetsController_enabledChains, _AssetsController_getSelectedAccounts, _AssetsController_isAccountTreeInitialized, _AssetsController_isUiOpen, _AssetsController_isKeyringUnlocked, _AssetsController_accountActivityDataSource, _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_refreshAssetsForTransaction, _AssetsController_runSpamCleanup, _AssetsController_updateActive, _AssetsController_runStartupRefresh, _AssetsController_registerActionHandlers, _AssetsController_handleActiveChainsUpdate, _AssetsController_executeMiddlewares, _AssetsController_assertNonEmptyAccountId, _AssetsController_normalizeAssetIdOrThrow, _AssetsController_fetchMissingPricesWithoutCache, _AssetsController_getNativeAssetMap, _AssetsController_isNativeAsset, _AssetsController_getAssetType, _AssetsController_resolveNativeAssetIds, _AssetsController_getNativeAssetIdsForEnabledChains, _AssetsController_getNativeAssetIdsForAccount, _AssetsController_getSlowPipelineChainIds, _AssetsController_ensureNativeBalancesDefaultZero, _AssetsController_ensureDefaultTrackedAssetsSeeded, _AssetsController_updateState, _AssetsController_getAssetsFromState, _AssetsController_getAssetFromState, _AssetsController_shouldHideNativeToken, _AssetsController_tokenStandardToAssetType, _AssetsController_start, _AssetsController_stop, _AssetsController_subscribeAssets, _AssetsController_subscribeAssetsBalance, _AssetsController_subscribeRpcCustomAssetsSupplement, _AssetsController_unsubscribeBySubscriptionKey, _AssetsController_subscribeStakedBalance, _AssetsController_buildChainToAccountsMap, _AssetsController_subscribeDataSource, _AssetsController_unsubscribeDataSource, _AssetsController_buildDataRequest, _AssetsController_getEnabledChainsForAccount, _AssetsController_handleAccountGroupChanged, _AssetsController_handleEnabledNetworksChanged, _AssetsController_handleNetworkAdded, _AssetsController_refreshActiveChainsOnNetworkSwitch, _AssetsController_getSelectedEvmChainIdFromNetworkState, _AssetsController_handleNetworkDidChange, _AssetsController_refreshAssetsAfterNetworkChange, _AssetsController_refreshAssetsAfterNetworkAdded;
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";
@@ -202,10 +202,6 @@ function normalizeResponse(response) {
202
202
  if (response.replaceCoveredChainBalances) {
203
203
  normalized.replaceCoveredChainBalances = true;
204
204
  }
205
- if (response.unprocessedCustomAssets &&
206
- response.unprocessedCustomAssets.length > 0) {
207
- normalized.unprocessedCustomAssets = response.unprocessedCustomAssets.map((assetId) => normalizeAssetId(assetId));
208
- }
209
205
  return normalized;
210
206
  }
211
207
  /**
@@ -213,13 +209,12 @@ function normalizeResponse(response) {
213
209
  *
214
210
  * @param previousBalances - Balances already in state for this account.
215
211
  * @param accountBalances - Balances from the incoming response.
216
- * @param customAssetIds - Custom assets to preserve when replacing covered chains
217
- * on the Accounts API v5 path (`replaceCoveredChainBalances`).
218
- * @param replaceCoveredChains - When true (v5 force refresh), drop prior balances
219
- * on chains present in the response before applying it, then restore custom assets.
212
+ * @param customAssetIds - Custom assets to preserve when replacing covered chains.
213
+ * @param replaceCoveredChains - When true, drop prior balances on chains present
214
+ * in the response before applying it (authoritative chain slice).
220
215
  * @returns The merged balance map for the account.
221
216
  */
222
- function mergeAccountBalancesV5(previousBalances, accountBalances, customAssetIds = [], replaceCoveredChains = false) {
217
+ function mergeAccountBalances(previousBalances, accountBalances, customAssetIds, replaceCoveredChains) {
223
218
  if (!replaceCoveredChains) {
224
219
  return { ...previousBalances, ...accountBalances };
225
220
  }
@@ -233,8 +228,8 @@ function mergeAccountBalancesV5(previousBalances, accountBalances, customAssetId
233
228
  Object.assign(next, accountBalances);
234
229
  for (const customId of customAssetIds) {
235
230
  if (!Object.prototype.hasOwnProperty.call(next, customId)) {
236
- const previous = previousBalances[customId];
237
- next[customId] = previous ?? { amount: '0' };
231
+ const prev = previousBalances[customId];
232
+ next[customId] = prev ?? { amount: '0' };
238
233
  }
239
234
  }
240
235
  // Staked vault balances are owned by StakedBalanceDataSource. When an
@@ -248,38 +243,6 @@ function mergeAccountBalancesV5(previousBalances, accountBalances, customAssetId
248
243
  }
249
244
  return next;
250
245
  }
251
- /**
252
- * Apply an Accounts API v6 authoritative chain snapshot.
253
- *
254
- * @param previousBalances - Balances already in state for this account.
255
- * @param accountBalances - Balances from the incoming response.
256
- * @param unprocessedCustomAssets - Pins that v6 and RPC could not resolve.
257
- * @returns The merged balance map for the account.
258
- */
259
- function mergeAccountBalancesV6(previousBalances, accountBalances, unprocessedCustomAssets = []) {
260
- const coveredChains = new Set(Object.keys(accountBalances).map((assetId) => assetId.split('/')[0]));
261
- const next = {};
262
- for (const [assetId, balance] of Object.entries(previousBalances)) {
263
- if (!coveredChains.has(assetId.split('/')[0])) {
264
- next[assetId] = balance;
265
- }
266
- }
267
- Object.assign(next, accountBalances);
268
- const unprocessedSet = new Set(unprocessedCustomAssets.map((assetId) => normalizeAssetId(assetId)));
269
- for (const [assetId, balance] of Object.entries(previousBalances)) {
270
- if (unprocessedSet.has(normalizeAssetId(assetId)) &&
271
- !Object.prototype.hasOwnProperty.call(next, assetId)) {
272
- next[assetId] = balance;
273
- }
274
- }
275
- for (const [assetId, balance] of Object.entries(previousBalances)) {
276
- if (isStakingContractAssetId(assetId) &&
277
- !Object.prototype.hasOwnProperty.call(next, assetId)) {
278
- next[assetId] = balance;
279
- }
280
- }
281
- return next;
282
- }
283
246
  // ============================================================================
284
247
  // CONTROLLER IMPLEMENTATION
285
248
  // ============================================================================
@@ -400,7 +363,6 @@ export class AssetsController extends BaseController {
400
363
  queryApiClient,
401
364
  onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
402
365
  ...accountsApiDataSourceConfig,
403
- isBalanceV6Enabled: () => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_isBalanceV6Enabled).call(this),
404
366
  }), "f");
405
367
  __classPrivateFieldSet(this, _AssetsController_snapDataSource, new SnapDataSource({
406
368
  messenger: this.messenger,
@@ -420,7 +382,6 @@ export class AssetsController extends BaseController {
420
382
  ...rpcConfig,
421
383
  isOnboarded: rpcConfig.isOnboarded ?? isOnboarded,
422
384
  getAssetType: (assetId) => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetType).call(this, assetId),
423
- isBalanceV6Enabled: () => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_isBalanceV6Enabled).call(this),
424
385
  }), "f");
425
386
  __classPrivateFieldSet(this, _AssetsController_stakedBalanceDataSource, new StakedBalanceDataSource({
426
387
  messenger: this.messenger,
@@ -453,7 +414,6 @@ export class AssetsController extends BaseController {
453
414
  }), "f");
454
415
  __classPrivateFieldSet(this, _AssetsController_rpcFallbackMiddleware, new RpcFallbackMiddleware({
455
416
  rpcDataSource: __classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f"),
456
- isBalanceV6Enabled: () => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_isBalanceV6Enabled).call(this),
457
417
  }), "f");
458
418
  log('Initializing AssetsController', {
459
419
  defaultUpdateInterval: __classPrivateFieldGet(this, _AssetsController_defaultUpdateInterval, "f"),
@@ -490,34 +450,147 @@ export class AssetsController extends BaseController {
490
450
  if (accounts.length === 0 || chainIds.length === 0) {
491
451
  return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetsFromState).call(this, accounts, chainIds, assetTypes);
492
452
  }
453
+ // Collect custom assets for all requested accounts
454
+ const customAssets = [];
455
+ for (const account of accounts) {
456
+ const accountCustomAssets = this.getCustomAssets(account.id);
457
+ customAssets.push(...accountCustomAssets);
458
+ }
493
459
  if (options?.forceUpdate) {
460
+ // Pipeline spans only on unlock/first-init fetch; later forceUpdates pass
461
+ // `undefined` so `emitTrace` / `withTrace` no-op without call-site if/else.
494
462
  const pipelineTrace = __classPrivateFieldGet(this, _AssetsController_firstInitFetchReported, "f")
495
463
  ? undefined
496
464
  : __classPrivateFieldGet(this, _AssetsController_trace, "f");
497
- const requestOptions = {
465
+ const request = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildDataRequest).call(this, accounts, chainIds, {
498
466
  assetTypes,
499
467
  dataTypes,
468
+ customAssets: customAssets.length > 0 ? customAssets : undefined,
500
469
  forceUpdate: true,
470
+ bypassServerCache: options?.bypassServerCache,
501
471
  assetsForPriceUpdate: options?.assetsForPriceUpdate,
502
- };
503
- if (__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_isBalanceV6Enabled).call(this)) {
504
- await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_forceUpdateAssetsV6).call(this, {
505
- accounts,
506
- chainIds,
507
- request: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildForceUpdateRequestV6).call(this, accounts, chainIds, {
508
- ...requestOptions,
509
- customAssetsOverride: options?.customAssets,
510
- }),
511
- pipelineTrace,
512
- });
513
- }
514
- else {
515
- await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_forceUpdateAssetsV5).call(this, {
516
- accounts,
517
- chainIds,
518
- request: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildForceUpdateRequestV5).call(this, accounts, chainIds, requestOptions),
519
- pipelineTrace,
520
- });
472
+ });
473
+ // Fast pipeline: accountsApi + stakedBalance → detection → token + price.
474
+ // Snap and RPC are excluded here due to their latency (snap triggers account
475
+ // creation, RPC is slow on many chains). Results are committed to state
476
+ // immediately so the UI can display balances without waiting for them.
477
+ //
478
+ // Fast/slow pipelines use merge so partial API snapshots cannot wipe
479
+ // tokens missing from the response (e.g. USDC when only native balance
480
+ // is returned). Balances present in the response are still refreshed.
481
+ const fastSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
482
+ ? [
483
+ createParallelBalanceMiddleware([
484
+ __classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f"),
485
+ __classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"),
486
+ ]),
487
+ // Graduation must run BEFORE the RPC fallback so it only sees
488
+ // AccountsApi/Websocket balances. RPC intentionally carries
489
+ // custom assets and must never trigger graduation.
490
+ __classPrivateFieldGet(this, _AssetsController_customAssetGraduationMiddleware, "f"),
491
+ __classPrivateFieldGet(this, _AssetsController_rpcFallbackMiddleware, "f"),
492
+ __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
493
+ createParallelMiddleware([
494
+ __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
495
+ __classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
496
+ ]),
497
+ ]
498
+ : [__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f")];
499
+ const { response } = await withTrace({
500
+ name: TRACE_FETCH_PIPELINE,
501
+ trace: pipelineTrace,
502
+ data: {
503
+ chain_count: chainIds.length,
504
+ account_count: accounts.length,
505
+ basic_functionality: __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this),
506
+ },
507
+ fn: async (parentContext) => {
508
+ const startTime = performance.now();
509
+ const result = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, {
510
+ sources: fastSources,
511
+ request,
512
+ parentContext,
513
+ trace: pipelineTrace,
514
+ });
515
+ await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
516
+ ...result.response,
517
+ updateMode: 'merge',
518
+ replaceCoveredChainBalances: true,
519
+ });
520
+ const durationMs = performance.now() - startTime;
521
+ // Summary fields for Assets Health (nested under the parent span).
522
+ emitTrace({
523
+ name: TRACE_FULL_FETCH,
524
+ trace: pipelineTrace,
525
+ data: {
526
+ duration_ms: durationMs,
527
+ chain_count: chainIds.length,
528
+ account_count: accounts.length,
529
+ basic_functionality: __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this),
530
+ asset_count: result.response.assetsBalance
531
+ ? Object.values(result.response.assetsBalance).reduce((sum, acct) => sum + Object.keys(acct).length, 0)
532
+ : 0,
533
+ price_count: result.response.assetsPrice
534
+ ? Object.keys(result.response.assetsPrice).length
535
+ : 0,
536
+ ...result.durationByDataSource,
537
+ },
538
+ parentContext,
539
+ });
540
+ emitTrace({
541
+ name: TRACE_FIRST_INIT_FETCH,
542
+ trace: pipelineTrace,
543
+ data: {
544
+ duration_ms: durationMs,
545
+ chain_ids: JSON.stringify(chainIds),
546
+ ...result.durationByDataSource,
547
+ },
548
+ parentContext,
549
+ });
550
+ return result;
551
+ },
552
+ });
553
+ // Mark after the unlock/first forceUpdate so later polls skip pipeline spans.
554
+ __classPrivateFieldSet(this, _AssetsController_firstInitFetchReported, true, "f");
555
+ // Background (slow) lane — flattened sibling of the fast lane (not nested
556
+ // inside its withTrace callback). Still fire-and-forget so UI is not blocked.
557
+ const slowPipelineChainIds = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSlowPipelineChainIds).call(this, chainIds, response);
558
+ if (slowPipelineChainIds.length > 0) {
559
+ const slowSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
560
+ ? [__classPrivateFieldGet(this, _AssetsController_snapDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")]
561
+ : [__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")];
562
+ const slowRequest = { ...request, chainIds: slowPipelineChainIds };
563
+ withTrace({
564
+ name: TRACE_BACKGROUND_FETCH,
565
+ trace: pipelineTrace,
566
+ data: {
567
+ chain_count: slowPipelineChainIds.length,
568
+ account_count: accounts.length,
569
+ },
570
+ fn: async (slowParentContext) => {
571
+ const { response: slowResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, {
572
+ sources: [
573
+ createParallelBalanceMiddleware(slowSources),
574
+ __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
575
+ ...(__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
576
+ ? [
577
+ createParallelMiddleware([
578
+ __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
579
+ __classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
580
+ ]),
581
+ ]
582
+ : []),
583
+ ],
584
+ request: slowRequest,
585
+ parentContext: slowParentContext,
586
+ trace: pipelineTrace,
587
+ });
588
+ await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
589
+ ...slowResponse,
590
+ updateMode: 'merge',
591
+ });
592
+ },
593
+ }).catch((error) => log('Background pipeline failed', { error }));
521
594
  }
522
595
  }
523
596
  const result = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetsFromState).call(this, accounts, chainIds, assetTypes);
@@ -764,28 +837,20 @@ export class AssetsController extends BaseController {
764
837
  balances[accountId] ?? (balances[accountId] = {});
765
838
  (_a = balances[accountId])[normalizedAssetId] ?? (_a[normalizedAssetId] = { amount: '0' });
766
839
  });
840
+ // Fetch data for the newly added custom asset (merge to preserve other chains)
767
841
  const account = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((a) => a.id === accountId);
768
842
  if (account) {
769
843
  const chainId = extractChainId(normalizedAssetId);
770
- if (__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_isBalanceV6Enabled).call(this)) {
771
- await this.getAssets([account], {
772
- chainIds: [chainId],
773
- dataTypes: ['balance', 'metadata', 'price'],
774
- assetTypes: ['fungible'],
775
- forceUpdate: true,
776
- customAssets: [normalizedAssetId],
777
- });
778
- }
779
- else {
780
- await this.getAssets([account], {
781
- chainIds: [chainId],
782
- dataTypes: ['balance', 'metadata', 'price'],
783
- assetTypes: ['fungible'],
784
- forceUpdate: true,
785
- });
786
- }
844
+ await this.getAssets([account], {
845
+ chainIds: [chainId],
846
+ dataTypes: ['balance', 'metadata', 'price'],
847
+ assetTypes: ['fungible'],
848
+ forceUpdate: true,
849
+ updateMode: 'merge',
850
+ });
787
851
  }
788
- // Re-evaluate subscriptions so polls pick up the new pin.
852
+ // Re-evaluate subscriptions so the supplemental RPC poll picks up the
853
+ // new customAsset on chains another data source already owns.
789
854
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
790
855
  }
791
856
  /**
@@ -806,7 +871,8 @@ export class AssetsController extends BaseController {
806
871
  }
807
872
  }
808
873
  });
809
- // Re-evaluate subscriptions so polls drop the removed pin.
874
+ // Re-evaluate subscriptions so the supplemental RPC poll for that chain
875
+ // is torn down when no more customAssets remain there.
810
876
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
811
877
  }
812
878
  /**
@@ -837,8 +903,6 @@ export class AssetsController extends BaseController {
837
903
  }
838
904
  state.assetPreferences[normalizedAssetId].hidden = true;
839
905
  });
840
- // Re-evaluate subscriptions so polls exclude the newly hidden asset.
841
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
842
906
  }
843
907
  /**
844
908
  * Unhide an asset globally.
@@ -857,8 +921,6 @@ export class AssetsController extends BaseController {
857
921
  }
858
922
  }
859
923
  });
860
- // Re-evaluate subscriptions so polls stop excluding the asset.
861
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
862
924
  }
863
925
  // ============================================================================
864
926
  // CURRENT CURRENCY MANAGEMENT
@@ -970,14 +1032,101 @@ export class AssetsController extends BaseController {
970
1032
  async handleAssetsUpdate(response, sourceId, request) {
971
1033
  log('Assets updated from data source', {
972
1034
  sourceId,
973
- assetsBalance: response.assetsBalance,
974
- assetsPrice: response.assetsPrice,
1035
+ hasBalance: Boolean(response.assetsBalance),
1036
+ hasPrice: Boolean(response.assetsPrice),
1037
+ });
1038
+ // Enrichment spans only before unlock/first-init fetch completes.
1039
+ const pipelineTrace = __classPrivateFieldGet(this, _AssetsController_firstInitFetchReported, "f")
1040
+ ? undefined
1041
+ : __classPrivateFieldGet(this, _AssetsController_trace, "f");
1042
+ await withTrace({
1043
+ name: TRACE_UPDATE_PARENT,
1044
+ trace: pipelineTrace,
1045
+ data: {
1046
+ source: sourceId,
1047
+ has_balance: Boolean(response.assetsBalance),
1048
+ has_price: Boolean(response.assetsPrice),
1049
+ balance_account_count: response.assetsBalance
1050
+ ? Object.keys(response.assetsBalance).length
1051
+ : 0,
1052
+ },
1053
+ fn: async (parentContext) => {
1054
+ const updateStart = performance.now();
1055
+ const resolvedRequest = request ?? {
1056
+ accountsWithSupportedChains: [],
1057
+ chainIds: [],
1058
+ dataTypes: ['balance', 'metadata', 'price'],
1059
+ };
1060
+ // RPC-only mode (basic functionality off): never run token/price APIs. Strip
1061
+ // those data types so downstream middleware cannot treat them as requested.
1062
+ const pipelineRequest = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
1063
+ ? resolvedRequest
1064
+ : {
1065
+ ...resolvedRequest,
1066
+ dataTypes: resolvedRequest.dataTypes.filter((dt) => dt !== 'metadata' && dt !== 'price'),
1067
+ };
1068
+ // Graduate custom assets only when AccountsAPI / AccountActivity reports
1069
+ // them. RPC already fetches custom assets on purpose, and Snap handles
1070
+ // non-EVM chains the rule does not apply to, so skip the middleware for
1071
+ // those.
1072
+ const shouldGraduateCustomAssets = sourceId === 'AccountsApiDataSource' ||
1073
+ sourceId === 'AccountActivityDataSource';
1074
+ // Websocket updates can carry brand-new spam airdrops: enrich them
1075
+ // with Token API occurrences and drop below-floor tokens BEFORE
1076
+ // detection, so spam is never detected, enriched, priced or persisted.
1077
+ const shouldFilterOccurrences = sourceId === 'AccountActivityDataSource' &&
1078
+ __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this);
1079
+ const shouldRunRpcFallback = sourceId === 'AccountsApiDataSource';
1080
+ const enrichmentSources = [
1081
+ ...(shouldGraduateCustomAssets
1082
+ ? [__classPrivateFieldGet(this, _AssetsController_customAssetGraduationMiddleware, "f")]
1083
+ : []),
1084
+ ...(shouldFilterOccurrences
1085
+ ? [
1086
+ {
1087
+ getName: () => 'OccurrenceFloorFilter',
1088
+ assetsMiddleware: __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f").occurrenceFilterMiddleware,
1089
+ },
1090
+ ]
1091
+ : []),
1092
+ ...(shouldRunRpcFallback ? [__classPrivateFieldGet(this, _AssetsController_rpcFallbackMiddleware, "f")] : []),
1093
+ __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
1094
+ ];
1095
+ if (__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)) {
1096
+ enrichmentSources.push(createParallelMiddleware([
1097
+ __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
1098
+ __classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
1099
+ ]));
1100
+ }
1101
+ const { response: enrichedResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, {
1102
+ sources: enrichmentSources,
1103
+ request: pipelineRequest,
1104
+ initialResponse: response,
1105
+ parentContext,
1106
+ trace: pipelineTrace,
1107
+ });
1108
+ await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
1109
+ ...enrichedResponse,
1110
+ replaceCoveredChainBalances: response.replaceCoveredChainBalances,
1111
+ });
1112
+ // Summary fields for Assets Health (nested under the parent span).
1113
+ emitTrace({
1114
+ name: TRACE_UPDATE_PIPELINE,
1115
+ trace: pipelineTrace,
1116
+ data: {
1117
+ source: sourceId,
1118
+ duration_ms: performance.now() - updateStart,
1119
+ has_balance: Boolean(response.assetsBalance),
1120
+ has_price: Boolean(response.assetsPrice),
1121
+ has_metadata: Boolean(enrichedResponse.assetsInfo),
1122
+ balance_account_count: response.assetsBalance
1123
+ ? Object.keys(response.assetsBalance).length
1124
+ : 0,
1125
+ },
1126
+ parentContext,
1127
+ });
1128
+ },
975
1129
  });
976
- if (__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_isBalanceV6Enabled).call(this)) {
977
- await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleAssetsUpdateV6).call(this, response, sourceId, request);
978
- return;
979
- }
980
- await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleAssetsUpdateV5).call(this, response, sourceId, request);
981
1130
  }
982
1131
  // ============================================================================
983
1132
  // CLEANUP
@@ -1219,6 +1368,7 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
1219
1368
  this.getAssets([matchedAccount], {
1220
1369
  chainIds: [caipChainId],
1221
1370
  forceUpdate: true,
1371
+ bypassServerCache: true,
1222
1372
  }).catch((error) => {
1223
1373
  log('Failed to refresh assets after transaction event', { error });
1224
1374
  });
@@ -1427,236 +1577,6 @@ async function _AssetsController_executeMiddlewares(params) {
1427
1577
  });
1428
1578
  }
1429
1579
  return { response: result.response, durationByDataSource };
1430
- }, _AssetsController_buildForceUpdateRequestV5 = function _AssetsController_buildForceUpdateRequestV5(accounts, chainIds, requestOptions) {
1431
- const customAssets = [];
1432
- for (const account of accounts) {
1433
- customAssets.push(...this.getCustomAssets(account.id));
1434
- }
1435
- return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildDataRequest).call(this, accounts, chainIds, {
1436
- ...requestOptions,
1437
- customAssets: customAssets.length > 0 ? customAssets : undefined,
1438
- });
1439
- }, _AssetsController_buildForceUpdateRequestV6 = function _AssetsController_buildForceUpdateRequestV6(accounts, chainIds, requestOptions) {
1440
- const requestedChains = new Set(chainIds);
1441
- const candidateCustomAssets = requestOptions.customAssetsOverride ??
1442
- accounts.flatMap((account) => this.getCustomAssets(account.id));
1443
- const customAssetsSet = new Set();
1444
- for (const assetId of candidateCustomAssets) {
1445
- try {
1446
- const normalizedAssetId = normalizeAssetId(assetId);
1447
- if (requestedChains.has(parseCaipAssetType(normalizedAssetId).chainId)) {
1448
- customAssetsSet.add(normalizedAssetId);
1449
- }
1450
- }
1451
- catch {
1452
- // Skip unparseable asset IDs
1453
- }
1454
- }
1455
- const customAssets = [...customAssetsSet];
1456
- const hiddenAssets = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getHiddenAssetIds).call(this);
1457
- return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildDataRequest).call(this, accounts, chainIds, {
1458
- assetTypes: requestOptions.assetTypes,
1459
- dataTypes: requestOptions.dataTypes,
1460
- forceUpdate: requestOptions.forceUpdate,
1461
- assetsForPriceUpdate: requestOptions.assetsForPriceUpdate,
1462
- customAssets: customAssets.length > 0 ? customAssets : undefined,
1463
- excludeAssetIds: hiddenAssets.length > 0 ? hiddenAssets : undefined,
1464
- });
1465
- }, _AssetsController_forceUpdateAssetsV5 = async function _AssetsController_forceUpdateAssetsV5({ accounts, chainIds, request, pipelineTrace, }) {
1466
- const isBasicFunctionality = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this);
1467
- const fastSources = isBasicFunctionality
1468
- ? [
1469
- createParallelBalanceMiddleware([
1470
- __classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f"),
1471
- __classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"),
1472
- ]),
1473
- __classPrivateFieldGet(this, _AssetsController_customAssetGraduationMiddleware, "f"),
1474
- __classPrivateFieldGet(this, _AssetsController_rpcFallbackMiddleware, "f"),
1475
- __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
1476
- createParallelMiddleware([
1477
- __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
1478
- __classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
1479
- ]),
1480
- ]
1481
- : [__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f")];
1482
- const fastResponse = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_runFastFetchV5).call(this, {
1483
- accounts,
1484
- chainIds,
1485
- request,
1486
- pipelineTrace,
1487
- fastSources,
1488
- isBasicFunctionality,
1489
- });
1490
- __classPrivateFieldSet(this, _AssetsController_firstInitFetchReported, true, "f");
1491
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_runBackgroundFetch).call(this, {
1492
- accounts,
1493
- request,
1494
- pipelineTrace,
1495
- chainIds: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSlowPipelineChainIds).call(this, chainIds, fastResponse),
1496
- isBasicFunctionality,
1497
- });
1498
- }, _AssetsController_forceUpdateAssetsV6 = async function _AssetsController_forceUpdateAssetsV6({ accounts, chainIds, request, pipelineTrace, }) {
1499
- const isBasicFunctionality = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this);
1500
- const fastSources = isBasicFunctionality
1501
- ? [
1502
- createParallelBalanceMiddleware([
1503
- __classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f"),
1504
- __classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"),
1505
- ]),
1506
- __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
1507
- createParallelMiddleware([
1508
- __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
1509
- __classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
1510
- ]),
1511
- ]
1512
- : [__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f")];
1513
- const fastResponse = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_runFastFetchV6).call(this, {
1514
- accounts,
1515
- chainIds,
1516
- request,
1517
- pipelineTrace,
1518
- fastSources,
1519
- isBasicFunctionality,
1520
- });
1521
- __classPrivateFieldSet(this, _AssetsController_firstInitFetchReported, true, "f");
1522
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_runBackgroundFetch).call(this, {
1523
- accounts,
1524
- request,
1525
- pipelineTrace,
1526
- chainIds: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSlowPipelineChainIds).call(this, chainIds, fastResponse),
1527
- isBasicFunctionality,
1528
- });
1529
- }, _AssetsController_runFastFetchV5 = async function _AssetsController_runFastFetchV5({ accounts, chainIds, request, pipelineTrace, fastSources, isBasicFunctionality, }) {
1530
- const { response } = await withTrace({
1531
- name: TRACE_FETCH_PIPELINE,
1532
- trace: pipelineTrace,
1533
- data: {
1534
- chain_count: chainIds.length,
1535
- account_count: accounts.length,
1536
- basic_functionality: isBasicFunctionality,
1537
- },
1538
- fn: async (parentContext) => {
1539
- const startTime = performance.now();
1540
- const result = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, {
1541
- sources: fastSources,
1542
- request,
1543
- parentContext,
1544
- trace: pipelineTrace,
1545
- });
1546
- await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
1547
- ...result.response,
1548
- updateMode: 'merge',
1549
- replaceCoveredChainBalances: true,
1550
- });
1551
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitFastFetchTraces).call(this, {
1552
- accounts,
1553
- chainIds,
1554
- result,
1555
- durationMs: performance.now() - startTime,
1556
- isBasicFunctionality,
1557
- parentContext,
1558
- pipelineTrace,
1559
- });
1560
- return result;
1561
- },
1562
- });
1563
- return response;
1564
- }, _AssetsController_runFastFetchV6 = async function _AssetsController_runFastFetchV6({ accounts, chainIds, request, pipelineTrace, fastSources, isBasicFunctionality, }) {
1565
- const { response } = await withTrace({
1566
- name: TRACE_FETCH_PIPELINE,
1567
- trace: pipelineTrace,
1568
- data: {
1569
- chain_count: chainIds.length,
1570
- account_count: accounts.length,
1571
- basic_functionality: isBasicFunctionality,
1572
- },
1573
- fn: async (parentContext) => {
1574
- const startTime = performance.now();
1575
- const result = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, {
1576
- sources: fastSources,
1577
- request,
1578
- parentContext,
1579
- trace: pipelineTrace,
1580
- });
1581
- await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, result.response);
1582
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitFastFetchTraces).call(this, {
1583
- accounts,
1584
- chainIds,
1585
- result,
1586
- durationMs: performance.now() - startTime,
1587
- isBasicFunctionality,
1588
- parentContext,
1589
- pipelineTrace,
1590
- });
1591
- return result;
1592
- },
1593
- });
1594
- return response;
1595
- }, _AssetsController_runBackgroundFetch = function _AssetsController_runBackgroundFetch({ accounts, chainIds, request, pipelineTrace, isBasicFunctionality, }) {
1596
- if (chainIds.length === 0) {
1597
- return;
1598
- }
1599
- const slowSources = isBasicFunctionality
1600
- ? [__classPrivateFieldGet(this, _AssetsController_snapDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")]
1601
- : [__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")];
1602
- const slowRequest = { ...request, chainIds };
1603
- withTrace({
1604
- name: TRACE_BACKGROUND_FETCH,
1605
- trace: pipelineTrace,
1606
- data: {
1607
- chain_count: chainIds.length,
1608
- account_count: accounts.length,
1609
- },
1610
- fn: async (parentContext) => {
1611
- const { response } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, {
1612
- sources: [
1613
- createParallelBalanceMiddleware(slowSources),
1614
- __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
1615
- ...(isBasicFunctionality
1616
- ? [
1617
- createParallelMiddleware([
1618
- __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
1619
- __classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
1620
- ]),
1621
- ]
1622
- : []),
1623
- ],
1624
- request: slowRequest,
1625
- parentContext,
1626
- trace: pipelineTrace,
1627
- });
1628
- await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, { ...response, updateMode: 'merge' });
1629
- },
1630
- }).catch((error) => log('Background pipeline failed', { error }));
1631
- }, _AssetsController_emitFastFetchTraces = function _AssetsController_emitFastFetchTraces({ accounts, chainIds, result, durationMs, isBasicFunctionality, parentContext, pipelineTrace, }) {
1632
- emitTrace({
1633
- name: TRACE_FULL_FETCH,
1634
- trace: pipelineTrace,
1635
- data: {
1636
- duration_ms: durationMs,
1637
- chain_count: chainIds.length,
1638
- account_count: accounts.length,
1639
- basic_functionality: isBasicFunctionality,
1640
- asset_count: result.response.assetsBalance
1641
- ? Object.values(result.response.assetsBalance).reduce((sum, account) => sum + Object.keys(account).length, 0)
1642
- : 0,
1643
- price_count: result.response.assetsPrice
1644
- ? Object.keys(result.response.assetsPrice).length
1645
- : 0,
1646
- ...result.durationByDataSource,
1647
- },
1648
- parentContext,
1649
- });
1650
- emitTrace({
1651
- name: TRACE_FIRST_INIT_FETCH,
1652
- trace: pipelineTrace,
1653
- data: {
1654
- duration_ms: durationMs,
1655
- chain_ids: JSON.stringify(chainIds),
1656
- ...result.durationByDataSource,
1657
- },
1658
- parentContext,
1659
- });
1660
1580
  }, _AssetsController_assertNonEmptyAccountId = function _AssetsController_assertNonEmptyAccountId(accountId, methodName) {
1661
1581
  if (typeof accountId !== 'string' || accountId.length === 0) {
1662
1582
  throw new Error(`AssetsController.${methodName}: accountId must be a non-empty string`);
@@ -1668,25 +1588,6 @@ async function _AssetsController_executeMiddlewares(params) {
1668
1588
  catch {
1669
1589
  throw new Error(`AssetsController.${methodName}: invalid CAIP-19 assetId "${assetId}"`);
1670
1590
  }
1671
- }, _AssetsController_getHiddenAssetIds = function _AssetsController_getHiddenAssetIds() {
1672
- const hidden = [];
1673
- for (const [assetId, prefs] of Object.entries(this.state.assetPreferences)) {
1674
- if (prefs.hidden) {
1675
- hidden.push(assetId);
1676
- }
1677
- }
1678
- return hidden;
1679
- }, _AssetsController_isBalanceV6Enabled = function _AssetsController_isBalanceV6Enabled() {
1680
- try {
1681
- const { remoteFeatureFlags } = this.messenger.call('RemoteFeatureFlagController:getState');
1682
- const flag = remoteFeatureFlags?.assetsAccountsApiV6;
1683
- return (typeof flag === 'object' &&
1684
- flag !== null &&
1685
- Boolean(flag.value));
1686
- }
1687
- catch {
1688
- return false;
1689
- }
1690
1591
  }, _AssetsController_fetchMissingPricesWithoutCache = function _AssetsController_fetchMissingPricesWithoutCache(accounts, chainIds) {
1691
1592
  if (!__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this) || accounts.length === 0) {
1692
1593
  return;
@@ -1768,16 +1669,10 @@ async function _AssetsController_executeMiddlewares(params) {
1768
1669
  return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_resolveNativeAssetIds).call(this, __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getEnabledChainsForAccount).call(this, account));
1769
1670
  }, _AssetsController_getSlowPipelineChainIds = function _AssetsController_getSlowPipelineChainIds(chainIds, fastResponse) {
1770
1671
  const accountsApiChains = new Set(__classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f").getActiveChainsSync());
1771
- // Chains whose pins went unresolved (`unprocessedCustomAssets`): route
1772
- // them to the slow pipeline so RPC fetches the pins.
1773
- const unprocessedCustomAssetChains = new Set((fastResponse.unprocessedCustomAssets ?? []).map((assetId) => assetId.split('/')[0]));
1774
1672
  return chainIds.filter((chainId) => {
1775
1673
  if (fastResponse.errors?.[chainId]) {
1776
1674
  return true;
1777
1675
  }
1778
- if (unprocessedCustomAssetChains.has(chainId)) {
1779
- return true;
1780
- }
1781
1676
  if (!accountsApiChains.has(chainId)) {
1782
1677
  return true;
1783
1678
  }
@@ -1917,9 +1812,9 @@ async function _AssetsController_executeMiddlewares(params) {
1917
1812
  for (const [accountId, accountBalances] of Object.entries(normalizedResponse.assetsBalance)) {
1918
1813
  const previousBalances = previousState.assetsBalance[accountId] ?? {};
1919
1814
  const customAssetIds = state.customAssets[accountId] ?? [];
1920
- const effective = mode === 'full'
1921
- ? mergeAccountBalancesV6(previousBalances, accountBalances, normalizedResponse.unprocessedCustomAssets ?? [])
1922
- : mergeAccountBalancesV5(previousBalances, accountBalances, customAssetIds, normalizedResponse.replaceCoveredChainBalances === true);
1815
+ const replaceCoveredChains = mode === 'full' ||
1816
+ normalizedResponse.replaceCoveredChainBalances === true;
1817
+ const effective = mergeAccountBalances(previousBalances, accountBalances, customAssetIds, replaceCoveredChains);
1923
1818
  // Ensure native tokens have an entry (0 if missing) for chains this account supports
1924
1819
  const account = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((a) => a.id === accountId);
1925
1820
  const nativeAssetIdsForAccount = account
@@ -1976,8 +1871,10 @@ async function _AssetsController_executeMiddlewares(params) {
1976
1871
  changedPriceAssets.length > 0) {
1977
1872
  log('State updated', {
1978
1873
  changedBalances: changedBalances.length > 0 ? changedBalances : undefined,
1979
- changedMetadata: changedMetadata.length > 0 ? changedMetadata : undefined,
1980
- changedPrices: changedPriceAssets.length > 0 ? changedPriceAssets : undefined,
1874
+ changedMetadataCount: changedMetadata.length > 0 ? changedMetadata.length : undefined,
1875
+ changedPricesCount: changedPriceAssets.length > 0
1876
+ ? changedPriceAssets.length
1877
+ : undefined,
1981
1878
  newAssets: Object.keys(detectedAssets).length > 0
1982
1879
  ? Object.entries(detectedAssets).map(([accountId, assets]) => ({
1983
1880
  accountId,
@@ -2150,10 +2047,16 @@ async function _AssetsController_executeMiddlewares(params) {
2150
2047
  if (!subscriptionKey.startsWith('ds:')) {
2151
2048
  continue;
2152
2049
  }
2153
- // Subscription keys take the form `ds:<SourceName>`.
2050
+ // Subscription keys take the form `ds:<SourceName>` for the regular
2051
+ // subscription or `ds:<SourceName>:<suffix>` for supplemental
2052
+ // subscriptions (e.g. `ds:RpcDataSource:custom`). Split on `:` and
2053
+ // pick the source-name segment so both shapes resolve correctly.
2154
2054
  const [, sourceId] = subscriptionKey.split(':');
2155
2055
  const source = allSources.find((ds) => ds.getName() === sourceId);
2156
2056
  if (source) {
2057
+ // Unsubscribe by the actual key — `#unsubscribeDataSource` only
2058
+ // knows the regular `ds:<SourceName>` shape and would miss
2059
+ // supplemental subscriptions, leaking their polling timers.
2157
2060
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_unsubscribeBySubscriptionKey).call(this, source, subscriptionKey);
2158
2061
  }
2159
2062
  }
@@ -2171,15 +2074,12 @@ async function _AssetsController_executeMiddlewares(params) {
2171
2074
  // Subscribe to price updates for all assets held by selected accounts
2172
2075
  this.subscribeAssetsPrice(accounts, enabledChains);
2173
2076
  }, _AssetsController_subscribeAssetsBalance = function _AssetsController_subscribeAssetsBalance(accounts, chainIds, options) {
2174
- if (__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_isBalanceV6Enabled).call(this)) {
2175
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssetsBalanceV6).call(this, accounts, chainIds, options);
2176
- return;
2177
- }
2178
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssetsBalanceV5).call(this, accounts, chainIds, options);
2179
- }, _AssetsController_subscribeAssetsBalanceV5 = function _AssetsController_subscribeAssetsBalanceV5(accounts, chainIds, options) {
2180
2077
  const chainToAccounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildChainToAccountsMap).call(this, accounts, new Set(chainIds));
2181
2078
  const remainingChains = new Set(chainToAccounts.keys());
2182
- const balanceDataSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
2079
+ // When basic functionality is on, use all balance data sources; when off,
2080
+ // RPC only.
2081
+ const isBasicFunctionality = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this);
2082
+ const balanceDataSources = isBasicFunctionality
2183
2083
  ? __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_allBalanceDataSources_get)
2184
2084
  : [__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")];
2185
2085
  let rpcAssignedChains = new Set();
@@ -2218,81 +2118,13 @@ async function _AssetsController_executeMiddlewares(params) {
2218
2118
  });
2219
2119
  }
2220
2120
  }
2121
+ // Supplemental RPC subscription for customAssets on chains another data
2122
+ // source claimed during regular handoff. RPC is the sole balance fetcher
2123
+ // for customAssets, so we must always poll them — even when (e.g.)
2124
+ // AccountsApi is already covering the chain for normal balances. The
2125
+ // supplemental subscription runs in `customAssetsOnly` mode so it does
2126
+ // NOT double-poll the regular tracked balances.
2221
2127
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeRpcCustomAssetsSupplement).call(this, accounts, chainToAccounts, rpcAssignedChains);
2222
- }, _AssetsController_subscribeAssetsBalanceV6 = function _AssetsController_subscribeAssetsBalanceV6(accounts, chainIds, options) {
2223
- const chainToAccounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildChainToAccountsMap).call(this, accounts, new Set(chainIds));
2224
- const remainingChains = new Set(chainToAccounts.keys());
2225
- const remainingCustomAssets = new Set();
2226
- for (const account of accounts) {
2227
- for (const assetId of this.getCustomAssets(account.id)) {
2228
- try {
2229
- if (remainingChains.has(parseCaipAssetType(assetId).chainId)) {
2230
- remainingCustomAssets.add(assetId);
2231
- }
2232
- }
2233
- catch {
2234
- // Skip unparseable asset IDs
2235
- }
2236
- }
2237
- }
2238
- const balanceDataSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
2239
- ? __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_allBalanceDataSources_get)
2240
- : [__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")];
2241
- for (const source of balanceDataSources) {
2242
- const availableChains = new Set(source.getActiveChainsSync());
2243
- const assignedChains = [];
2244
- for (const chainId of remainingChains) {
2245
- if (availableChains.has(chainId)) {
2246
- assignedChains.push(chainId);
2247
- remainingChains.delete(chainId);
2248
- }
2249
- }
2250
- const claimedAssets = source.claimCustomAssets([...remainingCustomAssets], assignedChains);
2251
- for (const assetId of claimedAssets) {
2252
- remainingCustomAssets.delete(assetId);
2253
- }
2254
- if (assignedChains.length === 0 && claimedAssets.length === 0) {
2255
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_unsubscribeDataSource).call(this, source);
2256
- continue;
2257
- }
2258
- const claimedAssetsSet = new Set(claimedAssets);
2259
- const seenIds = new Set();
2260
- const accountsForSource = assignedChains
2261
- .flatMap((chainId) => chainToAccounts.get(chainId) ?? [])
2262
- .filter((account) => {
2263
- if (seenIds.has(account.id)) {
2264
- return false;
2265
- }
2266
- seenIds.add(account.id);
2267
- return true;
2268
- });
2269
- for (const account of accounts) {
2270
- if (!seenIds.has(account.id) &&
2271
- this.getCustomAssets(account.id).some((assetId) => claimedAssetsSet.has(assetId))) {
2272
- seenIds.add(account.id);
2273
- accountsForSource.push(account);
2274
- }
2275
- }
2276
- if (accountsForSource.length > 0) {
2277
- const hiddenAssets = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getHiddenAssetIds).call(this);
2278
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeDataSource).call(this, source, accountsForSource, assignedChains, {
2279
- customAssets: claimedAssets,
2280
- excludeAssetIds: hiddenAssets.length > 0 ? hiddenAssets : undefined,
2281
- ...(options?.skipInitialFetch &&
2282
- source === __classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f")
2283
- ? { skipInitialFetch: true }
2284
- : {}),
2285
- });
2286
- }
2287
- else {
2288
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_unsubscribeDataSource).call(this, source);
2289
- }
2290
- }
2291
- if (remainingCustomAssets.size > 0) {
2292
- log('Custom assets unclaimed by any data source', {
2293
- assetIds: [...remainingCustomAssets],
2294
- });
2295
- }
2296
2128
  }, _AssetsController_subscribeRpcCustomAssetsSupplement = function _AssetsController_subscribeRpcCustomAssetsSupplement(accounts, chainToAccounts, rpcAssignedChains) {
2297
2129
  const rpc = __classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f");
2298
2130
  const supplementalKey = `ds:${rpc.getName()}:custom`;
@@ -2355,14 +2187,12 @@ async function _AssetsController_executeMiddlewares(params) {
2355
2187
  const subscriptionKey = options.subscriptionKey ?? `ds:${sourceId}`;
2356
2188
  const existingSubscription = __classPrivateFieldGet(this, _AssetsController_activeSubscriptions, "f").get(subscriptionKey);
2357
2189
  const isUpdate = existingSubscription !== undefined;
2358
- const customAssets = options.customAssets ?? [];
2359
2190
  log('Subscribe to data source', {
2360
2191
  sourceId,
2361
2192
  subscriptionKey,
2362
2193
  isUpdate,
2363
2194
  accountCount: accounts.length,
2364
2195
  chainCount: chains.length,
2365
- customAssetCount: customAssets.length,
2366
2196
  customAssetsOnly: options.customAssetsOnly === true,
2367
2197
  skipInitialFetch: options.skipInitialFetch === true,
2368
2198
  });
@@ -2371,10 +2201,6 @@ async function _AssetsController_executeMiddlewares(params) {
2371
2201
  assetTypes: ['fungible'],
2372
2202
  dataTypes: ['balance'],
2373
2203
  updateInterval: __classPrivateFieldGet(this, _AssetsController_defaultUpdateInterval, "f"),
2374
- customAssets: customAssets.length > 0 ? customAssets : undefined,
2375
- excludeAssetIds: options.excludeAssetIds && options.excludeAssetIds.length > 0
2376
- ? options.excludeAssetIds
2377
- : undefined,
2378
2204
  ...(options.customAssetsOnly === true
2379
2205
  ? { customAssetsOnly: true }
2380
2206
  : {}),
@@ -2538,13 +2364,13 @@ async function _AssetsController_handleAccountGroupChanged(groupId, previousGrou
2538
2364
  // The data will simply not be updated until the network is re-enabled.
2539
2365
  // Refresh subscriptions for new chain set
2540
2366
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
2541
- // One-time fetch for newly enabled chains. v6 `full` replace is scoped to
2542
- // those chains; existing balances on other chains are left untouched.
2367
+ // Do one-time fetch for newly enabled chains; merge so we keep existing chain balances
2543
2368
  const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this);
2544
2369
  if (addedChains.length > 0 && accounts.length > 0) {
2545
2370
  await this.getAssets(accounts, {
2546
2371
  chainIds: addedChains,
2547
2372
  forceUpdate: true,
2373
+ updateMode: 'merge',
2548
2374
  });
2549
2375
  }
2550
2376
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
@@ -2667,150 +2493,5 @@ async function _AssetsController_refreshAssetsAfterNetworkAdded(hexChainId) {
2667
2493
  });
2668
2494
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
2669
2495
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_fetchMissingPricesWithoutCache).call(this, accounts, [caipChainId]);
2670
- }, _AssetsController_handleAssetsUpdateV5 = async function _AssetsController_handleAssetsUpdateV5(response, sourceId, request) {
2671
- const pipelineTrace = __classPrivateFieldGet(this, _AssetsController_firstInitFetchReported, "f")
2672
- ? undefined
2673
- : __classPrivateFieldGet(this, _AssetsController_trace, "f");
2674
- await withTrace({
2675
- name: TRACE_UPDATE_PARENT,
2676
- trace: pipelineTrace,
2677
- data: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getUpdateTraceData).call(this, response, sourceId),
2678
- fn: async (parentContext) => {
2679
- const updateStart = performance.now();
2680
- const pipelineRequest = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getUpdatePipelineRequest).call(this, request);
2681
- const shouldGraduateCustomAssets = sourceId === 'AccountsApiDataSource' ||
2682
- sourceId === 'AccountActivityDataSource';
2683
- const shouldFilterOccurrences = sourceId === 'AccountActivityDataSource' &&
2684
- __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this);
2685
- const enrichmentSources = [
2686
- ...(shouldGraduateCustomAssets
2687
- ? [__classPrivateFieldGet(this, _AssetsController_customAssetGraduationMiddleware, "f")]
2688
- : []),
2689
- ...(shouldFilterOccurrences
2690
- ? [
2691
- {
2692
- getName: () => 'OccurrenceFloorFilter',
2693
- assetsMiddleware: __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f").occurrenceFilterMiddleware,
2694
- },
2695
- ]
2696
- : []),
2697
- ];
2698
- enrichmentSources.push(__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"));
2699
- if (__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)) {
2700
- enrichmentSources.push(createParallelMiddleware([
2701
- __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
2702
- __classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
2703
- ]));
2704
- }
2705
- const { response: enrichedResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, {
2706
- sources: enrichmentSources,
2707
- request: pipelineRequest,
2708
- initialResponse: response,
2709
- parentContext,
2710
- trace: pipelineTrace,
2711
- });
2712
- await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
2713
- ...enrichedResponse,
2714
- replaceCoveredChainBalances: response.replaceCoveredChainBalances,
2715
- });
2716
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitUpdateTrace).call(this, {
2717
- response,
2718
- sourceId,
2719
- enrichedResponse,
2720
- updateStart,
2721
- pipelineTrace,
2722
- parentContext,
2723
- });
2724
- },
2725
- });
2726
- }, _AssetsController_handleAssetsUpdateV6 = async function _AssetsController_handleAssetsUpdateV6(response, sourceId, request) {
2727
- const pipelineTrace = __classPrivateFieldGet(this, _AssetsController_firstInitFetchReported, "f")
2728
- ? undefined
2729
- : __classPrivateFieldGet(this, _AssetsController_trace, "f");
2730
- await withTrace({
2731
- name: TRACE_UPDATE_PARENT,
2732
- trace: pipelineTrace,
2733
- data: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getUpdateTraceData).call(this, response, sourceId),
2734
- fn: async (parentContext) => {
2735
- const updateStart = performance.now();
2736
- const pipelineRequest = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getUpdatePipelineRequest).call(this, request);
2737
- const shouldFilterOccurrences = sourceId === 'AccountActivityDataSource' &&
2738
- __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this);
2739
- const enrichmentSources = [
2740
- ...(shouldFilterOccurrences
2741
- ? [
2742
- {
2743
- getName: () => 'OccurrenceFloorFilter',
2744
- assetsMiddleware: __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f").occurrenceFilterMiddleware,
2745
- },
2746
- ]
2747
- : []),
2748
- ];
2749
- if (__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)) {
2750
- enrichmentSources.push(__classPrivateFieldGet(this, _AssetsController_rpcFallbackMiddleware, "f"));
2751
- }
2752
- enrichmentSources.push(__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"));
2753
- if (__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)) {
2754
- enrichmentSources.push(createParallelMiddleware([
2755
- __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
2756
- __classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
2757
- ]));
2758
- }
2759
- const { response: enrichedResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, {
2760
- sources: enrichmentSources,
2761
- request: pipelineRequest,
2762
- initialResponse: response,
2763
- parentContext,
2764
- trace: pipelineTrace,
2765
- });
2766
- await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, enrichedResponse);
2767
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitUpdateTrace).call(this, {
2768
- response,
2769
- sourceId,
2770
- enrichedResponse,
2771
- updateStart,
2772
- pipelineTrace,
2773
- parentContext,
2774
- });
2775
- },
2776
- });
2777
- }, _AssetsController_getUpdatePipelineRequest = function _AssetsController_getUpdatePipelineRequest(request) {
2778
- const resolvedRequest = request ?? {
2779
- accountsWithSupportedChains: [],
2780
- chainIds: [],
2781
- dataTypes: ['balance', 'metadata', 'price'],
2782
- };
2783
- if (__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)) {
2784
- return resolvedRequest;
2785
- }
2786
- return {
2787
- ...resolvedRequest,
2788
- dataTypes: resolvedRequest.dataTypes.filter((dataType) => dataType !== 'metadata' && dataType !== 'price'),
2789
- };
2790
- }, _AssetsController_getUpdateTraceData = function _AssetsController_getUpdateTraceData(response, sourceId) {
2791
- return {
2792
- source: sourceId,
2793
- has_balance: Boolean(response.assetsBalance),
2794
- has_price: Boolean(response.assetsPrice),
2795
- balance_account_count: response.assetsBalance
2796
- ? Object.keys(response.assetsBalance).length
2797
- : 0,
2798
- };
2799
- }, _AssetsController_emitUpdateTrace = function _AssetsController_emitUpdateTrace({ response, sourceId, enrichedResponse, updateStart, pipelineTrace, parentContext, }) {
2800
- emitTrace({
2801
- name: TRACE_UPDATE_PIPELINE,
2802
- trace: pipelineTrace,
2803
- data: {
2804
- source: sourceId,
2805
- duration_ms: performance.now() - updateStart,
2806
- has_balance: Boolean(response.assetsBalance),
2807
- has_price: Boolean(response.assetsPrice),
2808
- has_metadata: Boolean(enrichedResponse.assetsInfo),
2809
- balance_account_count: response.assetsBalance
2810
- ? Object.keys(response.assetsBalance).length
2811
- : 0,
2812
- },
2813
- parentContext,
2814
- });
2815
2496
  };
2816
2497
  //# sourceMappingURL=AssetsController.mjs.map