@metamask-previews/assets-controller 14.0.3-preview-e12b5ece6 → 14.0.3-preview-fe4b3be11

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 (80) hide show
  1. package/CHANGELOG.md +5 -10
  2. package/dist/AssetsController.cjs +592 -273
  3. package/dist/AssetsController.cjs.map +1 -1
  4. package/dist/AssetsController.d.cts +7 -10
  5. package/dist/AssetsController.d.cts.map +1 -1
  6. package/dist/AssetsController.d.mts +7 -10
  7. package/dist/AssetsController.d.mts.map +1 -1
  8. package/dist/AssetsController.mjs +592 -273
  9. package/dist/AssetsController.mjs.map +1 -1
  10. package/dist/data-sources/AbstractDataSource.cjs +23 -0
  11. package/dist/data-sources/AbstractDataSource.cjs.map +1 -1
  12. package/dist/data-sources/AbstractDataSource.d.cts +13 -1
  13. package/dist/data-sources/AbstractDataSource.d.cts.map +1 -1
  14. package/dist/data-sources/AbstractDataSource.d.mts +13 -1
  15. package/dist/data-sources/AbstractDataSource.d.mts.map +1 -1
  16. package/dist/data-sources/AbstractDataSource.mjs +23 -0
  17. package/dist/data-sources/AbstractDataSource.mjs.map +1 -1
  18. package/dist/data-sources/AccountActivityDataSource.cjs +2 -0
  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 +2 -0
  23. package/dist/data-sources/AccountActivityDataSource.mjs.map +1 -1
  24. package/dist/data-sources/AccountsApiDataSource.cjs +144 -31
  25. package/dist/data-sources/AccountsApiDataSource.cjs.map +1 -1
  26. package/dist/data-sources/AccountsApiDataSource.d.cts +18 -2
  27. package/dist/data-sources/AccountsApiDataSource.d.cts.map +1 -1
  28. package/dist/data-sources/AccountsApiDataSource.d.mts +18 -2
  29. package/dist/data-sources/AccountsApiDataSource.d.mts.map +1 -1
  30. package/dist/data-sources/AccountsApiDataSource.mjs +145 -32
  31. package/dist/data-sources/AccountsApiDataSource.mjs.map +1 -1
  32. package/dist/data-sources/RpcDataSource.cjs +163 -24
  33. package/dist/data-sources/RpcDataSource.cjs.map +1 -1
  34. package/dist/data-sources/RpcDataSource.d.cts +17 -0
  35. package/dist/data-sources/RpcDataSource.d.cts.map +1 -1
  36. package/dist/data-sources/RpcDataSource.d.mts +17 -0
  37. package/dist/data-sources/RpcDataSource.d.mts.map +1 -1
  38. package/dist/data-sources/RpcDataSource.mjs +164 -25
  39. package/dist/data-sources/RpcDataSource.mjs.map +1 -1
  40. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.cjs +21 -12
  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 +7 -2
  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 +7 -2
  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 +21 -12
  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 +3 -2
  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 +3 -2
  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 +9 -0
  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 +9 -0
  59. package/dist/middlewares/ParallelMiddleware.mjs.map +1 -1
  60. package/dist/middlewares/RpcFallbackMiddleware.cjs +158 -128
  61. package/dist/middlewares/RpcFallbackMiddleware.cjs.map +1 -1
  62. package/dist/middlewares/RpcFallbackMiddleware.d.cts +10 -14
  63. package/dist/middlewares/RpcFallbackMiddleware.d.cts.map +1 -1
  64. package/dist/middlewares/RpcFallbackMiddleware.d.mts +10 -14
  65. package/dist/middlewares/RpcFallbackMiddleware.d.mts.map +1 -1
  66. package/dist/middlewares/RpcFallbackMiddleware.mjs +158 -128
  67. package/dist/middlewares/RpcFallbackMiddleware.mjs.map +1 -1
  68. package/dist/selectors/balance.cjs +4 -9
  69. package/dist/selectors/balance.cjs.map +1 -1
  70. package/dist/selectors/balance.d.cts.map +1 -1
  71. package/dist/selectors/balance.d.mts.map +1 -1
  72. package/dist/selectors/balance.mjs +4 -9
  73. package/dist/selectors/balance.mjs.map +1 -1
  74. package/dist/types.cjs.map +1 -1
  75. package/dist/types.d.cts +28 -26
  76. package/dist/types.d.cts.map +1 -1
  77. package/dist/types.d.mts +28 -26
  78. package/dist/types.d.mts.map +1 -1
  79. package/dist/types.mjs.map +1 -1
  80. package/package.json +4 -4
