@metamask-previews/assets-controller 15.0.0-preview-d8fceeabc → 15.0.0-preview-b123e43e2

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 +9 -1
  2. package/dist/AssetsController.cjs +631 -275
  3. package/dist/AssetsController.cjs.map +1 -1
  4. package/dist/AssetsController.d.cts +7 -3
  5. package/dist/AssetsController.d.cts.map +1 -1
  6. package/dist/AssetsController.d.mts +7 -3
  7. package/dist/AssetsController.d.mts.map +1 -1
  8. package/dist/AssetsController.mjs +632 -276
  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 +143 -22
  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 +144 -23
  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/types.cjs.map +1 -1
  69. package/dist/types.d.cts +28 -18
  70. package/dist/types.d.cts.map +1 -1
  71. package/dist/types.d.mts +28 -18
  72. package/dist/types.d.mts.map +1 -1
  73. package/dist/types.mjs.map +1 -1
  74. package/package.json +2 -2
@@ -13,7 +13,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
13
13
  var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
15
  };
16
- var _AssetsController_instances, _AssetsController_isEnabled, _AssetsController_isBasicFunctionality, _AssetsController_defaultUpdateInterval, _AssetsController_trace, _AssetsController_captureException, _AssetsController_firstInitFetchReported, _AssetsController_stateSizeReported, _AssetsController_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;
16
+ 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_getVisibleCustomAssets, _AssetsController_isBalanceV6Enabled, _AssetsController_fetchMissingPricesWithoutCache, _AssetsController_getNativeAssetMap, _AssetsController_isNativeAsset, _AssetsController_getAssetType, _AssetsController_resolveNativeAssetIds, _AssetsController_getNativeAssetIdsForEnabledChains, _AssetsController_getNativeAssetIdsForAccount, _AssetsController_getDefaultTrackedAssetIdsForAccount, _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;
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.AssetsController = exports.getDefaultAssetsControllerState = void 0;
19
19
  const base_controller_1 = require("@metamask/base-controller");
@@ -208,6 +208,10 @@ function normalizeResponse(response) {
208
208
  if (response.replaceCoveredChainBalances) {
209
209
  normalized.replaceCoveredChainBalances = true;
210
210
  }
211
+ if (response.unprocessedCustomAssets &&
212
+ response.unprocessedCustomAssets.length > 0) {
213
+ normalized.unprocessedCustomAssets = response.unprocessedCustomAssets.map((assetId) => (0, index_js_2.normalizeAssetId)(assetId));
214
+ }
211
215
  return normalized;
212
216
  }
213
217
  /**
@@ -215,12 +219,13 @@ function normalizeResponse(response) {
215
219
  *
216
220
  * @param previousBalances - Balances already in state for this account.
217
221
  * @param accountBalances - Balances from the incoming response.
218
- * @param customAssetIds - Custom assets to preserve when replacing covered chains.
219
- * @param replaceCoveredChains - When true, drop prior balances on chains present
220
- * in the response before applying it (authoritative chain slice).
222
+ * @param customAssetIds - Custom assets to preserve when replacing covered chains
223
+ * on the Accounts API v5 path (`replaceCoveredChainBalances`).
224
+ * @param replaceCoveredChains - When true (v5 force refresh), drop prior balances
225
+ * on chains present in the response before applying it, then restore custom assets.
221
226
  * @returns The merged balance map for the account.
222
227
  */
223
- function mergeAccountBalances(previousBalances, accountBalances, customAssetIds, replaceCoveredChains) {
228
+ function mergeAccountBalancesV5(previousBalances, accountBalances, customAssetIds = [], replaceCoveredChains = false) {
224
229
  if (!replaceCoveredChains) {
225
230
  return { ...previousBalances, ...accountBalances };
226
231
  }
@@ -234,8 +239,8 @@ function mergeAccountBalances(previousBalances, accountBalances, customAssetIds,
234
239
  Object.assign(next, accountBalances);
235
240
  for (const customId of customAssetIds) {
236
241
  if (!Object.prototype.hasOwnProperty.call(next, customId)) {
237
- const prev = previousBalances[customId];
238
- next[customId] = prev ?? { amount: '0' };
242
+ const previous = previousBalances[customId];
243
+ next[customId] = previous ?? { amount: '0' };
239
244
  }
240
245
  }
241
246
  // Staked vault balances are owned by StakedBalanceDataSource. When an
@@ -249,6 +254,38 @@ function mergeAccountBalances(previousBalances, accountBalances, customAssetIds,
249
254
  }
250
255
  return next;
251
256
  }
257
+ /**
258
+ * Apply an Accounts API v6 authoritative chain snapshot.
259
+ *
260
+ * @param previousBalances - Balances already in state for this account.
261
+ * @param accountBalances - Balances from the incoming response.
262
+ * @param unprocessedCustomAssets - Pins that v6 and RPC could not resolve.
263
+ * @returns The merged balance map for the account.
264
+ */
265
+ function mergeAccountBalancesV6(previousBalances, accountBalances, unprocessedCustomAssets = []) {
266
+ const coveredChains = new Set(Object.keys(accountBalances).map((assetId) => assetId.split('/')[0]));
267
+ const next = {};
268
+ for (const [assetId, balance] of Object.entries(previousBalances)) {
269
+ if (!coveredChains.has(assetId.split('/')[0])) {
270
+ next[assetId] = balance;
271
+ }
272
+ }
273
+ Object.assign(next, accountBalances);
274
+ const unprocessedSet = new Set(unprocessedCustomAssets.map((assetId) => (0, index_js_2.normalizeAssetId)(assetId)));
275
+ for (const [assetId, balance] of Object.entries(previousBalances)) {
276
+ if (unprocessedSet.has((0, index_js_2.normalizeAssetId)(assetId)) &&
277
+ !Object.prototype.hasOwnProperty.call(next, assetId)) {
278
+ next[assetId] = balance;
279
+ }
280
+ }
281
+ for (const [assetId, balance] of Object.entries(previousBalances)) {
282
+ if ((0, index_js_1.isStakingContractAssetId)(assetId) &&
283
+ !Object.prototype.hasOwnProperty.call(next, assetId)) {
284
+ next[assetId] = balance;
285
+ }
286
+ }
287
+ return next;
288
+ }
252
289
  // ============================================================================
253
290
  // CONTROLLER IMPLEMENTATION
254
291
  // ============================================================================
@@ -369,6 +406,7 @@ class AssetsController extends base_controller_1.BaseController {
369
406
  queryApiClient,
370
407
  onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
371
408
  ...accountsApiDataSourceConfig,
409
+ isBalanceV6Enabled: () => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_isBalanceV6Enabled).call(this),
372
410
  }), "f");
373
411
  __classPrivateFieldSet(this, _AssetsController_snapDataSource, new SnapDataSource_js_1.SnapDataSource({
374
412
  messenger: this.messenger,
@@ -388,6 +426,7 @@ class AssetsController extends base_controller_1.BaseController {
388
426
  ...rpcConfig,
389
427
  isOnboarded: rpcConfig.isOnboarded ?? isOnboarded,
390
428
  getAssetType: (assetId) => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetType).call(this, assetId),
429
+ isBalanceV6Enabled: () => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_isBalanceV6Enabled).call(this),
391
430
  }), "f");