@@ -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_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;
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;
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,6 +202,10 @@ 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
+ }
205
209
  return normalized;
206
210
  }
207
211
  /**
@@ -209,12 +213,13 @@ function normalizeResponse(response) {
209
213
  *
210
214
  * @param previousBalances - Balances already in state for this account.
211
215
  * @param accountBalances - Balances from the incoming response.
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).
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.
215
220
  * @returns The merged balance map for the account.
216
221
  */
217
- function mergeAccountBalances(previousBalances, accountBalances, customAssetIds, replaceCoveredChains) {
222
+ function mergeAccountBalancesV5(previousBalances, accountBalances, customAssetIds = [], replaceCoveredChains = false) {
218
223
  if (!replaceCoveredChains) {
219
224
  return { ...previousBalances, ...accountBalances };
220
225
  }
@@ -228,8 +233,8 @@ function mergeAccountBalances(previousBalances, accountBalances, customAssetIds,
228
233
  Object.assign(next, accountBalances);
229
234
  for (const customId of customAssetIds) {
230
235
  if (!Object.prototype.hasOwnProperty.call(next, customId)) {
231
- const prev = previousBalances[customId];
232
- next[customId] = prev ?? { amount: '0' };
236
+ const previous = previousBalances[customId];
237
+ next[customId] = previous ?? { amount: '0' };
233
238
  }
234
239
  }
235
240
  // Staked vault balances are owned by StakedBalanceDataSource. When an
@@ -243,6 +248,38 @@ function mergeAccountBalances(previousBalances, accountBalances, customAssetIds,
243
248
  }
244
249
  return next;
245
250
  }
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
+ }
246
283
  // ============================================================================
247
284
  // CONTROLLER IMPLEMENTATION
248
285
  // ============================================================================
@@ -363,6 +400,7 @@ export class AssetsController extends BaseController {
363
400
  queryApiClient,
364
401
  onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
365
402
  ...accountsApiDataSourceConfig,
403
+ isBalanceV6Enabled: () => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_isBalanceV6Enabled).call(this),
366
404
  }), "f");
367
405
  __classPrivateFieldSet(this, _AssetsController_snapDataSource, new SnapDataSource({
368
406
  messenger: this.messenger,
@@ -382,6 +420,7 @@ export class AssetsController extends BaseController {
382
420
  ...rpcConfig,
383
421
  isOnboarded: rpcConfig.isOnboarded ?? isOnboarded,
384
422
  getAssetType: (assetId) => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetType).call(this, assetId),
423
+ isBalanceV6Enabled: () => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_isBalanceV6Enabled).call(this),
385
424
  }), "f");
386
425
  __classPrivateFieldSet(this, _AssetsController_stakedBalanceDataSource, new StakedBalanceDataSource({
387
426
  messenger: this.messenger,
@@ -414,6 +453,7 @@ export class AssetsController extends BaseController {
414
453
  }), "f");
415
454
  __classPrivateFieldSet(this, _AssetsController_rpcFallbackMiddleware, new RpcFallbackMiddleware({
416
455
  rpcDataSource: __classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f"),
456
+ isBalanceV6Enabled: () => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_isBalanceV6Enabled).call(this),
417
457
  }), "f");