392
431
  __classPrivateFieldSet(this, _AssetsController_stakedBalanceDataSource, new StakedBalanceDataSource_js_1.StakedBalanceDataSource({
393
432
  messenger: this.messenger,
@@ -420,6 +459,7 @@ class AssetsController extends base_controller_1.BaseController {
420
459
  }), "f");
421
460
  __classPrivateFieldSet(this, _AssetsController_rpcFallbackMiddleware, new RpcFallbackMiddleware_js_1.RpcFallbackMiddleware({
422
461
  rpcDataSource: __classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f"),
462
+ isBalanceV6Enabled: () => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_isBalanceV6Enabled).call(this),
423
463
  }), "f");
424
464
  log('Initializing AssetsController', {
425
465
  defaultUpdateInterval: __classPrivateFieldGet(this, _AssetsController_defaultUpdateInterval, "f"),
@@ -456,147 +496,35 @@ class AssetsController extends base_controller_1.BaseController {
456
496
  if (accounts.length === 0 || chainIds.length === 0) {
457
497
  return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetsFromState).call(this, accounts, chainIds, assetTypes);
458
498
  }
459
- // Collect custom assets for all requested accounts
460
- const customAssets = [];
461
- for (const account of accounts) {
462
- const accountCustomAssets = this.getCustomAssets(account.id);
463
- customAssets.push(...accountCustomAssets);
464
- }
465
499
  if (options?.forceUpdate) {
466
- // Pipeline spans only on unlock/first-init fetch; later forceUpdates pass
467
- // `undefined` so `emitTrace` / `withTrace` no-op without call-site if/else.
468
500
  const pipelineTrace = __classPrivateFieldGet(this, _AssetsController_firstInitFetchReported, "f")
469
501
  ? undefined
470
502
  : __classPrivateFieldGet(this, _AssetsController_trace, "f");
471
- const request = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildDataRequest).call(this, accounts, chainIds, {
503
+ const requestOptions = {
472
504
  assetTypes,
473
505
  dataTypes,
474
- customAssets: customAssets.length > 0 ? customAssets : undefined,
475
506
  forceUpdate: true,
476
507
  bypassServerCache: options?.bypassServerCache,
477
508
  assetsForPriceUpdate: options?.assetsForPriceUpdate,
478
- });
479
- // Fast pipeline: accountsApi + stakedBalance → detection → token + price.
480
- // Snap and RPC are excluded here due to their latency (snap triggers account
481
- // creation, RPC is slow on many chains). Results are committed to state
482
- // immediately so the UI can display balances without waiting for them.
483
- //
484
- // Fast/slow pipelines use merge so partial API snapshots cannot wipe
485
- // tokens missing from the response (e.g. USDC when only native balance
486
- // is returned). Balances present in the response are still refreshed.
487
- const fastSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
488
- ? [
489
- (0, ParallelMiddleware_js_1.createParallelBalanceMiddleware)([
490
- __classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f"),
491
- __classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"),
492
- ]),
493
- // Graduation must run BEFORE the RPC fallback so it only sees
494
- // AccountsApi/Websocket balances. RPC intentionally carries
495
- // custom assets and must never trigger graduation.
496
- __classPrivateFieldGet(this, _AssetsController_customAssetGraduationMiddleware, "f"),
497
- __classPrivateFieldGet(this, _AssetsController_rpcFallbackMiddleware, "f"),
498
- __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
499
- (0, ParallelMiddleware_js_1.createParallelMiddleware)([
500
- __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
501
- __classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
502
- ]),
503
- ]
504
- : [__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f")];
505
- const { response } = await (0, trace_js_1.withTrace)({
506
- name: TRACE_FETCH_PIPELINE,
507
- trace: pipelineTrace,
508
- data: {
509
- chain_count: chainIds.length,
510
- account_count: accounts.length,
511
- basic_functionality: __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this),
512
- },
513
- fn: async (parentContext) => {
514
- const startTime = performance.now();
515
- const result = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, {
516
- sources: fastSources,
517
- request,
518
- parentContext,
519
- trace: pipelineTrace,
520
- });
521
- await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
522
- ...result.response,
523
- updateMode: 'merge',
524
- replaceCoveredChainBalances: true,
525
- });
526
- const durationMs = performance.now() - startTime;
527
- // Summary fields for Assets Health (nested under the parent span).
528
- (0, trace_js_1.emitTrace)({
529
- name: TRACE_FULL_FETCH,
530
- trace: pipelineTrace,
531
- data: {
532
- duration_ms: durationMs,
533
- chain_count: chainIds.length,
534
- account_count: accounts.length,
535
- basic_functionality: __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this),
536
- asset_count: result.response.assetsBalance
537
- ? Object.values(result.response.assetsBalance).reduce((sum, acct) => sum + Object.keys(acct).length, 0)
538
- : 0,
539
- price_count: result.response.assetsPrice
540
- ? Object.keys(result.response.assetsPrice).length
541
- : 0,
542
- ...result.durationByDataSource,
543
- },
544
- parentContext,
545
- });
546
- (0, trace_js_1.emitTrace)({
547
- name: TRACE_FIRST_INIT_FETCH,
548
- trace: pipelineTrace,
549
- data: {
550
- duration_ms: durationMs,
551
- chain_ids: JSON.stringify(chainIds),
552
- ...result.durationByDataSource,
553
- },
554
- parentContext,
555
- });
556
- return result;
557
- },
558
- });
559
- // Mark after the unlock/first forceUpdate so later polls skip pipeline spans.
560
- __classPrivateFieldSet(this, _AssetsController_firstInitFetchReported, true, "f");
561
- // Background (slow) lane — flattened sibling of the fast lane (not nested
562
- // inside its withTrace callback). Still fire-and-forget so UI is not blocked.
563
- const slowPipelineChainIds = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSlowPipelineChainIds).call(this, chainIds, response);
564
- if (slowPipelineChainIds.length > 0) {
565
- const slowSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
566
- ? [__classPrivateFieldGet(this, _AssetsController_snapDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")]
567
- : [__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")];
568
- const slowRequest = { ...request, chainIds: slowPipelineChainIds };
569
- (0, trace_js_1.withTrace)({
570
- name: TRACE_BACKGROUND_FETCH,
571
- trace: pipelineTrace,
572
- data: {
573
- chain_count: slowPipelineChainIds.length,
574
- account_count: accounts.length,
575
- },
576
- fn: async (slowParentContext) => {
577
- const { response: slowResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, {
578
- sources: [
579
- (0, ParallelMiddleware_js_1.createParallelBalanceMiddleware)(slowSources),
580
- __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
581
- ...(__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
582
- ? [
583
- (0, ParallelMiddleware_js_1.createParallelMiddleware)([
584
- __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
585
- __classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
586
- ]),
587
- ]
588
- : []),
589
- ],
590
- request: slowRequest,
591
- parentContext: slowParentContext,
592
- trace: pipelineTrace,
593
- });
594
- await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
595
- ...slowResponse,
596
- updateMode: 'merge',
597
- });
598
- },
599
- }).catch((error) => log('Background pipeline failed', { error }));
509
+ };
510
+ if (__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_isBalanceV6Enabled).call(this)) {
511
+ await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_forceUpdateAssetsV6).call(this, {
512
+ accounts,
513
+ chainIds,
514
+ request: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildForceUpdateRequestV6).call(this, accounts, chainIds, {
515
+ ...requestOptions,
516
+ customAssetsOverride: options?.customAssets,
517
+ }),
518
+ pipelineTrace,
519
+ });
520
+ }
521
+ else {
522
+ await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_forceUpdateAssetsV5).call(this, {
523
+ accounts,
524
+ chainIds,
525
+ request: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildForceUpdateRequestV5).call(this, accounts, chainIds, requestOptions),
526
+ pipelineTrace,
527
+ });
600
528
  }
601
529
  }