418
458
  log('Initializing AssetsController', {
419
459
  defaultUpdateInterval: __classPrivateFieldGet(this, _AssetsController_defaultUpdateInterval, "f"),
@@ -450,147 +490,34 @@ export class AssetsController extends BaseController {
450
490
  if (accounts.length === 0 || chainIds.length === 0) {
451
491
  return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetsFromState).call(this, accounts, chainIds, assetTypes);
452
492
  }
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
- }
459
493
  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.
462
494
  const pipelineTrace = __classPrivateFieldGet(this, _AssetsController_firstInitFetchReported, "f")
463
495
  ? undefined
464
496
  : __classPrivateFieldGet(this, _AssetsController_trace, "f");
465
- const request = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildDataRequest).call(this, accounts, chainIds, {
497
+ const requestOptions = {
466
498
  assetTypes,
467
499
  dataTypes,
468
- customAssets: customAssets.length > 0 ? customAssets : undefined,
469
500
  forceUpdate: true,
470
- bypassServerCache: options?.bypassServerCache,
471
501
  assetsForPriceUpdate: options?.assetsForPriceUpdate,
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 }));
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
+ });
594
521
  }
595
522
  }
596
523
  const result = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetsFromState).call(this, accounts, chainIds, assetTypes);
@@ -837,20 +764,28 @@ export class AssetsController extends BaseController {
837
764
  balances[accountId] ?? (balances[accountId] = {});
838
765
  (_a = balances[accountId])[normalizedAssetId] ?? (_a[normalizedAssetId] = { amount: '0' });
839
766
  });
840
- // Fetch data for the newly added custom asset (merge to preserve other chains)
841
767
  const account = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((a) => a.id === accountId);
842
768
  if (account) {
843
769
  const chainId = extractChainId(normalizedAssetId);
844
- await this.getAssets([account], {
845
- chainIds: [chainId],
846
- dataTypes: ['balance', 'metadata', 'price'],
847
- assetTypes: ['fungible'],
848
- forceUpdate: true,
849
- updateMode: 'merge',
850
- });
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
+ }
851
787
  }
852
- // Re-evaluate subscriptions so the supplemental RPC poll picks up the
853
- // new customAsset on chains another data source already owns.
788
+ // Re-evaluate subscriptions so polls pick up the new pin.
854
789
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
855
790
  }