602
530
  const result = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetsFromState).call(this, accounts, chainIds, assetTypes);
@@ -843,20 +771,28 @@ class AssetsController extends base_controller_1.BaseController {
843
771
  balances[accountId] ?? (balances[accountId] = {});
844
772
  (_a = balances[accountId])[normalizedAssetId] ?? (_a[normalizedAssetId] = { amount: '0' });
845
773
  });
846
- // Fetch data for the newly added custom asset (merge to preserve other chains)
847
774
  const account = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((a) => a.id === accountId);
848
775
  if (account) {
849
776
  const chainId = extractChainId(normalizedAssetId);
850
- await this.getAssets([account], {
851
- chainIds: [chainId],
852
- dataTypes: ['balance', 'metadata', 'price'],
853
- assetTypes: ['fungible'],
854
- forceUpdate: true,
855
- updateMode: 'merge',
856
- });
777
+ if (__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_isBalanceV6Enabled).call(this)) {
778
+ await this.getAssets([account], {
779
+ chainIds: [chainId],
780
+ dataTypes: ['balance', 'metadata', 'price'],
781
+ assetTypes: ['fungible'],
782
+ forceUpdate: true,
783
+ customAssets: [normalizedAssetId],
784
+ });
785
+ }
786
+ else {
787
+ await this.getAssets([account], {
788
+ chainIds: [chainId],
789
+ dataTypes: ['balance', 'metadata', 'price'],
790
+ assetTypes: ['fungible'],
791
+ forceUpdate: true,
792
+ });
793
+ }
857
794
  }
858
- // Re-evaluate subscriptions so the supplemental RPC poll picks up the
859
- // new customAsset on chains another data source already owns.
795
+ // Re-evaluate subscriptions so polls pick up the new pin.
860
796
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
861
797
  }