856
791
  /**
@@ -871,8 +806,7 @@ export class AssetsController extends BaseController {
871
806
  }
872
807
  }
873
808
  });
874
- // Re-evaluate subscriptions so the supplemental RPC poll for that chain
875
- // is torn down when no more customAssets remain there.
809
+ // Re-evaluate subscriptions so polls drop the removed pin.
876
810
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
877
811
  }
878
812
  /**
@@ -903,6 +837,8 @@ export class AssetsController extends BaseController {
903
837
  }
904
838
  state.assetPreferences[normalizedAssetId].hidden = true;
905
839
  });
840
+ // Re-evaluate subscriptions so polls exclude the newly hidden asset.
841
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
906
842
  }
907
843
  /**
908
844
  * Unhide an asset globally.
@@ -921,6 +857,8 @@ export class AssetsController extends BaseController {
921
857
  }
922
858
  }
923
859
  });
860
+ // Re-evaluate subscriptions so polls stop excluding the asset.
861
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
924
862
  }
925
863
  // ============================================================================
926
864
  // CURRENT CURRENCY MANAGEMENT
@@ -1032,101 +970,14 @@ export class AssetsController extends BaseController {
1032
970
  async handleAssetsUpdate(response, sourceId, request) {
1033
971
  log('Assets updated from data source', {
1034
972
  sourceId,
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
- },
973
+ assetsBalance: response.assetsBalance,
974
+ assetsPrice: response.assetsPrice,
1129
975
  });
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);
1130
981
  }
1131
982
  // ============================================================================
1132
983
  // CLEANUP
@@ -1368,7 +1219,6 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
1368
1219
  this.getAssets([matchedAccount], {
1369
1220
  chainIds: [caipChainId],
1370
1221
  forceUpdate: true,
1371
- bypassServerCache: true,
1372
1222
  }).catch((error) => {
1373
1223
  log('Failed to refresh assets after transaction event', { error });
1374
1224
  });
@@ -1577,6 +1427,236 @@ async function _AssetsController_executeMiddlewares(params) {
1577
1427
  });
1578
1428
  }
1579
1429
  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
+ });
1580
1660
  }, _AssetsController_assertNonEmptyAccountId = function _AssetsController_assertNonEmptyAccountId(accountId, methodName) {
1581
1661
  if (typeof accountId !== 'string' || accountId.length === 0) {
1582
1662
  throw new Error(`AssetsController.${methodName}: accountId must be a non-empty string`);
@@ -1588,6 +1668,25 @@ async function _AssetsController_executeMiddlewares(params) {
1588
1668
  catch {
1589
1669
  throw new Error(`AssetsController.${methodName}: invalid CAIP-19 assetId "${assetId}"`);
1590
1670
  }
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
+ }
1591
1690
  }, _AssetsController_fetchMissingPricesWithoutCache = function _AssetsController_fetchMissingPricesWithoutCache(accounts, chainIds) {
1592
1691
  if (!__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this) || accounts.length === 0) {
1593
1692
  return;
@@ -1669,10 +1768,16 @@ async function _AssetsController_executeMiddlewares(params) {
1669
1768
  return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_resolveNativeAssetIds).call(this, __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getEnabledChainsForAccount).call(this, account));
1670
1769
  }, _AssetsController_getSlowPipelineChainIds = function _AssetsController_getSlowPipelineChainIds(chainIds, fastResponse) {
1671
1770
  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]));
1672
1774
  return chainIds.filter((chainId) => {
1673
1775
  if (fastResponse.errors?.[chainId]) {
1674
1776
  return true;
1675
1777
  }
1778
+ if (unprocessedCustomAssetChains.has(chainId)) {
1779
+ return true;
1780
+ }
1676
1781
  if (!accountsApiChains.has(chainId)) {
1677
1782
  return true;
1678
1783
  }
@@ -1812,9 +1917,9 @@ async function _AssetsController_executeMiddlewares(params) {
1812
1917
  for (const [accountId, accountBalances] of Object.entries(normalizedResponse.assetsBalance)) {
1813
1918
  const previousBalances = previousState.assetsBalance[accountId] ?? {};
1814
1919
  const customAssetIds = state.customAssets[accountId] ?? [];
1815
- const replaceCoveredChains = mode === 'full' ||
1816
- normalizedResponse.replaceCoveredChainBalances === true;
1817
- const effective = mergeAccountBalances(previousBalances, accountBalances, customAssetIds, replaceCoveredChains);
1920
+ const effective = mode === 'full'
1921
+ ? mergeAccountBalancesV6(previousBalances, accountBalances, normalizedResponse.unprocessedCustomAssets ?? [])
1922
+ : mergeAccountBalancesV5(previousBalances, accountBalances, customAssetIds, normalizedResponse.replaceCoveredChainBalances === true);
1818
1923
  // Ensure native tokens have an entry (0 if missing) for chains this account supports
1819
1924
  const account = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((a) => a.id === accountId);
1820
1925
  const nativeAssetIdsForAccount = account
@@ -1871,10 +1976,8 @@ async function _AssetsController_executeMiddlewares(params) {
1871
1976
  changedPriceAssets.length > 0) {
1872
1977
  log('State updated', {
1873
1978
  changedBalances: changedBalances.length > 0 ? changedBalances : undefined,
1874
- changedMetadataCount: changedMetadata.length > 0 ? changedMetadata.length : undefined,
1875
- changedPricesCount: changedPriceAssets.length > 0
1876
- ? changedPriceAssets.length
1877
- : undefined,
1979
+ changedMetadata: changedMetadata.length > 0 ? changedMetadata : undefined,
1980
+ changedPrices: changedPriceAssets.length > 0 ? changedPriceAssets : undefined,
1878
1981
  newAssets: Object.keys(detectedAssets).length > 0
1879
1982
  ? Object.entries(detectedAssets).map(([accountId, assets]) => ({
1880
1983
  accountId,
@@ -2047,16 +2150,10 @@ async function _AssetsController_executeMiddlewares(params) {
2047
2150
  if (!subscriptionKey.startsWith('ds:')) {
2048
2151
  continue;
2049
2152
  }
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.
2153
+ // Subscription keys take the form `ds:<SourceName>`.
2054
2154
  const [, sourceId] = subscriptionKey.split(':');
2055
2155
  const source = allSources.find((ds) => ds.getName() === sourceId);
2056
2156
  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.
2060
2157
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_unsubscribeBySubscriptionKey).call(this, source, subscriptionKey);
2061
2158
  }
2062
2159
  }
@@ -2074,12 +2171,15 @@ async function _AssetsController_executeMiddlewares(params) {
2074
2171
  // Subscribe to price updates for all assets held by selected accounts
2075
2172
  this.subscribeAssetsPrice(accounts, enabledChains);
2076
2173
  }, _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) {
2077
2180
  const chainToAccounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildChainToAccountsMap).call(this, accounts, new Set(chainIds));
2078
2181
  const remainingChains = new Set(chainToAccounts.keys());
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
2182
+ const balanceDataSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
2083
2183
  ? __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_allBalanceDataSources_get)
2084
2184
  : [__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")];
2085
2185
  let rpcAssignedChains = new Set();
@@ -2118,13 +2218,81 @@ async function _AssetsController_executeMiddlewares(params) {
2118
2218
  });
2119
2219
  }
2120
2220
  }
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.
2127
2221
  __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
+ }
2128
2296
  }, _AssetsController_subscribeRpcCustomAssetsSupplement = function _AssetsController_subscribeRpcCustomAssetsSupplement(accounts, chainToAccounts, rpcAssignedChains) {
2129
2297
  const rpc = __classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f");
2130
2298
  const supplementalKey = `ds:${rpc.getName()}:custom`;
@@ -2187,12 +2355,14 @@ async function _AssetsController_executeMiddlewares(params) {
2187
2355
  const subscriptionKey = options.subscriptionKey ?? `ds:${sourceId}`;
2188
2356
  const existingSubscription = __classPrivateFieldGet(this, _AssetsController_activeSubscriptions, "f").get(subscriptionKey);
2189
2357
  const isUpdate = existingSubscription !== undefined;
2358
+ const customAssets = options.customAssets ?? [];
2190
2359
  log('Subscribe to data source', {
2191
2360
  sourceId,
2192
2361
  subscriptionKey,
2193
2362
  isUpdate,
2194
2363
  accountCount: accounts.length,
2195
2364
  chainCount: chains.length,
2365
+ customAssetCount: customAssets.length,
2196
2366
  customAssetsOnly: options.customAssetsOnly === true,
2197
2367
  skipInitialFetch: options.skipInitialFetch === true,
2198
2368
  });
@@ -2201,6 +2371,10 @@ async function _AssetsController_executeMiddlewares(params) {
2201
2371
  assetTypes: ['fungible'],
2202
2372
  dataTypes: ['balance'],
2203
2373
  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,
2204
2378
  ...(options.customAssetsOnly === true
2205
2379
  ? { customAssetsOnly: true }
2206
2380
  : {}),
@@ -2364,13 +2538,13 @@ async function _AssetsController_handleAccountGroupChanged(groupId, previousGrou
2364
2538
  // The data will simply not be updated until the network is re-enabled.
2365
2539
  // Refresh subscriptions for new chain set
2366
2540
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
2367
- // Do one-time fetch for newly enabled chains; merge so we keep existing chain balances
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.
2368
2543
  const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this);
2369
2544
  if (addedChains.length > 0 && accounts.length > 0) {
2370
2545
  await this.getAssets(accounts, {
2371
2546
  chainIds: addedChains,
2372
2547
  forceUpdate: true,
2373
- updateMode: 'merge',
2374
2548
  });
2375
2549
  }
2376
2550
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
@@ -2493,5 +2667,150 @@ async function _AssetsController_refreshAssetsAfterNetworkAdded(hexChainId) {
2493
2667
  });
2494
2668
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
2495
2669
  __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
+ });
2496
2815
  };
2497
2816
  //# sourceMappingURL=AssetsController.mjs.map