862
798
  /**
@@ -877,8 +813,7 @@ class AssetsController extends base_controller_1.BaseController {
877
813
  }
878
814
  }
879
815
  });
880
- // Re-evaluate subscriptions so the supplemental RPC poll for that chain
881
- // is torn down when no more customAssets remain there.
816
+ // Re-evaluate subscriptions so polls drop the removed pin.
882
817
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
883
818
  }
884
819
  /**
@@ -909,6 +844,8 @@ class AssetsController extends base_controller_1.BaseController {
909
844
  }
910
845
  state.assetPreferences[normalizedAssetId].hidden = true;
911
846
  });
847
+ // Re-evaluate subscriptions so polls exclude the newly hidden asset.
848
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
912
849
  }
913
850
  /**
914
851
  * Unhide an asset globally.
@@ -927,6 +864,8 @@ class AssetsController extends base_controller_1.BaseController {
927
864
  }
928
865
  }
929
866
  });
867
+ // Re-evaluate subscriptions so polls stop excluding the asset.
868
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
930
869
  }
931
870
  // ============================================================================
932
871
  // CURRENT CURRENCY MANAGEMENT
@@ -1038,101 +977,14 @@ class AssetsController extends base_controller_1.BaseController {
1038
977
  async handleAssetsUpdate(response, sourceId, request) {
1039
978
  log('Assets updated from data source', {
1040
979
  sourceId,
1041
- hasBalance: Boolean(response.assetsBalance),
1042
- hasPrice: Boolean(response.assetsPrice),
1043
- });
1044
- // Enrichment spans only before unlock/first-init fetch completes.
1045
- const pipelineTrace = __classPrivateFieldGet(this, _AssetsController_firstInitFetchReported, "f")
1046
- ? undefined
1047
- : __classPrivateFieldGet(this, _AssetsController_trace, "f");
1048
- await (0, trace_js_1.withTrace)({
1049
- name: TRACE_UPDATE_PARENT,
1050
- trace: pipelineTrace,
1051
- data: {
1052
- source: sourceId,
1053
- has_balance: Boolean(response.assetsBalance),
1054
- has_price: Boolean(response.assetsPrice),
1055
- balance_account_count: response.assetsBalance
1056
- ? Object.keys(response.assetsBalance).length
1057
- : 0,
1058
- },
1059
- fn: async (parentContext) => {
1060
- const updateStart = performance.now();
1061
- const resolvedRequest = request ?? {
1062
- accountsWithSupportedChains: [],
1063
- chainIds: [],
1064
- dataTypes: ['balance', 'metadata', 'price'],
1065
- };
1066
- // RPC-only mode (basic functionality off): never run token/price APIs. Strip
1067
- // those data types so downstream middleware cannot treat them as requested.
1068
- const pipelineRequest = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
1069
- ? resolvedRequest
1070
- : {
1071
- ...resolvedRequest,
1072
- dataTypes: resolvedRequest.dataTypes.filter((dt) => dt !== 'metadata' && dt !== 'price'),
1073
- };
1074
- // Graduate custom assets only when AccountsAPI / AccountActivity reports
1075
- // them. RPC already fetches custom assets on purpose, and Snap handles
1076
- // non-EVM chains the rule does not apply to, so skip the middleware for
1077
- // those.
1078
- const shouldGraduateCustomAssets = sourceId === 'AccountsApiDataSource' ||
1079
- sourceId === 'AccountActivityDataSource';
1080
- // Websocket updates can carry brand-new spam airdrops: enrich them
1081
- // with Token API occurrences and drop below-floor tokens BEFORE
1082
- // detection, so spam is never detected, enriched, priced or persisted.
1083
- const shouldFilterOccurrences = sourceId === 'AccountActivityDataSource' &&
1084
- __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this);
1085
- const shouldRunRpcFallback = sourceId === 'AccountsApiDataSource';
1086
- const enrichmentSources = [
1087
- ...(shouldGraduateCustomAssets
1088
- ? [__classPrivateFieldGet(this, _AssetsController_customAssetGraduationMiddleware, "f")]
1089
- : []),
1090
- ...(shouldFilterOccurrences
1091
- ? [
1092
- {
1093
- getName: () => 'OccurrenceFloorFilter',
1094
- assetsMiddleware: __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f").occurrenceFilterMiddleware,
1095
- },
1096
- ]
1097
- : []),
1098
- ...(shouldRunRpcFallback ? [__classPrivateFieldGet(this, _AssetsController_rpcFallbackMiddleware, "f")] : []),
1099
- __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
1100
- ];
1101
- if (__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)) {
1102
- enrichmentSources.push((0, ParallelMiddleware_js_1.createParallelMiddleware)([
1103
- __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
1104
- __classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
1105
- ]));
1106
- }
1107
- const { response: enrichedResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, {
1108
- sources: enrichmentSources,
1109
- request: pipelineRequest,
1110
- initialResponse: response,
1111
- parentContext,
1112
- trace: pipelineTrace,
1113
- });
1114
- await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
1115
- ...enrichedResponse,
1116
- replaceCoveredChainBalances: response.replaceCoveredChainBalances,
1117
- });
1118
- // Summary fields for Assets Health (nested under the parent span).
1119
- (0, trace_js_1.emitTrace)({
1120
- name: TRACE_UPDATE_PIPELINE,
1121
- trace: pipelineTrace,
1122
- data: {
1123
- source: sourceId,
1124
- duration_ms: performance.now() - updateStart,
1125
- has_balance: Boolean(response.assetsBalance),
1126
- has_price: Boolean(response.assetsPrice),
1127
- has_metadata: Boolean(enrichedResponse.assetsInfo),
1128
- balance_account_count: response.assetsBalance
1129
- ? Object.keys(response.assetsBalance).length
1130
- : 0,
1131
- },
1132
- parentContext,
1133
- });
1134
- },
980
+ assetsBalance: response.assetsBalance,
981
+ assetsPrice: response.assetsPrice,
1135
982
  });
983
+ if (__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_isBalanceV6Enabled).call(this)) {
984
+ await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleAssetsUpdateV6).call(this, response, sourceId, request);
985
+ return;
986
+ }
987
+ await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleAssetsUpdateV5).call(this, response, sourceId, request);
1136
988
  }
1137
989
  // ============================================================================
1138
990
  // CLEANUP
@@ -1584,6 +1436,239 @@ async function _AssetsController_executeMiddlewares(params) {
1584
1436
  });
1585
1437
  }
1586
1438
  return { response: result.response, durationByDataSource };
1439
+ }, _AssetsController_buildForceUpdateRequestV5 = function _AssetsController_buildForceUpdateRequestV5(accounts, chainIds, requestOptions) {
1440
+ const customAssets = [];
1441
+ for (const account of accounts) {
1442
+ customAssets.push(...__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getVisibleCustomAssets).call(this, account.id));
1443
+ }
1444
+ return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildDataRequest).call(this, accounts, chainIds, {
1445
+ ...requestOptions,
1446
+ customAssets: customAssets.length > 0 ? customAssets : undefined,
1447
+ });
1448
+ }, _AssetsController_buildForceUpdateRequestV6 = function _AssetsController_buildForceUpdateRequestV6(accounts, chainIds, requestOptions) {
1449
+ const requestedChains = new Set(chainIds);
1450
+ const candidateCustomAssets = requestOptions.customAssetsOverride ??
1451
+ accounts.flatMap((account) => this.getCustomAssets(account.id));
1452
+ const customAssetsSet = new Set();
1453
+ for (const assetId of candidateCustomAssets) {
1454
+ try {
1455
+ const normalizedAssetId = (0, index_js_2.normalizeAssetId)(assetId);
1456
+ if (requestedChains.has((0, utils_1.parseCaipAssetType)(normalizedAssetId).chainId) &&
1457
+ !this.state.assetPreferences[normalizedAssetId]?.hidden) {
1458
+ customAssetsSet.add(normalizedAssetId);
1459
+ }
1460
+ }
1461
+ catch {
1462
+ // Skip unparseable asset IDs
1463
+ }
1464
+ }
1465
+ const customAssets = [...customAssetsSet];
1466
+ const hiddenAssets = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getHiddenAssetIds).call(this);
1467
+ return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildDataRequest).call(this, accounts, chainIds, {
1468
+ assetTypes: requestOptions.assetTypes,
1469
+ dataTypes: requestOptions.dataTypes,
1470
+ forceUpdate: requestOptions.forceUpdate,
1471
+ bypassServerCache: requestOptions.bypassServerCache,
1472
+ assetsForPriceUpdate: requestOptions.assetsForPriceUpdate,
1473
+ customAssets: customAssets.length > 0 ? customAssets : undefined,
1474
+ excludeAssetIds: hiddenAssets.length > 0 ? hiddenAssets : undefined,
1475
+ });
1476
+ }, _AssetsController_forceUpdateAssetsV5 = async function _AssetsController_forceUpdateAssetsV5({ accounts, chainIds, request, pipelineTrace, }) {
1477
+ const isBasicFunctionality = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this);
1478
+ const fastSources = isBasicFunctionality
1479
+ ? [
1480
+ (0, ParallelMiddleware_js_1.createParallelBalanceMiddleware)([
1481
+ __classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f"),
1482
+ __classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"),
1483
+ ]),
1484
+ __classPrivateFieldGet(this, _AssetsController_customAssetGraduationMiddleware, "f"),
1485
+ __classPrivateFieldGet(this, _AssetsController_rpcFallbackMiddleware, "f"),
1486
+ __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
1487
+ (0, ParallelMiddleware_js_1.createParallelMiddleware)([
1488
+ __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
1489
+ __classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
1490
+ ]),
1491
+ ]
1492
+ : [__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f")];
1493
+ const fastResponse = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_runFastFetchV5).call(this, {
1494
+ accounts,
1495
+ chainIds,
1496
+ request,
1497
+ pipelineTrace,
1498
+ fastSources,
1499
+ isBasicFunctionality,
1500
+ });
1501
+ __classPrivateFieldSet(this, _AssetsController_firstInitFetchReported, true, "f");
1502
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_runBackgroundFetch).call(this, {
1503
+ accounts,
1504
+ request,
1505
+ pipelineTrace,
1506
+ chainIds: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSlowPipelineChainIds).call(this, chainIds, fastResponse),
1507
+ isBasicFunctionality,
1508
+ });
1509
+ }, _AssetsController_forceUpdateAssetsV6 = async function _AssetsController_forceUpdateAssetsV6({ accounts, chainIds, request, pipelineTrace, }) {
1510
+ const isBasicFunctionality = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this);
1511
+ const fastSources = isBasicFunctionality
1512
+ ? [
1513
+ (0, ParallelMiddleware_js_1.createParallelBalanceMiddleware)([
1514
+ __classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f"),
1515
+ __classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"),
1516
+ ]),
1517
+ __classPrivateFieldGet(this, _AssetsController_rpcFallbackMiddleware, "f"),
1518
+ __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
1519
+ (0, ParallelMiddleware_js_1.createParallelMiddleware)([
1520
+ __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
1521
+ __classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
1522
+ ]),
1523
+ ]
1524
+ : [__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f")];
1525
+ const fastResponse = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_runFastFetchV6).call(this, {
1526
+ accounts,
1527
+ chainIds,
1528
+ request,
1529
+ pipelineTrace,
1530
+ fastSources,
1531
+ isBasicFunctionality,
1532
+ });
1533
+ __classPrivateFieldSet(this, _AssetsController_firstInitFetchReported, true, "f");
1534
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_runBackgroundFetch).call(this, {
1535
+ accounts,
1536
+ request,
1537
+ pipelineTrace,
1538
+ chainIds: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSlowPipelineChainIds).call(this, chainIds, fastResponse),
1539
+ isBasicFunctionality,
1540
+ });
1541
+ }, _AssetsController_runFastFetchV5 = async function _AssetsController_runFastFetchV5({ accounts, chainIds, request, pipelineTrace, fastSources, isBasicFunctionality, }) {
1542
+ const { response } = await (0, trace_js_1.withTrace)({
1543
+ name: TRACE_FETCH_PIPELINE,
1544
+ trace: pipelineTrace,
1545
+ data: {
1546
+ chain_count: chainIds.length,
1547
+ account_count: accounts.length,
1548
+ basic_functionality: isBasicFunctionality,
1549
+ },
1550
+ fn: async (parentContext) => {
1551
+ const startTime = performance.now();
1552
+ const result = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, {
1553
+ sources: fastSources,
1554
+ request,
1555
+ parentContext,
1556
+ trace: pipelineTrace,
1557
+ });
1558
+ await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
1559
+ ...result.response,
1560
+ updateMode: 'merge',
1561
+ replaceCoveredChainBalances: true,
1562
+ });
1563
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitFastFetchTraces).call(this, {
1564
+ accounts,
1565
+ chainIds,
1566
+ result,
1567
+ durationMs: performance.now() - startTime,
1568
+ isBasicFunctionality,
1569
+ parentContext,
1570
+ pipelineTrace,
1571
+ });
1572
+ return result;
1573
+ },
1574
+ });
1575
+ return response;
1576
+ }, _AssetsController_runFastFetchV6 = async function _AssetsController_runFastFetchV6({ accounts, chainIds, request, pipelineTrace, fastSources, isBasicFunctionality, }) {
1577
+ const { response } = await (0, trace_js_1.withTrace)({
1578
+ name: TRACE_FETCH_PIPELINE,
1579
+ trace: pipelineTrace,
1580
+ data: {
1581
+ chain_count: chainIds.length,
1582
+ account_count: accounts.length,
1583
+ basic_functionality: isBasicFunctionality,
1584
+ },
1585
+ fn: async (parentContext) => {
1586
+ const startTime = performance.now();
1587
+ const result = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, {
1588
+ sources: fastSources,
1589
+ request,
1590
+ parentContext,
1591
+ trace: pipelineTrace,
1592
+ });
1593
+ await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, result.response);
1594
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitFastFetchTraces).call(this, {
1595
+ accounts,
1596
+ chainIds,
1597
+ result,
1598
+ durationMs: performance.now() - startTime,
1599
+ isBasicFunctionality,
1600
+ parentContext,
1601
+ pipelineTrace,
1602
+ });
1603
+ return result;
1604
+ },
1605
+ });
1606
+ return response;
1607
+ }, _AssetsController_runBackgroundFetch = function _AssetsController_runBackgroundFetch({ accounts, chainIds, request, pipelineTrace, isBasicFunctionality, }) {
1608
+ if (chainIds.length === 0) {
1609
+ return;
1610
+ }
1611
+ const slowSources = isBasicFunctionality
1612
+ ? [__classPrivateFieldGet(this, _AssetsController_snapDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")]
1613
+ : [__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")];
1614
+ const slowRequest = { ...request, chainIds };
1615
+ (0, trace_js_1.withTrace)({
1616
+ name: TRACE_BACKGROUND_FETCH,
1617
+ trace: pipelineTrace,
1618
+ data: {
1619
+ chain_count: chainIds.length,
1620
+ account_count: accounts.length,
1621
+ },
1622
+ fn: async (parentContext) => {
1623
+ const { response } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, {
1624
+ sources: [
1625
+ (0, ParallelMiddleware_js_1.createParallelBalanceMiddleware)(slowSources),
1626
+ __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
1627
+ ...(isBasicFunctionality
1628
+ ? [
1629
+ (0, ParallelMiddleware_js_1.createParallelMiddleware)([
1630
+ __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
1631
+ __classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
1632
+ ]),
1633
+ ]
1634
+ : []),
1635
+ ],
1636
+ request: slowRequest,
1637
+ parentContext,
1638
+ trace: pipelineTrace,
1639
+ });
1640
+ await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, { ...response, updateMode: 'merge' });
1641
+ },
1642
+ }).catch((error) => log('Background pipeline failed', { error }));
1643
+ }, _AssetsController_emitFastFetchTraces = function _AssetsController_emitFastFetchTraces({ accounts, chainIds, result, durationMs, isBasicFunctionality, parentContext, pipelineTrace, }) {
1644
+ (0, trace_js_1.emitTrace)({
1645
+ name: TRACE_FULL_FETCH,
1646
+ trace: pipelineTrace,
1647
+ data: {
1648
+ duration_ms: durationMs,
1649
+ chain_count: chainIds.length,
1650
+ account_count: accounts.length,
1651
+ basic_functionality: isBasicFunctionality,
1652
+ asset_count: result.response.assetsBalance
1653
+ ? Object.values(result.response.assetsBalance).reduce((sum, account) => sum + Object.keys(account).length, 0)
1654
+ : 0,
1655
+ price_count: result.response.assetsPrice
1656
+ ? Object.keys(result.response.assetsPrice).length
1657
+ : 0,
1658
+ ...result.durationByDataSource,
1659
+ },
1660
+ parentContext,
1661
+ });
1662
+ (0, trace_js_1.emitTrace)({
1663
+ name: TRACE_FIRST_INIT_FETCH,
1664
+ trace: pipelineTrace,
1665
+ data: {
1666
+ duration_ms: durationMs,
1667
+ chain_ids: JSON.stringify(chainIds),
1668
+ ...result.durationByDataSource,
1669
+ },
1670
+ parentContext,
1671
+ });
1587
1672
  }, _AssetsController_assertNonEmptyAccountId = function _AssetsController_assertNonEmptyAccountId(accountId, methodName) {
1588
1673
  if (typeof accountId !== 'string' || accountId.length === 0) {
1589
1674
  throw new Error(`AssetsController.${methodName}: accountId must be a non-empty string`);
@@ -1595,6 +1680,27 @@ async function _AssetsController_executeMiddlewares(params) {
1595
1680
  catch {
1596
1681
  throw new Error(`AssetsController.${methodName}: invalid CAIP-19 assetId "${assetId}"`);
1597
1682
  }
1683
+ }, _AssetsController_getHiddenAssetIds = function _AssetsController_getHiddenAssetIds() {
1684
+ const hidden = [];
1685
+ for (const [assetId, prefs] of Object.entries(this.state.assetPreferences)) {
1686
+ if (prefs.hidden) {
1687
+ hidden.push(assetId);
1688
+ }
1689
+ }
1690
+ return hidden;
1691
+ }, _AssetsController_getVisibleCustomAssets = function _AssetsController_getVisibleCustomAssets(accountId) {
1692
+ return this.getCustomAssets(accountId).filter((assetId) => !this.state.assetPreferences[assetId]?.hidden);
1693
+ }, _AssetsController_isBalanceV6Enabled = function _AssetsController_isBalanceV6Enabled() {
1694
+ try {
1695
+ const { remoteFeatureFlags } = this.messenger.call('RemoteFeatureFlagController:getState');
1696
+ const flag = remoteFeatureFlags?.assetsAccountsApiV6;
1697
+ return (typeof flag === 'object' &&
1698
+ flag !== null &&
1699
+ Boolean(flag.value));
1700
+ }
1701
+ catch {
1702
+ return false;
1703
+ }
1598
1704
  }, _AssetsController_fetchMissingPricesWithoutCache = function _AssetsController_fetchMissingPricesWithoutCache(accounts, chainIds) {
1599
1705
  if (!__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this) || accounts.length === 0) {
1600
1706
  return;
@@ -1674,12 +1780,24 @@ async function _AssetsController_executeMiddlewares(params) {
1674
1780
  return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_resolveNativeAssetIds).call(this, __classPrivateFieldGet(this, _AssetsController_enabledChains, "f"));
1675
1781
  }, _AssetsController_getNativeAssetIdsForAccount = function _AssetsController_getNativeAssetIdsForAccount(account) {
1676
1782
  return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_resolveNativeAssetIds).call(this, __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getEnabledChainsForAccount).call(this, account));
1783
+ }, _AssetsController_getDefaultTrackedAssetIdsForAccount = function _AssetsController_getDefaultTrackedAssetIdsForAccount(account) {
1784
+ const ids = [];
1785
+ for (const chainId of __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getEnabledChainsForAccount).call(this, account)) {
1786
+ ids.push(...(0, defaults_js_1.getDefaultTrackedAssetsForChain)(chainId));
1787
+ }
1788
+ return ids;
1677
1789
  }, _AssetsController_getSlowPipelineChainIds = function _AssetsController_getSlowPipelineChainIds(chainIds, fastResponse) {
1678
1790
  const accountsApiChains = new Set(__classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f").getActiveChainsSync());
1791
+ // Chains whose pins went unresolved (`unprocessedCustomAssets`): route
1792
+ // them to the slow pipeline so RPC fetches the pins.
1793
+ const unprocessedCustomAssetChains = new Set((fastResponse.unprocessedCustomAssets ?? []).map((assetId) => assetId.split('/')[0]));
1679
1794
  return chainIds.filter((chainId) => {
1680
1795
  if (fastResponse.errors?.[chainId]) {
1681
1796
  return true;
1682
1797
  }
1798
+ if (unprocessedCustomAssetChains.has(chainId)) {
1799
+ return true;
1800
+ }
1683
1801
  if (!accountsApiChains.has(chainId)) {
1684
1802
  return true;
1685
1803
  }
@@ -1819,9 +1937,9 @@ async function _AssetsController_executeMiddlewares(params) {
1819
1937
  for (const [accountId, accountBalances] of Object.entries(normalizedResponse.assetsBalance)) {
1820
1938
  const previousBalances = previousState.assetsBalance[accountId] ?? {};
1821
1939
  const customAssetIds = state.customAssets[accountId] ?? [];
1822
- const replaceCoveredChains = mode === 'full' ||
1823
- normalizedResponse.replaceCoveredChainBalances === true;
1824
- const effective = mergeAccountBalances(previousBalances, accountBalances, customAssetIds, replaceCoveredChains);
1940
+ const effective = mode === 'full'
1941
+ ? mergeAccountBalancesV6(previousBalances, accountBalances, normalizedResponse.unprocessedCustomAssets ?? [])
1942
+ : mergeAccountBalancesV5(previousBalances, accountBalances, customAssetIds, normalizedResponse.replaceCoveredChainBalances === true);
1825
1943
  // Ensure native tokens have an entry (0 if missing) for chains this account supports
1826
1944
  const account = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((a) => a.id === accountId);
1827
1945
  const nativeAssetIdsForAccount = account
@@ -1832,6 +1950,19 @@ async function _AssetsController_executeMiddlewares(params) {
1832
1950
  effective[nativeAssetId] = { amount: '0' };
1833
1951
  }
1834
1952
  }
1953
+ // Default tracked assets (mUSD) are controller-managed and, like
1954
+ // natives, must render at zero balance. An authoritative
1955
+ // chain-slice replace omits them whenever the account holds none,
1956
+ // so re-assert them here — otherwise a force refresh (e.g. the
1957
+ // "Refresh list" action) would drop mUSD from the token list.
1958
+ const defaultTrackedAssetIdsForAccount = account
1959
+ ? __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getDefaultTrackedAssetIdsForAccount).call(this, account)
1960
+ : [];
1961
+ for (const defaultAssetId of defaultTrackedAssetIdsForAccount) {
1962
+ if (!Object.prototype.hasOwnProperty.call(effective, defaultAssetId)) {
1963
+ effective[defaultAssetId] = { amount: '0' };
1964
+ }
1965
+ }
1835
1966
  for (const [assetId, balance] of Object.entries(effective)) {
1836
1967
  const previousBalance = previousBalances[assetId];
1837
1968
  // Coerce amounts (e.g. "1e-18" from a data source stringifying
@@ -1845,10 +1976,11 @@ async function _AssetsController_executeMiddlewares(params) {
1845
1976
  const newAmount = (0, index_js_2.normalizeAmountString)(balance.amount, assetDecimals);
1846
1977
  effective[assetId] = { ...balance, amount: newAmount };
1847
1978
  const oldAmount = previousBalance?.amount;
1848
- const isNewDefaultNativeZero = oldAmount === undefined &&
1979
+ const isNewSeededZero = oldAmount === undefined &&
1849
1980
  newAmount === '0' &&
1850
- nativeAssetIdsForAccount.includes(assetId);
1851
- if (oldAmount !== newAmount && !isNewDefaultNativeZero) {
1981
+ (nativeAssetIdsForAccount.includes(assetId) ||
1982
+ defaultTrackedAssetIdsForAccount.includes(assetId));
1983
+ if (oldAmount !== newAmount && !isNewSeededZero) {
1852
1984
  changedBalances.push({
1853
1985
  accountId,
1854
1986
  assetId,
@@ -1878,10 +2010,8 @@ async function _AssetsController_executeMiddlewares(params) {
1878
2010
  changedPriceAssets.length > 0) {
1879
2011
  log('State updated', {
1880
2012
  changedBalances: changedBalances.length > 0 ? changedBalances : undefined,
1881
- changedMetadataCount: changedMetadata.length > 0 ? changedMetadata.length : undefined,
1882
- changedPricesCount: changedPriceAssets.length > 0
1883
- ? changedPriceAssets.length
1884
- : undefined,
2013
+ changedMetadata: changedMetadata.length > 0 ? changedMetadata : undefined,
2014
+ changedPrices: changedPriceAssets.length > 0 ? changedPriceAssets : undefined,
1885
2015
  newAssets: Object.keys(detectedAssets).length > 0
1886
2016
  ? Object.entries(detectedAssets).map(([accountId, assets]) => ({
1887
2017
  accountId,
@@ -2054,16 +2184,10 @@ async function _AssetsController_executeMiddlewares(params) {
2054
2184
  if (!subscriptionKey.startsWith('ds:')) {
2055
2185
  continue;
2056
2186
  }
2057
- // Subscription keys take the form `ds:<SourceName>` for the regular
2058
- // subscription or `ds:<SourceName>:<suffix>` for supplemental
2059
- // subscriptions (e.g. `ds:RpcDataSource:custom`). Split on `:` and
2060
- // pick the source-name segment so both shapes resolve correctly.
2187
+ // Subscription keys take the form `ds:<SourceName>`.
2061
2188
  const [, sourceId] = subscriptionKey.split(':');
2062
2189
  const source = allSources.find((ds) => ds.getName() === sourceId);
2063
2190
  if (source) {
2064
- // Unsubscribe by the actual key — `#unsubscribeDataSource` only
2065
- // knows the regular `ds:<SourceName>` shape and would miss
2066
- // supplemental subscriptions, leaking their polling timers.
2067
2191
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_unsubscribeBySubscriptionKey).call(this, source, subscriptionKey);
2068
2192
  }
2069
2193
  }
@@ -2081,12 +2205,15 @@ async function _AssetsController_executeMiddlewares(params) {
2081
2205
  // Subscribe to price updates for all assets held by selected accounts
2082
2206
  this.subscribeAssetsPrice(accounts, enabledChains);
2083
2207
  }, _AssetsController_subscribeAssetsBalance = function _AssetsController_subscribeAssetsBalance(accounts, chainIds, options) {
2208
+ if (__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_isBalanceV6Enabled).call(this)) {
2209
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssetsBalanceV6).call(this, accounts, chainIds, options);
2210
+ return;
2211
+ }
2212
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssetsBalanceV5).call(this, accounts, chainIds, options);
2213
+ }, _AssetsController_subscribeAssetsBalanceV5 = function _AssetsController_subscribeAssetsBalanceV5(accounts, chainIds, options) {
2084
2214
  const chainToAccounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildChainToAccountsMap).call(this, accounts, new Set(chainIds));
2085
2215
  const remainingChains = new Set(chainToAccounts.keys());
2086
- // When basic functionality is on, use all balance data sources; when off,
2087
- // RPC only.
2088
- const isBasicFunctionality = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this);
2089
- const balanceDataSources = isBasicFunctionality
2216
+ const balanceDataSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
2090
2217
  ? __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_allBalanceDataSources_get)
2091
2218
  : [__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")];
2092
2219
  let rpcAssignedChains = new Set();
@@ -2125,19 +2252,94 @@ async function _AssetsController_executeMiddlewares(params) {
2125
2252
  });
2126
2253
  }
2127
2254
  }
2128
- // Supplemental RPC subscription for customAssets on chains another data
2129
- // source claimed during regular handoff. RPC is the sole balance fetcher
2130
- // for customAssets, so we must always poll them — even when (e.g.)
2131
- // AccountsApi is already covering the chain for normal balances. The
2132
- // supplemental subscription runs in `customAssetsOnly` mode so it does
2133
- // NOT double-poll the regular tracked balances.
2134
2255
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeRpcCustomAssetsSupplement).call(this, accounts, chainToAccounts, rpcAssignedChains);
2256
+ }, _AssetsController_subscribeAssetsBalanceV6 = function _AssetsController_subscribeAssetsBalanceV6(accounts, chainIds, options) {
2257
+ const chainToAccounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildChainToAccountsMap).call(this, accounts, new Set(chainIds));
2258
+ const remainingChains = new Set(chainToAccounts.keys());
2259
+ const remainingCustomAssets = new Set();
2260
+ for (const account of accounts) {
2261
+ for (const assetId of __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getVisibleCustomAssets).call(this, account.id)) {
2262
+ try {
2263
+ if (remainingChains.has((0, utils_1.parseCaipAssetType)(assetId).chainId)) {
2264
+ remainingCustomAssets.add(assetId);
2265
+ }
2266
+ }
2267
+ catch {
2268
+ // Skip unparseable asset IDs
2269
+ }
2270
+ }
2271
+ }
2272
+ const balanceDataSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
2273
+ ? __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_allBalanceDataSources_get)
2274
+ : [__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")];
2275
+ for (const source of balanceDataSources) {
2276
+ const availableChains = new Set(source.getActiveChainsSync());
2277
+ const assignedChains = [];
2278
+ for (const chainId of remainingChains) {
2279
+ if (availableChains.has(chainId)) {
2280
+ assignedChains.push(chainId);
2281
+ remainingChains.delete(chainId);
2282
+ }
2283
+ }
2284
+ const claimedAssets = source.claimCustomAssets([...remainingCustomAssets], assignedChains);
2285
+ for (const assetId of claimedAssets) {
2286
+ remainingCustomAssets.delete(assetId);
2287
+ }
2288
+ if (assignedChains.length === 0 && claimedAssets.length === 0) {
2289
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_unsubscribeDataSource).call(this, source);
2290
+ continue;
2291
+ }
2292
+ const claimedAssetsSet = new Set(claimedAssets);
2293
+ const seenIds = new Set();
2294
+ const accountsForSource = assignedChains
2295
+ .flatMap((chainId) => chainToAccounts.get(chainId) ?? [])
2296
+ .filter((account) => {
2297
+ if (seenIds.has(account.id)) {
2298
+ return false;
2299
+ }
2300
+ seenIds.add(account.id);
2301
+ return true;
2302
+ });
2303
+ for (const account of accounts) {
2304
+ if (!seenIds.has(account.id) &&
2305
+ this.getCustomAssets(account.id).some((assetId) => claimedAssetsSet.has(assetId))) {
2306
+ seenIds.add(account.id);
2307
+ accountsForSource.push(account);
2308
+ }
2309
+ }
2310
+ if (accountsForSource.length > 0) {
2311
+ const hiddenAssets = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getHiddenAssetIds).call(this);
2312
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeDataSource).call(this, source, accountsForSource, assignedChains, {
2313
+ customAssets: claimedAssets,
2314
+ excludeAssetIds: hiddenAssets.length > 0 ? hiddenAssets : undefined,
2315
+ ...(options?.skipInitialFetch &&
2316
+ source === __classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f")
2317
+ ? { skipInitialFetch: true }
2318
+ : {}),
2319
+ });
2320
+ }
2321
+ else {
2322
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_unsubscribeDataSource).call(this, source);
2323
+ }
2324
+ }
2325
+ if (remainingCustomAssets.size > 0) {
2326
+ log('Custom assets unclaimed by any data source', {
2327
+ assetIds: [...remainingCustomAssets],
2328
+ });
2329
+ }
2135
2330
  }, _AssetsController_subscribeRpcCustomAssetsSupplement = function _AssetsController_subscribeRpcCustomAssetsSupplement(accounts, chainToAccounts, rpcAssignedChains) {
2136
2331
  const rpc = __classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f");
2137
2332
  const supplementalKey = `ds:${rpc.getName()}:custom`;
2333
+ const visibleCustomAssetsByAccount = {};
2334
+ for (const account of accounts) {
2335
+ const visibleCustomAssets = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getVisibleCustomAssets).call(this, account.id);
2336
+ if (visibleCustomAssets.length > 0) {
2337
+ visibleCustomAssetsByAccount[account.id] = visibleCustomAssets;
2338
+ }
2339
+ }
2138
2340
  const decision = (0, customAssetsRpcSupplement_js_1.pickRpcCustomAssetsSupplement)({
2139
2341
  accountIds: accounts.map((account) => account.id),
2140
- customAssetsByAccount: this.state.customAssets,
2342
+ customAssetsByAccount: visibleCustomAssetsByAccount,
2141
2343
  rpcAssignedChains,
2142
2344
  rpcAvailableChains: new Set(rpc.getActiveChainsSync()),
2143
2345
  enabledChains: new Set(chainToAccounts.keys()),
@@ -2194,12 +2396,14 @@ async function _AssetsController_executeMiddlewares(params) {
2194
2396
  const subscriptionKey = options.subscriptionKey ?? `ds:${sourceId}`;
2195
2397
  const existingSubscription = __classPrivateFieldGet(this, _AssetsController_activeSubscriptions, "f").get(subscriptionKey);
2196
2398
  const isUpdate = existingSubscription !== undefined;
2399
+ const customAssets = options.customAssets ?? [];
2197
2400
  log('Subscribe to data source', {
2198
2401
  sourceId,
2199
2402
  subscriptionKey,
2200
2403
  isUpdate,
2201
2404
  accountCount: accounts.length,
2202
2405
  chainCount: chains.length,
2406
+ customAssetCount: customAssets.length,
2203
2407
  customAssetsOnly: options.customAssetsOnly === true,
2204
2408
  skipInitialFetch: options.skipInitialFetch === true,
2205
2409
  });
@@ -2208,6 +2412,10 @@ async function _AssetsController_executeMiddlewares(params) {
2208
2412
  assetTypes: ['fungible'],
2209
2413
  dataTypes: ['balance'],
2210
2414
  updateInterval: __classPrivateFieldGet(this, _AssetsController_defaultUpdateInterval, "f"),
2415
+ customAssets: customAssets.length > 0 ? customAssets : undefined,
2416
+ excludeAssetIds: options.excludeAssetIds && options.excludeAssetIds.length > 0
2417
+ ? options.excludeAssetIds
2418
+ : undefined,
2211
2419
  ...(options.customAssetsOnly === true
2212
2420
  ? { customAssetsOnly: true }
2213
2421
  : {}),
@@ -2371,13 +2579,13 @@ async function _AssetsController_handleAccountGroupChanged(groupId, previousGrou
2371
2579
  // The data will simply not be updated until the network is re-enabled.
2372
2580
  // Refresh subscriptions for new chain set
2373
2581
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
2374
- // Do one-time fetch for newly enabled chains; merge so we keep existing chain balances
2582
+ // One-time fetch for newly enabled chains. v6 `full` replace is scoped to
2583
+ // those chains; existing balances on other chains are left untouched.
2375
2584
  const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this);
2376
2585
  if (addedChains.length > 0 && accounts.length > 0) {
2377
2586
  await this.getAssets(accounts, {
2378
2587
  chainIds: addedChains,
2379
2588
  forceUpdate: true,
2380
- updateMode: 'merge',
2381
2589
  });
2382
2590
  }
2383
2591
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
@@ -2500,5 +2708,153 @@ async function _AssetsController_refreshAssetsAfterNetworkAdded(hexChainId) {
2500
2708
  });
2501
2709
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
2502
2710
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_fetchMissingPricesWithoutCache).call(this, accounts, [caipChainId]);
2711
+ }, _AssetsController_handleAssetsUpdateV5 = async function _AssetsController_handleAssetsUpdateV5(response, sourceId, request) {
2712
+ const pipelineTrace = __classPrivateFieldGet(this, _AssetsController_firstInitFetchReported, "f")
2713
+ ? undefined
2714
+ : __classPrivateFieldGet(this, _AssetsController_trace, "f");
2715
+ await (0, trace_js_1.withTrace)({
2716
+ name: TRACE_UPDATE_PARENT,
2717
+ trace: pipelineTrace,
2718
+ data: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getUpdateTraceData).call(this, response, sourceId),
2719
+ fn: async (parentContext) => {
2720
+ const updateStart = performance.now();
2721
+ const pipelineRequest = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getUpdatePipelineRequest).call(this, request);
2722
+ const shouldGraduateCustomAssets = sourceId === 'AccountsApiDataSource' ||
2723
+ sourceId === 'AccountActivityDataSource';
2724
+ const shouldFilterOccurrences = sourceId === 'AccountActivityDataSource' &&
2725
+ __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this);
2726
+ const shouldRunRpcFallback = sourceId === 'AccountsApiDataSource';
2727
+ const enrichmentSources = [
2728
+ ...(shouldGraduateCustomAssets
2729
+ ? [__classPrivateFieldGet(this, _AssetsController_customAssetGraduationMiddleware, "f")]
2730
+ : []),
2731
+ ...(shouldFilterOccurrences
2732
+ ? [
2733
+ {
2734
+ getName: () => 'OccurrenceFloorFilter',
2735
+ assetsMiddleware: __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f").occurrenceFilterMiddleware,
2736
+ },
2737
+ ]
2738
+ : []),
2739
+ ...(shouldRunRpcFallback ? [__classPrivateFieldGet(this, _AssetsController_rpcFallbackMiddleware, "f")] : []),
2740
+ __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
2741
+ ];
2742
+ enrichmentSources.push(__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"));
2743
+ if (__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)) {
2744
+ enrichmentSources.push((0, ParallelMiddleware_js_1.createParallelMiddleware)([
2745
+ __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
2746
+ __classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
2747
+ ]));
2748
+ }
2749
+ const { response: enrichedResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, {
2750
+ sources: enrichmentSources,
2751
+ request: pipelineRequest,
2752
+ initialResponse: response,
2753
+ parentContext,
2754
+ trace: pipelineTrace,
2755
+ });
2756
+ await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
2757
+ ...enrichedResponse,
2758
+ replaceCoveredChainBalances: response.replaceCoveredChainBalances,
2759
+ });
2760
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitUpdateTrace).call(this, {
2761
+ response,
2762
+ sourceId,
2763
+ enrichedResponse,
2764
+ updateStart,
2765
+ pipelineTrace,
2766
+ parentContext,
2767
+ });
2768
+ },
2769
+ });
2770
+ }, _AssetsController_handleAssetsUpdateV6 = async function _AssetsController_handleAssetsUpdateV6(response, sourceId, request) {
2771
+ const pipelineTrace = __classPrivateFieldGet(this, _AssetsController_firstInitFetchReported, "f")
2772
+ ? undefined
2773
+ : __classPrivateFieldGet(this, _AssetsController_trace, "f");
2774
+ await (0, trace_js_1.withTrace)({
2775
+ name: TRACE_UPDATE_PARENT,
2776
+ trace: pipelineTrace,
2777
+ data: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getUpdateTraceData).call(this, response, sourceId),
2778
+ fn: async (parentContext) => {
2779
+ const updateStart = performance.now();
2780
+ const pipelineRequest = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getUpdatePipelineRequest).call(this, request);
2781
+ const shouldFilterOccurrences = sourceId === 'AccountActivityDataSource' &&
2782
+ __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this);
2783
+ const enrichmentSources = [
2784
+ ...(shouldFilterOccurrences
2785
+ ? [
2786
+ {
2787
+ getName: () => 'OccurrenceFloorFilter',
2788
+ assetsMiddleware: __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f").occurrenceFilterMiddleware,
2789
+ },
2790
+ ]
2791
+ : []),
2792
+ ];
2793
+ if (__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)) {
2794
+ enrichmentSources.push(__classPrivateFieldGet(this, _AssetsController_rpcFallbackMiddleware, "f"));
2795
+ }
2796
+ enrichmentSources.push(__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"));
2797
+ if (__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)) {
2798
+ enrichmentSources.push((0, ParallelMiddleware_js_1.createParallelMiddleware)([
2799
+ __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
2800
+ __classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
2801
+ ]));
2802
+ }
2803
+ const { response: enrichedResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, {
2804
+ sources: enrichmentSources,
2805
+ request: pipelineRequest,
2806
+ initialResponse: response,
2807
+ parentContext,
2808
+ trace: pipelineTrace,
2809
+ });
2810
+ await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, enrichedResponse);
2811
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitUpdateTrace).call(this, {
2812
+ response,
2813
+ sourceId,
2814
+ enrichedResponse,
2815
+ updateStart,
2816
+ pipelineTrace,
2817
+ parentContext,
2818
+ });
2819
+ },
2820
+ });
2821
+ }, _AssetsController_getUpdatePipelineRequest = function _AssetsController_getUpdatePipelineRequest(request) {
2822
+ const resolvedRequest = request ?? {
2823
+ accountsWithSupportedChains: [],
2824
+ chainIds: [],
2825
+ dataTypes: ['balance', 'metadata', 'price'],
2826
+ };
2827
+ if (__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)) {
2828
+ return resolvedRequest;
2829
+ }
2830
+ return {
2831
+ ...resolvedRequest,
2832
+ dataTypes: resolvedRequest.dataTypes.filter((dataType) => dataType !== 'metadata' && dataType !== 'price'),
2833
+ };
2834
+ }, _AssetsController_getUpdateTraceData = function _AssetsController_getUpdateTraceData(response, sourceId) {
2835
+ return {
2836
+ source: sourceId,
2837
+ has_balance: Boolean(response.assetsBalance),
2838
+ has_price: Boolean(response.assetsPrice),
2839
+ balance_account_count: response.assetsBalance
2840
+ ? Object.keys(response.assetsBalance).length
2841
+ : 0,
2842
+ };
2843
+ }, _AssetsController_emitUpdateTrace = function _AssetsController_emitUpdateTrace({ response, sourceId, enrichedResponse, updateStart, pipelineTrace, parentContext, }) {
2844
+ (0, trace_js_1.emitTrace)({
2845
+ name: TRACE_UPDATE_PIPELINE,
2846
+ trace: pipelineTrace,
2847
+ data: {
2848
+ source: sourceId,
2849
+ duration_ms: performance.now() - updateStart,
2850
+ has_balance: Boolean(response.assetsBalance),
2851
+ has_price: Boolean(response.assetsPrice),
2852
+ has_metadata: Boolean(enrichedResponse.assetsInfo),
2853
+ balance_account_count: response.assetsBalance
2854
+ ? Object.keys(response.assetsBalance).length
2855
+ : 0,
2856
+ },
2857
+ parentContext,
2858
+ });
2503
2859
  };
2504
2860
  //# sourceMappingURL=AssetsController.cjs.map