@metamask/assets-controller 9.0.2 → 10.0.0

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 (98) hide show
  1. package/CHANGELOG.md +44 -1
  2. package/dist/AssetsController.cjs +357 -105
  3. package/dist/AssetsController.cjs.map +1 -1
  4. package/dist/AssetsController.d.cts +11 -8
  5. package/dist/AssetsController.d.cts.map +1 -1
  6. package/dist/AssetsController.d.mts +11 -8
  7. package/dist/AssetsController.d.mts.map +1 -1
  8. package/dist/AssetsController.mjs +357 -105
  9. package/dist/AssetsController.mjs.map +1 -1
  10. package/dist/data-sources/AccountsApiDataSource.cjs +15 -2
  11. package/dist/data-sources/AccountsApiDataSource.cjs.map +1 -1
  12. package/dist/data-sources/AccountsApiDataSource.d.cts +8 -0
  13. package/dist/data-sources/AccountsApiDataSource.d.cts.map +1 -1
  14. package/dist/data-sources/AccountsApiDataSource.d.mts +8 -0
  15. package/dist/data-sources/AccountsApiDataSource.d.mts.map +1 -1
  16. package/dist/data-sources/AccountsApiDataSource.mjs +15 -2
  17. package/dist/data-sources/AccountsApiDataSource.mjs.map +1 -1
  18. package/dist/data-sources/BackendWebsocketDataSource.cjs +236 -149
  19. package/dist/data-sources/BackendWebsocketDataSource.cjs.map +1 -1
  20. package/dist/data-sources/BackendWebsocketDataSource.d.cts +15 -0
  21. package/dist/data-sources/BackendWebsocketDataSource.d.cts.map +1 -1
  22. package/dist/data-sources/BackendWebsocketDataSource.d.mts +15 -0
  23. package/dist/data-sources/BackendWebsocketDataSource.d.mts.map +1 -1
  24. package/dist/data-sources/BackendWebsocketDataSource.mjs +236 -146
  25. package/dist/data-sources/BackendWebsocketDataSource.mjs.map +1 -1
  26. package/dist/data-sources/PriceDataSource.cjs +82 -22
  27. package/dist/data-sources/PriceDataSource.cjs.map +1 -1
  28. package/dist/data-sources/PriceDataSource.d.cts +13 -0
  29. package/dist/data-sources/PriceDataSource.d.cts.map +1 -1
  30. package/dist/data-sources/PriceDataSource.d.mts +13 -0
  31. package/dist/data-sources/PriceDataSource.d.mts.map +1 -1
  32. package/dist/data-sources/PriceDataSource.mjs +83 -23
  33. package/dist/data-sources/PriceDataSource.mjs.map +1 -1
  34. package/dist/data-sources/RpcDataSource.cjs +29 -9
  35. package/dist/data-sources/RpcDataSource.cjs.map +1 -1
  36. package/dist/data-sources/RpcDataSource.d.cts +5 -0
  37. package/dist/data-sources/RpcDataSource.d.cts.map +1 -1
  38. package/dist/data-sources/RpcDataSource.d.mts +5 -0
  39. package/dist/data-sources/RpcDataSource.d.mts.map +1 -1
  40. package/dist/data-sources/RpcDataSource.mjs +29 -9
  41. package/dist/data-sources/RpcDataSource.mjs.map +1 -1
  42. package/dist/data-sources/SnapDataSource.cjs +2 -2
  43. package/dist/data-sources/SnapDataSource.cjs.map +1 -1
  44. package/dist/data-sources/SnapDataSource.mjs +2 -2
  45. package/dist/data-sources/SnapDataSource.mjs.map +1 -1
  46. package/dist/index.cjs +3 -1
  47. package/dist/index.cjs.map +1 -1
  48. package/dist/index.d.cts +2 -2
  49. package/dist/index.d.cts.map +1 -1
  50. package/dist/index.d.mts +2 -2
  51. package/dist/index.d.mts.map +1 -1
  52. package/dist/index.mjs +1 -1
  53. package/dist/index.mjs.map +1 -1
  54. package/dist/middlewares/DetectionMiddleware.cjs +64 -23
  55. package/dist/middlewares/DetectionMiddleware.cjs.map +1 -1
  56. package/dist/middlewares/DetectionMiddleware.d.cts +15 -13
  57. package/dist/middlewares/DetectionMiddleware.d.cts.map +1 -1
  58. package/dist/middlewares/DetectionMiddleware.d.mts +15 -13
  59. package/dist/middlewares/DetectionMiddleware.d.mts.map +1 -1
  60. package/dist/middlewares/DetectionMiddleware.mjs +64 -23
  61. package/dist/middlewares/DetectionMiddleware.mjs.map +1 -1
  62. package/dist/middlewares/ParallelMiddleware.cjs +7 -0
  63. package/dist/middlewares/ParallelMiddleware.cjs.map +1 -1
  64. package/dist/middlewares/ParallelMiddleware.d.cts.map +1 -1
  65. package/dist/middlewares/ParallelMiddleware.d.mts.map +1 -1
  66. package/dist/middlewares/ParallelMiddleware.mjs +7 -0
  67. package/dist/middlewares/ParallelMiddleware.mjs.map +1 -1
  68. package/dist/selectors/balance.cjs +191 -8
  69. package/dist/selectors/balance.cjs.map +1 -1
  70. package/dist/selectors/balance.d.cts +80 -0
  71. package/dist/selectors/balance.d.cts.map +1 -1
  72. package/dist/selectors/balance.d.mts +80 -0
  73. package/dist/selectors/balance.d.mts.map +1 -1
  74. package/dist/selectors/balance.mjs +186 -7
  75. package/dist/selectors/balance.mjs.map +1 -1
  76. package/dist/types.cjs.map +1 -1
  77. package/dist/types.d.cts +20 -4
  78. package/dist/types.d.cts.map +1 -1
  79. package/dist/types.d.mts +20 -4
  80. package/dist/types.d.mts.map +1 -1
  81. package/dist/types.mjs.map +1 -1
  82. package/dist/utils/dedupingBatchFetcher.cjs +168 -0
  83. package/dist/utils/dedupingBatchFetcher.cjs.map +1 -0
  84. package/dist/utils/dedupingBatchFetcher.d.cts +72 -0
  85. package/dist/utils/dedupingBatchFetcher.d.cts.map +1 -0
  86. package/dist/utils/dedupingBatchFetcher.d.mts +72 -0
  87. package/dist/utils/dedupingBatchFetcher.d.mts.map +1 -0
  88. package/dist/utils/dedupingBatchFetcher.mjs +164 -0
  89. package/dist/utils/dedupingBatchFetcher.mjs.map +1 -0
  90. package/dist/utils/processAccountActivityBalanceUpdates.cjs +54 -0
  91. package/dist/utils/processAccountActivityBalanceUpdates.cjs.map +1 -0
  92. package/dist/utils/processAccountActivityBalanceUpdates.d.cts +13 -0
  93. package/dist/utils/processAccountActivityBalanceUpdates.d.cts.map +1 -0
  94. package/dist/utils/processAccountActivityBalanceUpdates.d.mts +13 -0
  95. package/dist/utils/processAccountActivityBalanceUpdates.d.mts.map +1 -0
  96. package/dist/utils/processAccountActivityBalanceUpdates.mjs +47 -0
  97. package/dist/utils/processAccountActivityBalanceUpdates.mjs.map +1 -0
  98. package/package.json +7 -7
@@ -230,7 +230,42 @@ function resolveAccountsToAggregate(args) {
230
230
  }
231
231
  return [selectedInternalAccount];
232
232
  }
233
- export function getAggregatedBalanceForAccount(state, selectedInternalAccount, enabledNetworkMap, accountTreeState, internalAccountsOrAccountIds, accountsById, trace) {
233
+ /**
234
+ * Get account ids that belong to a group, reading directly from the account
235
+ * tree. Unlike {@link getInternalAccountsForGroup}, this does not require an
236
+ * `accountsById` lookup map, which makes it convenient for balance aggregation
237
+ * where only the ids are needed.
238
+ *
239
+ * @param accountTreeState - AccountTreeController state.
240
+ * @param groupId - The account group id to look up.
241
+ * @returns The list of account ids in the group, or an empty array.
242
+ */
243
+ export function getAccountIdsForGroup(accountTreeState, groupId) {
244
+ const wallets = accountTreeState.accountTree?.wallets ?? {};
245
+ for (const wallet of Object.values(wallets)) {
246
+ const groups = (wallet?.groups ?? {});
247
+ const group = groups[groupId];
248
+ if (group?.accounts) {
249
+ return [...group.accounts];
250
+ }
251
+ }
252
+ return [];
253
+ }
254
+ /**
255
+ * Aggregate balances across an explicit list of accounts.
256
+ *
257
+ * This is the core aggregation engine shared by the account- and group-level
258
+ * selectors. It intentionally takes a fully-resolved list of accounts so that
259
+ * callers control account resolution and no "selected account" placeholder is
260
+ * required.
261
+ *
262
+ * @param state - AssetsController state slice.
263
+ * @param accounts - Accounts whose balances should be aggregated.
264
+ * @param enabledNetworkMap - Optional map of enabled networks keyed by namespace.
265
+ * @param trace - Optional trace callback for telemetry spans.
266
+ * @returns Aggregated balance entries plus fiat totals when prices are present.
267
+ */
268
+ function aggregateBalances(state, accounts, enabledNetworkMap, trace) {
234
269
  const startTime = trace ? performance.now() : 0;
235
270
  const { assetsBalance, assetsInfo, assetPreferences, assetsPrice } = state;
236
271
  const metadata = (assetsInfo ?? {});
@@ -243,12 +278,7 @@ export function getAggregatedBalanceForAccount(state, selectedInternalAccount, e
243
278
  }
244
279
  return false;
245
280
  })();
246
- const accountsToAggregate = resolveAccountsToAggregate({
247
- selectedInternalAccount,
248
- accountTreeState,
249
- internalAccountsOrAccountIds,
250
- accountsById,
251
- });
281
+ const accountsToAggregate = accounts;
252
282
  const assetInfoCache = makeAssetInfoCache();
253
283
  const merged = new Map();
254
284
  for (const account of accountsToAggregate) {
@@ -268,6 +298,7 @@ export function getAggregatedBalanceForAccount(state, selectedInternalAccount, e
268
298
  let idx = 0;
269
299
  // If prices exist, compute totals in a single pass over merged.
270
300
  let totalBalanceInFiat = 0;
301
+ let previousTotalInFiat = 0;
271
302
  let weightedNumerator = 0;
272
303
  for (const [assetId, row] of merged.entries()) {
273
304
  const { amount } = row;
@@ -286,6 +317,11 @@ export function getAggregatedBalanceForAccount(state, selectedInternalAccount, e
286
317
  if (contribution > 0) {
287
318
  totalBalanceInFiat += contribution;
288
319
  weightedNumerator += contribution * pricePercentChange1d;
320
+ // A -100% move makes the denominator zero; treat it as flat so the
321
+ // previous total never goes to infinity.
322
+ const denom = Number((1 + pricePercentChange1d / 100).toFixed(8));
323
+ previousTotalInFiat +=
324
+ denom === 0 ? contribution : contribution / denom;
289
325
  }
290
326
  }
291
327
  }
@@ -315,8 +351,151 @@ export function getAggregatedBalanceForAccount(state, selectedInternalAccount, e
315
351
  entries,
316
352
  totalBalanceInFiat,
317
353
  pricePercentChange1d,
354
+ previousTotalInFiat,
318
355
  };
319
356
  }
320
357
  return { entries };
321
358
  }
359
+ /**
360
+ * Aggregate balances for an explicit list of account ids.
361
+ *
362
+ * Prefer this over {@link getAggregatedBalanceForAccount} when the set of
363
+ * accounts to aggregate is already known (e.g. all accounts in a group), since
364
+ * it does not require a "selected account" and therefore avoids the brittle
365
+ * account-resolution heuristics.
366
+ *
367
+ * @param state - AssetsController state slice.
368
+ * @param accountIds - Account ids whose balances should be aggregated.
369
+ * @param enabledNetworkMap - Optional map of enabled networks keyed by namespace.
370
+ * @param trace - Optional trace callback for telemetry spans.
371
+ * @returns Aggregated balance entries plus fiat totals when prices are present.
372
+ */
373
+ export function getAggregatedBalanceForAccountIds(state, accountIds, enabledNetworkMap, trace) {
374
+ const accounts = accountIds.map((id) => ({ id }));
375
+ return aggregateBalances(state, accounts, enabledNetworkMap, trace);
376
+ }
377
+ export function getAggregatedBalanceForAccount(state, selectedInternalAccount, enabledNetworkMap, accountTreeState, internalAccountsOrAccountIds, accountsById, trace) {
378
+ const accountsToAggregate = resolveAccountsToAggregate({
379
+ selectedInternalAccount,
380
+ accountTreeState,
381
+ internalAccountsOrAccountIds,
382
+ accountsById,
383
+ });
384
+ return aggregateBalances(state, accountsToAggregate, enabledNetworkMap, trace);
385
+ }
386
+ // ============================================================================
387
+ // WALLET- AND GROUP-LEVEL BALANCE CALCULATIONS
388
+ // ============================================================================
389
+ /**
390
+ * Default user currency used when {@link AssetsControllerState.selectedCurrency}
391
+ * is not set.
392
+ */
393
+ const DEFAULT_USER_CURRENCY = 'usd';
394
+ /**
395
+ * Resolve the user currency for a balance calculation, falling back to a
396
+ * sensible default when the controller has no selected currency.
397
+ *
398
+ * @param assetsControllerState - AssetsController state slice.
399
+ * @returns The user currency code.
400
+ */
401
+ function getUserCurrency(assetsControllerState) {
402
+ return assetsControllerState.selectedCurrency ?? DEFAULT_USER_CURRENCY;
403
+ }
404
+ /**
405
+ * Resolve the current and previous totals for a change calculation.
406
+ *
407
+ * The AssetsController state only exposes a 1d price change, so non-`1d`
408
+ * periods produce a zeroed change (previous equals current).
409
+ *
410
+ * @param totalBalanceInFiat - Aggregated current balance in user currency.
411
+ * @param previousTotalInFiat - Aggregated prior balance summed per asset.
412
+ * @param period - Period to compute the change for.
413
+ * @returns The current and previous totals in user currency.
414
+ */
415
+ function getCurrentAndPrevious(totalBalanceInFiat, previousTotalInFiat, period) {
416
+ const current = totalBalanceInFiat;
417
+ const previous = period === '1d' ? previousTotalInFiat : current;
418
+ return { current, previous };
419
+ }
420
+ /**
421
+ * Build a {@link BalanceChangeResult} from current/previous totals.
422
+ *
423
+ * @param current - Current total in user currency.
424
+ * @param previous - Previous total in user currency.
425
+ * @param period - Period the change was computed for.
426
+ * @param userCurrency - User currency code.
427
+ * @returns The change result with delta and percent change.
428
+ */
429
+ function buildBalanceChangeResult(current, previous, period, userCurrency) {
430
+ const amountChange = current - previous;
431
+ const percentChange = previous === 0 ? 0 : (amountChange / previous) * 100;
432
+ return {
433
+ period,
434
+ currentTotalInUserCurrency: Number(current.toFixed(8)),
435
+ previousTotalInUserCurrency: Number(previous.toFixed(8)),
436
+ amountChangeInUserCurrency: Number(amountChange.toFixed(8)),
437
+ percentChange: Number(percentChange.toFixed(8)),
438
+ userCurrency,
439
+ };
440
+ }
441
+ /**
442
+ * Calculate aggregated balances for all wallets and groups.
443
+ *
444
+ * Mirrors the legacy `@metamask/assets-controllers` `calculateBalanceForAllWallets`
445
+ * output shape, but sources every group total from the unified AssetsController
446
+ * state via {@link getAggregatedBalanceForAccountIds}. The account tree is walked
447
+ * to aggregate each group individually.
448
+ *
449
+ * @param assetsControllerState - AssetsController state slice.
450
+ * @param accountTreeState - AccountTreeController state.
451
+ * @param enabledNetworkMap - Map of enabled networks keyed by namespace.
452
+ * @param trace - Optional trace callback forwarded to the aggregation selector.
453
+ * @returns Aggregated balances for all wallets and groups.
454
+ */
455
+ export function calculateBalanceForAllWallets(assetsControllerState, accountTreeState, enabledNetworkMap, trace) {
456
+ const userCurrency = getUserCurrency(assetsControllerState);
457
+ const wallets = {};
458
+ let totalBalanceInUserCurrency = 0;
459
+ for (const [walletId, wallet] of Object.entries(accountTreeState.accountTree?.wallets ?? {})) {
460
+ const walletBalance = {
461
+ walletId,
462
+ groups: {},
463
+ totalBalanceInUserCurrency: 0,
464
+ userCurrency,
465
+ };
466
+ const groups = wallet?.groups ?? {};
467
+ for (const groupId of Object.keys(groups)) {
468
+ const accountIds = getAccountIdsForGroup(accountTreeState, groupId);
469
+ const { totalBalanceInFiat = 0 } = getAggregatedBalanceForAccountIds(assetsControllerState, accountIds, enabledNetworkMap, trace);
470
+ walletBalance.groups[groupId] = {
471
+ walletId,
472
+ groupId,
473
+ totalBalanceInUserCurrency: totalBalanceInFiat,
474
+ userCurrency,
475
+ };
476
+ walletBalance.totalBalanceInUserCurrency += totalBalanceInFiat;
477
+ }
478
+ wallets[walletId] = walletBalance;
479
+ totalBalanceInUserCurrency += walletBalance.totalBalanceInUserCurrency;
480
+ }
481
+ return { wallets, totalBalanceInUserCurrency, userCurrency };
482
+ }
483
+ /**
484
+ * Calculate the portfolio value change for a single account group and period.
485
+ *
486
+ * @param assetsControllerState - AssetsController state slice.
487
+ * @param accountTreeState - AccountTreeController state.
488
+ * @param groupId - Account group id to compute the change for.
489
+ * @param period - Change period (`1d` | `7d` | `30d`).
490
+ * @param enabledNetworkMap - Map of enabled networks keyed by namespace.
491
+ * @param trace - Optional trace callback forwarded to the aggregation selector.
492
+ * @returns The change result for the requested period.
493
+ */
494
+ export function calculateBalanceChangeForAccountGroup(assetsControllerState, accountTreeState, groupId, period, enabledNetworkMap, trace) {
495
+ const userCurrency = getUserCurrency(assetsControllerState);
496
+ const accountIds = getAccountIdsForGroup(accountTreeState, groupId);
497
+ const { totalBalanceInFiat = 0, previousTotalInFiat = totalBalanceInFiat } = getAggregatedBalanceForAccountIds(assetsControllerState, accountIds, enabledNetworkMap, trace);
498
+ const { current, previous } = getCurrentAndPrevious(totalBalanceInFiat, previousTotalInFiat, period);
499
+ return buildBalanceChangeResult(current, previous, period, userCurrency);
500
+ }
322
501
  //# sourceMappingURL=balance.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"balance.mjs","sourceRoot":"","sources":["../../src/selectors/balance.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccountTreeControllerState } from '@metamask/account-tree-controller';\nimport { toHex } from '@metamask/controller-utils';\nimport type { TraceCallback } from '@metamask/controller-utils';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { CaipChainId, Hex } from '@metamask/utils';\nimport {\n KnownCaipNamespace,\n isStrictHexString,\n parseCaipAssetType,\n parseCaipChainId,\n} from '@metamask/utils';\nimport BigNumberJS from 'bignumber.js';\n\nimport type { AssetsControllerState } from '../AssetsController';\nimport type {\n AccountId,\n AssetBalance,\n AssetMetadata,\n AssetPreferences,\n Caip19AssetId,\n} from '../types';\n\n// ============================================================================\n// TRACE NAMES — used in Sentry spans (search these strings in Discover)\n// ============================================================================\nconst TRACE_AGGREGATED_BALANCE_SELECTOR = 'AggregatedBalanceSelector';\n\nexport type EnabledNetworkMap =\n | Record<string, Record<string, boolean>>\n | undefined;\n\nexport type AggregatedBalanceEntry = {\n assetId: Caip19AssetId;\n amount: string;\n decimals?: number;\n symbol?: string;\n name?: string;\n};\n\nexport type AggregatedBalanceForAccount = {\n entries: AggregatedBalanceEntry[];\n totalBalanceInFiat?: number;\n pricePercentChange1d?: number;\n};\n\ntype AccountLike = { id: AccountId };\nexport type AccountsById = Record<AccountId, InternalAccount>;\n\ntype PriceDatum = { price: number; pricePercentChange1d: number };\n\nconst ZERO_PRICE: PriceDatum = { price: 0, pricePercentChange1d: 0 };\n\nconst getAmountFromBalance = (balance: AssetBalance): string => {\n if (typeof balance === 'object' && balance !== null && 'amount' in balance) {\n const { amount } = balance as { amount?: unknown };\n return typeof amount === 'string' ? amount : '0';\n }\n return '0';\n};\n\nconst toBigNumberOrZero = (value: string): BigNumberJS => {\n const parsed = new BigNumberJS(value);\n return parsed.isNaN() || !parsed.isFinite() ? new BigNumberJS(0) : parsed;\n};\n\n/**\n * When state contains raw base units (e.g. SPORE \"16201541034.639288184\" with 9 decimals),\n * scale to human (16.2) before pricing. Only scale when amount >= 10^decimals so we don't\n * double-scale amounts that are already human (e.g. \"1\", \"0.227285\").\n *\n * @param amountRaw - Amount from state (may be raw or human).\n * @param decimals - Token decimals from metadata.\n * @returns Human amount for display and fiat (amountRaw or amountRaw / 10^decimals).\n */\nconst scaleToHumanIfRaw = (\n amountRaw: BigNumberJS,\n decimals: number,\n): BigNumberJS => {\n if (decimals <= 0) {\n return amountRaw;\n }\n const scale = new BigNumberJS(10).pow(decimals);\n if (amountRaw.lt(scale)) {\n return amountRaw;\n }\n return amountRaw.dividedBy(scale);\n};\n\nconst getPriceDatumFast = (\n assetsPrice: AssetsControllerState['assetsPrice'] | undefined,\n assetId: Caip19AssetId,\n): PriceDatum => {\n const raw = assetsPrice?.[assetId];\n if (!raw || typeof raw !== 'object') {\n return ZERO_PRICE;\n }\n const { price, pricePercentChange1d } = raw as {\n price?: unknown;\n pricePercentChange1d?: unknown;\n };\n return {\n price: typeof price === 'number' && Number.isFinite(price) ? price : 0,\n pricePercentChange1d:\n typeof pricePercentChange1d === 'number' &&\n Number.isFinite(pricePercentChange1d)\n ? pricePercentChange1d\n : 0,\n };\n};\n\n/**\n * Enablement lookup optimized:\n * - no array allocations\n * - early returns\n *\n * @param map - Enabled network map (namespace -> storageKey -> boolean)\n * @param id - Chain id as Hex or CAIP-2\n * @returns True if the chain is enabled or map is undefined\n */\nconst isChainEnabledByMap = (\n map: EnabledNetworkMap,\n id: Hex | CaipChainId,\n): boolean => {\n if (!map) {\n return true;\n }\n\n if (isStrictHexString(id)) {\n return Boolean(map[KnownCaipNamespace.Eip155]?.[id]);\n }\n\n const { namespace, reference } = parseCaipChainId(id);\n const namespaceMap = map[namespace];\n if (!namespaceMap) {\n return false;\n }\n\n // exact CAIP-2 id / reference\n if (namespaceMap[id] || namespaceMap[reference]) {\n return true;\n }\n\n // EVM: hex storage key\n if (namespace === KnownCaipNamespace.Eip155) {\n try {\n const storageKey = toHex(reference);\n return Boolean(namespaceMap[storageKey]);\n } catch {\n const parsedRef = Number.parseInt(reference, 10);\n if (Number.isFinite(parsedRef)) {\n return Boolean(namespaceMap[`0x${parsedRef.toString(16)}`]);\n }\n }\n }\n\n return false;\n};\n\n/**\n * Cache parsing results per assetId to avoid parseCaipAssetType/parseCaipChainId\n * being called multiple times across filtering + grouping + pricing.\n */\ntype AssetParseInfo = {\n chainId: CaipChainId;\n isEvm: boolean;\n};\n\nconst makeAssetInfoCache = (): Map<Caip19AssetId, AssetParseInfo> =>\n new Map<Caip19AssetId, AssetParseInfo>();\n\nconst getAssetInfo = (\n cache: Map<Caip19AssetId, AssetParseInfo>,\n assetId: Caip19AssetId,\n): AssetParseInfo => {\n const cached = cache.get(assetId);\n if (cached) {\n return cached;\n }\n const { chainId } = parseCaipAssetType(assetId);\n const { namespace } = parseCaipChainId(chainId);\n const info = { chainId, isEvm: namespace === KnownCaipNamespace.Eip155 };\n cache.set(assetId, info);\n return info;\n};\n\n/**\n * Merge across accounts without building per-account entries arrays.\n * Uses BigNumber for amount accumulation to avoid float precision loss.\n */\ntype AggRow = {\n amount: BigNumberJS;\n decimals?: number;\n symbol?: string;\n name?: string;\n};\n\nfunction mergeBalancesIntoMap(args: {\n out: Map<Caip19AssetId, AggRow>;\n accountBalances: Record<Caip19AssetId, AssetBalance>;\n metadata: Record<Caip19AssetId, AssetMetadata>;\n assetPreferences?: Record<Caip19AssetId, AssetPreferences>;\n enabledNetworkMap?: EnabledNetworkMap;\n assetInfoCache: Map<Caip19AssetId, AssetParseInfo>;\n}): void {\n const {\n out,\n accountBalances,\n metadata,\n assetPreferences,\n enabledNetworkMap,\n assetInfoCache,\n } = args;\n\n for (const assetId in accountBalances) {\n if (!Object.prototype.hasOwnProperty.call(accountBalances, assetId)) {\n continue;\n }\n const typedAssetId = assetId as Caip19AssetId;\n\n if (assetPreferences?.[typedAssetId]?.hidden) {\n continue;\n }\n\n const info = getAssetInfo(assetInfoCache, typedAssetId);\n if (!isChainEnabledByMap(enabledNetworkMap, info.chainId)) {\n continue;\n }\n\n const amountStr = getAmountFromBalance(accountBalances[typedAssetId]);\n let amountBn = toBigNumberOrZero(amountStr);\n const meta = metadata[typedAssetId];\n if (meta?.decimals !== undefined) {\n amountBn = scaleToHumanIfRaw(amountBn, meta.decimals);\n }\n if (amountBn.isZero()) {\n continue; // skip zeros early to reduce map pressure\n }\n\n const existing = out.get(typedAssetId);\n if (existing) {\n existing.amount = existing.amount.plus(amountBn);\n continue;\n }\n\n out.set(typedAssetId, {\n amount: amountBn,\n decimals: meta?.decimals,\n symbol: meta?.symbol,\n name: meta?.name,\n });\n }\n}\n\nexport function getGroupIdForAccount(\n accountTreeState: AccountTreeControllerState,\n accountId: AccountId,\n): string | undefined {\n const wallets = accountTreeState.accountTree?.wallets;\n if (!wallets) {\n return undefined;\n }\n for (const wallet of Object.values(wallets)) {\n for (const [groupId, group] of Object.entries(wallet?.groups ?? {})) {\n const accounts = group?.accounts;\n if (Array.isArray(accounts) && accounts.includes(accountId)) {\n return groupId;\n }\n }\n }\n return undefined;\n}\n\nexport function getInternalAccountsForGroup(\n accountTreeState: AccountTreeControllerState,\n accountsById: AccountsById,\n groupId: string,\n): InternalAccount[] {\n const wallets = accountTreeState.accountTree?.wallets;\n if (!wallets) {\n return [];\n }\n type GroupWithAccounts = { accounts?: AccountId[] };\n const getGroups = (\n walletItem: (typeof wallets)[keyof typeof wallets],\n ): Record<string, GroupWithAccounts> =>\n (walletItem?.groups ?? {}) as Record<string, GroupWithAccounts>;\n\n for (const wallet of Object.values(wallets)) {\n const group = getGroups(wallet)[groupId];\n if (!group?.accounts) {\n continue;\n }\n const result: InternalAccount[] = [];\n for (const id of group.accounts) {\n const acct = accountsById[id];\n if (acct) {\n result.push(acct);\n }\n }\n return result;\n }\n return [];\n}\n\nfunction getAccountIdsInSameGroup(\n accountTreeState: AccountTreeControllerState,\n selectedAccountId: AccountId,\n): AccountId[] | undefined {\n const groupId = getGroupIdForAccount(accountTreeState, selectedAccountId);\n if (!groupId) {\n return undefined;\n }\n const wallets = accountTreeState.accountTree?.wallets;\n if (!wallets) {\n return undefined;\n }\n type GroupWithAccounts = { accounts?: AccountId[] };\n const getGroups = (\n walletItem: (typeof wallets)[keyof typeof wallets],\n ): Record<string, GroupWithAccounts> =>\n (walletItem?.groups ?? {}) as Record<string, GroupWithAccounts>;\n\n for (const wallet of Object.values(wallets)) {\n const group = getGroups(wallet)[groupId];\n if (group?.accounts) {\n return [...group.accounts];\n }\n }\n return undefined;\n}\n\nfunction resolveAccountsToAggregate(args: {\n selectedInternalAccount: InternalAccount;\n accountTreeState?: AccountTreeControllerState;\n internalAccountsOrAccountIds?: InternalAccount[] | AccountId[];\n accountsById?: AccountsById;\n}): AccountLike[] {\n const {\n selectedInternalAccount,\n accountTreeState,\n internalAccountsOrAccountIds,\n accountsById,\n } = args;\n\n if (internalAccountsOrAccountIds && internalAccountsOrAccountIds.length > 0) {\n const first = internalAccountsOrAccountIds[0];\n if (typeof first === 'string') {\n const ids = internalAccountsOrAccountIds as AccountId[];\n const out: AccountLike[] = new Array(ids.length);\n for (let i = 0; i < ids.length; i++) {\n out[i] = { id: ids[i] };\n }\n return out;\n }\n return internalAccountsOrAccountIds as InternalAccount[];\n }\n\n if (\n accountTreeState &&\n accountsById &&\n Object.keys(accountsById).length > 0\n ) {\n const groupId = getGroupIdForAccount(\n accountTreeState,\n selectedInternalAccount.id,\n );\n if (groupId) {\n const groupAccounts = getInternalAccountsForGroup(\n accountTreeState,\n accountsById,\n groupId,\n );\n if (groupAccounts.length > 0) {\n return groupAccounts;\n }\n }\n }\n\n if (accountTreeState) {\n const ids = getAccountIdsInSameGroup(\n accountTreeState,\n selectedInternalAccount.id,\n );\n if (ids && ids.length > 0) {\n const out: AccountLike[] = new Array(ids.length);\n for (let i = 0; i < ids.length; i++) {\n out[i] = { id: ids[i] };\n }\n return out;\n }\n }\n\n return [selectedInternalAccount];\n}\n\nexport function getAggregatedBalanceForAccount(\n state: AssetsControllerState,\n selectedInternalAccount: InternalAccount,\n enabledNetworkMap?: EnabledNetworkMap,\n accountTreeState?: AccountTreeControllerState,\n internalAccountsOrAccountIds?: InternalAccount[] | AccountId[],\n accountsById?: AccountsById,\n trace?: TraceCallback,\n): AggregatedBalanceForAccount {\n const startTime = trace ? performance.now() : 0;\n const { assetsBalance, assetsInfo, assetPreferences, assetsPrice } = state;\n\n const metadata = (assetsInfo ?? {}) as Record<Caip19AssetId, AssetMetadata>;\n\n const hasPrices =\n Boolean(assetsPrice) &&\n ((): boolean => {\n for (const key in assetsPrice) {\n if (Object.prototype.hasOwnProperty.call(assetsPrice, key)) {\n return true;\n }\n }\n return false;\n })();\n\n const accountsToAggregate = resolveAccountsToAggregate({\n selectedInternalAccount,\n accountTreeState,\n internalAccountsOrAccountIds,\n accountsById,\n });\n\n const assetInfoCache = makeAssetInfoCache();\n const merged = new Map<Caip19AssetId, AggRow>();\n\n for (const account of accountsToAggregate) {\n const accountId = account.id;\n const accountBalances =\n assetsBalance?.[accountId] ?? ({} as Record<Caip19AssetId, AssetBalance>);\n\n mergeBalancesIntoMap({\n out: merged,\n accountBalances,\n metadata,\n assetPreferences,\n enabledNetworkMap,\n assetInfoCache,\n });\n }\n\n // Materialize entries once\n const entries: AggregatedBalanceEntry[] = new Array(merged.size);\n let idx = 0;\n\n // If prices exist, compute totals in a single pass over merged.\n let totalBalanceInFiat = 0;\n let weightedNumerator = 0;\n\n for (const [assetId, row] of merged.entries()) {\n const { amount } = row;\n const entry: AggregatedBalanceEntry = {\n assetId,\n amount: amount.toFixed(),\n ...(row.decimals === undefined ? {} : { decimals: row.decimals }),\n ...(row.symbol === undefined ? {} : { symbol: row.symbol }),\n ...(row.name === undefined ? {} : { name: row.name }),\n };\n entries[idx] = entry;\n idx += 1;\n\n if (hasPrices) {\n const { price, pricePercentChange1d } = getPriceDatumFast(\n assetsPrice,\n assetId,\n );\n const contribution = amount.multipliedBy(price).toNumber();\n if (contribution > 0) {\n totalBalanceInFiat += contribution;\n weightedNumerator += contribution * pricePercentChange1d;\n }\n }\n }\n\n if (trace) {\n const durationMs = performance.now() - startTime;\n const uniqueNetworks = new Set<CaipChainId>();\n for (const assetId of merged.keys()) {\n const info = getAssetInfo(assetInfoCache, assetId);\n uniqueNetworks.add(info.chainId);\n }\n trace(\n {\n name: TRACE_AGGREGATED_BALANCE_SELECTOR,\n data: {\n duration_ms: durationMs,\n asset_count: merged.size,\n network_count: uniqueNetworks.size,\n account_count: accountsToAggregate.length,\n },\n tags: { controller: 'AssetsController' },\n },\n () => undefined,\n ).catch(() => {\n // Telemetry failure must not break.\n });\n }\n\n if (hasPrices) {\n const pricePercentChange1d =\n totalBalanceInFiat > 0 ? weightedNumerator / totalBalanceInFiat : 0;\n return {\n entries,\n totalBalanceInFiat,\n pricePercentChange1d,\n };\n }\n\n return { entries };\n}\n"]}
1
+ {"version":3,"file":"balance.mjs","sourceRoot":"","sources":["../../src/selectors/balance.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccountTreeControllerState } from '@metamask/account-tree-controller';\nimport { toHex } from '@metamask/controller-utils';\nimport type { TraceCallback } from '@metamask/controller-utils';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { CaipChainId, Hex } from '@metamask/utils';\nimport {\n KnownCaipNamespace,\n isStrictHexString,\n parseCaipAssetType,\n parseCaipChainId,\n} from '@metamask/utils';\nimport BigNumberJS from 'bignumber.js';\n\nimport type { AssetsControllerState } from '../AssetsController';\nimport type {\n AccountId,\n AssetBalance,\n AssetMetadata,\n AssetPreferences,\n Caip19AssetId,\n} from '../types';\n\n// ============================================================================\n// TRACE NAMES — used in Sentry spans (search these strings in Discover)\n// ============================================================================\nconst TRACE_AGGREGATED_BALANCE_SELECTOR = 'AggregatedBalanceSelector';\n\nexport type EnabledNetworkMap =\n | Record<string, Record<string, boolean>>\n | undefined;\n\nexport type AggregatedBalanceEntry = {\n assetId: Caip19AssetId;\n amount: string;\n decimals?: number;\n symbol?: string;\n name?: string;\n};\n\nexport type AggregatedBalanceForAccount = {\n entries: AggregatedBalanceEntry[];\n totalBalanceInFiat?: number;\n pricePercentChange1d?: number;\n previousTotalInFiat?: number;\n};\n\ntype AccountLike = { id: AccountId };\nexport type AccountsById = Record<AccountId, InternalAccount>;\n\ntype PriceDatum = { price: number; pricePercentChange1d: number };\n\nconst ZERO_PRICE: PriceDatum = { price: 0, pricePercentChange1d: 0 };\n\nconst getAmountFromBalance = (balance: AssetBalance): string => {\n if (typeof balance === 'object' && balance !== null && 'amount' in balance) {\n const { amount } = balance as { amount?: unknown };\n return typeof amount === 'string' ? amount : '0';\n }\n return '0';\n};\n\nconst toBigNumberOrZero = (value: string): BigNumberJS => {\n const parsed = new BigNumberJS(value);\n return parsed.isNaN() || !parsed.isFinite() ? new BigNumberJS(0) : parsed;\n};\n\n/**\n * When state contains raw base units (e.g. SPORE \"16201541034.639288184\" with 9 decimals),\n * scale to human (16.2) before pricing. Only scale when amount >= 10^decimals so we don't\n * double-scale amounts that are already human (e.g. \"1\", \"0.227285\").\n *\n * @param amountRaw - Amount from state (may be raw or human).\n * @param decimals - Token decimals from metadata.\n * @returns Human amount for display and fiat (amountRaw or amountRaw / 10^decimals).\n */\nconst scaleToHumanIfRaw = (\n amountRaw: BigNumberJS,\n decimals: number,\n): BigNumberJS => {\n if (decimals <= 0) {\n return amountRaw;\n }\n const scale = new BigNumberJS(10).pow(decimals);\n if (amountRaw.lt(scale)) {\n return amountRaw;\n }\n return amountRaw.dividedBy(scale);\n};\n\nconst getPriceDatumFast = (\n assetsPrice: AssetsControllerState['assetsPrice'] | undefined,\n assetId: Caip19AssetId,\n): PriceDatum => {\n const raw = assetsPrice?.[assetId];\n if (!raw || typeof raw !== 'object') {\n return ZERO_PRICE;\n }\n const { price, pricePercentChange1d } = raw as {\n price?: unknown;\n pricePercentChange1d?: unknown;\n };\n return {\n price: typeof price === 'number' && Number.isFinite(price) ? price : 0,\n pricePercentChange1d:\n typeof pricePercentChange1d === 'number' &&\n Number.isFinite(pricePercentChange1d)\n ? pricePercentChange1d\n : 0,\n };\n};\n\n/**\n * Enablement lookup optimized:\n * - no array allocations\n * - early returns\n *\n * @param map - Enabled network map (namespace -> storageKey -> boolean)\n * @param id - Chain id as Hex or CAIP-2\n * @returns True if the chain is enabled or map is undefined\n */\nconst isChainEnabledByMap = (\n map: EnabledNetworkMap,\n id: Hex | CaipChainId,\n): boolean => {\n if (!map) {\n return true;\n }\n\n if (isStrictHexString(id)) {\n return Boolean(map[KnownCaipNamespace.Eip155]?.[id]);\n }\n\n const { namespace, reference } = parseCaipChainId(id);\n const namespaceMap = map[namespace];\n if (!namespaceMap) {\n return false;\n }\n\n // exact CAIP-2 id / reference\n if (namespaceMap[id] || namespaceMap[reference]) {\n return true;\n }\n\n // EVM: hex storage key\n if (namespace === KnownCaipNamespace.Eip155) {\n try {\n const storageKey = toHex(reference);\n return Boolean(namespaceMap[storageKey]);\n } catch {\n const parsedRef = Number.parseInt(reference, 10);\n if (Number.isFinite(parsedRef)) {\n return Boolean(namespaceMap[`0x${parsedRef.toString(16)}`]);\n }\n }\n }\n\n return false;\n};\n\n/**\n * Cache parsing results per assetId to avoid parseCaipAssetType/parseCaipChainId\n * being called multiple times across filtering + grouping + pricing.\n */\ntype AssetParseInfo = {\n chainId: CaipChainId;\n isEvm: boolean;\n};\n\nconst makeAssetInfoCache = (): Map<Caip19AssetId, AssetParseInfo> =>\n new Map<Caip19AssetId, AssetParseInfo>();\n\nconst getAssetInfo = (\n cache: Map<Caip19AssetId, AssetParseInfo>,\n assetId: Caip19AssetId,\n): AssetParseInfo => {\n const cached = cache.get(assetId);\n if (cached) {\n return cached;\n }\n const { chainId } = parseCaipAssetType(assetId);\n const { namespace } = parseCaipChainId(chainId);\n const info = { chainId, isEvm: namespace === KnownCaipNamespace.Eip155 };\n cache.set(assetId, info);\n return info;\n};\n\n/**\n * Merge across accounts without building per-account entries arrays.\n * Uses BigNumber for amount accumulation to avoid float precision loss.\n */\ntype AggRow = {\n amount: BigNumberJS;\n decimals?: number;\n symbol?: string;\n name?: string;\n};\n\nfunction mergeBalancesIntoMap(args: {\n out: Map<Caip19AssetId, AggRow>;\n accountBalances: Record<Caip19AssetId, AssetBalance>;\n metadata: Record<Caip19AssetId, AssetMetadata>;\n assetPreferences?: Record<Caip19AssetId, AssetPreferences>;\n enabledNetworkMap?: EnabledNetworkMap;\n assetInfoCache: Map<Caip19AssetId, AssetParseInfo>;\n}): void {\n const {\n out,\n accountBalances,\n metadata,\n assetPreferences,\n enabledNetworkMap,\n assetInfoCache,\n } = args;\n\n for (const assetId in accountBalances) {\n if (!Object.prototype.hasOwnProperty.call(accountBalances, assetId)) {\n continue;\n }\n const typedAssetId = assetId as Caip19AssetId;\n\n if (assetPreferences?.[typedAssetId]?.hidden) {\n continue;\n }\n\n const info = getAssetInfo(assetInfoCache, typedAssetId);\n if (!isChainEnabledByMap(enabledNetworkMap, info.chainId)) {\n continue;\n }\n\n const amountStr = getAmountFromBalance(accountBalances[typedAssetId]);\n let amountBn = toBigNumberOrZero(amountStr);\n const meta = metadata[typedAssetId];\n if (meta?.decimals !== undefined) {\n amountBn = scaleToHumanIfRaw(amountBn, meta.decimals);\n }\n if (amountBn.isZero()) {\n continue; // skip zeros early to reduce map pressure\n }\n\n const existing = out.get(typedAssetId);\n if (existing) {\n existing.amount = existing.amount.plus(amountBn);\n continue;\n }\n\n out.set(typedAssetId, {\n amount: amountBn,\n decimals: meta?.decimals,\n symbol: meta?.symbol,\n name: meta?.name,\n });\n }\n}\n\nexport function getGroupIdForAccount(\n accountTreeState: AccountTreeControllerState,\n accountId: AccountId,\n): string | undefined {\n const wallets = accountTreeState.accountTree?.wallets;\n if (!wallets) {\n return undefined;\n }\n for (const wallet of Object.values(wallets)) {\n for (const [groupId, group] of Object.entries(wallet?.groups ?? {})) {\n const accounts = group?.accounts;\n if (Array.isArray(accounts) && accounts.includes(accountId)) {\n return groupId;\n }\n }\n }\n return undefined;\n}\n\nexport function getInternalAccountsForGroup(\n accountTreeState: AccountTreeControllerState,\n accountsById: AccountsById,\n groupId: string,\n): InternalAccount[] {\n const wallets = accountTreeState.accountTree?.wallets;\n if (!wallets) {\n return [];\n }\n type GroupWithAccounts = { accounts?: AccountId[] };\n const getGroups = (\n walletItem: (typeof wallets)[keyof typeof wallets],\n ): Record<string, GroupWithAccounts> =>\n (walletItem?.groups ?? {}) as Record<string, GroupWithAccounts>;\n\n for (const wallet of Object.values(wallets)) {\n const group = getGroups(wallet)[groupId];\n if (!group?.accounts) {\n continue;\n }\n const result: InternalAccount[] = [];\n for (const id of group.accounts) {\n const acct = accountsById[id];\n if (acct) {\n result.push(acct);\n }\n }\n return result;\n }\n return [];\n}\n\nfunction getAccountIdsInSameGroup(\n accountTreeState: AccountTreeControllerState,\n selectedAccountId: AccountId,\n): AccountId[] | undefined {\n const groupId = getGroupIdForAccount(accountTreeState, selectedAccountId);\n if (!groupId) {\n return undefined;\n }\n const wallets = accountTreeState.accountTree?.wallets;\n if (!wallets) {\n return undefined;\n }\n type GroupWithAccounts = { accounts?: AccountId[] };\n const getGroups = (\n walletItem: (typeof wallets)[keyof typeof wallets],\n ): Record<string, GroupWithAccounts> =>\n (walletItem?.groups ?? {}) as Record<string, GroupWithAccounts>;\n\n for (const wallet of Object.values(wallets)) {\n const group = getGroups(wallet)[groupId];\n if (group?.accounts) {\n return [...group.accounts];\n }\n }\n return undefined;\n}\n\nfunction resolveAccountsToAggregate(args: {\n selectedInternalAccount: InternalAccount;\n accountTreeState?: AccountTreeControllerState;\n internalAccountsOrAccountIds?: InternalAccount[] | AccountId[];\n accountsById?: AccountsById;\n}): AccountLike[] {\n const {\n selectedInternalAccount,\n accountTreeState,\n internalAccountsOrAccountIds,\n accountsById,\n } = args;\n\n if (internalAccountsOrAccountIds && internalAccountsOrAccountIds.length > 0) {\n const first = internalAccountsOrAccountIds[0];\n if (typeof first === 'string') {\n const ids = internalAccountsOrAccountIds as AccountId[];\n const out: AccountLike[] = new Array(ids.length);\n for (let i = 0; i < ids.length; i++) {\n out[i] = { id: ids[i] };\n }\n return out;\n }\n return internalAccountsOrAccountIds as InternalAccount[];\n }\n\n if (\n accountTreeState &&\n accountsById &&\n Object.keys(accountsById).length > 0\n ) {\n const groupId = getGroupIdForAccount(\n accountTreeState,\n selectedInternalAccount.id,\n );\n if (groupId) {\n const groupAccounts = getInternalAccountsForGroup(\n accountTreeState,\n accountsById,\n groupId,\n );\n if (groupAccounts.length > 0) {\n return groupAccounts;\n }\n }\n }\n\n if (accountTreeState) {\n const ids = getAccountIdsInSameGroup(\n accountTreeState,\n selectedInternalAccount.id,\n );\n if (ids && ids.length > 0) {\n const out: AccountLike[] = new Array(ids.length);\n for (let i = 0; i < ids.length; i++) {\n out[i] = { id: ids[i] };\n }\n return out;\n }\n }\n\n return [selectedInternalAccount];\n}\n\n/**\n * Get account ids that belong to a group, reading directly from the account\n * tree. Unlike {@link getInternalAccountsForGroup}, this does not require an\n * `accountsById` lookup map, which makes it convenient for balance aggregation\n * where only the ids are needed.\n *\n * @param accountTreeState - AccountTreeController state.\n * @param groupId - The account group id to look up.\n * @returns The list of account ids in the group, or an empty array.\n */\nexport function getAccountIdsForGroup(\n accountTreeState: AccountTreeControllerState,\n groupId: string,\n): AccountId[] {\n const wallets = accountTreeState.accountTree?.wallets ?? {};\n type GroupWithAccounts = { accounts?: AccountId[] };\n for (const wallet of Object.values(wallets)) {\n const groups = (wallet?.groups ?? {}) as Record<string, GroupWithAccounts>;\n const group = groups[groupId];\n if (group?.accounts) {\n return [...group.accounts];\n }\n }\n return [];\n}\n\n/**\n * Aggregate balances across an explicit list of accounts.\n *\n * This is the core aggregation engine shared by the account- and group-level\n * selectors. It intentionally takes a fully-resolved list of accounts so that\n * callers control account resolution and no \"selected account\" placeholder is\n * required.\n *\n * @param state - AssetsController state slice.\n * @param accounts - Accounts whose balances should be aggregated.\n * @param enabledNetworkMap - Optional map of enabled networks keyed by namespace.\n * @param trace - Optional trace callback for telemetry spans.\n * @returns Aggregated balance entries plus fiat totals when prices are present.\n */\nfunction aggregateBalances(\n state: AssetsControllerState,\n accounts: AccountLike[],\n enabledNetworkMap?: EnabledNetworkMap,\n trace?: TraceCallback,\n): AggregatedBalanceForAccount {\n const startTime = trace ? performance.now() : 0;\n const { assetsBalance, assetsInfo, assetPreferences, assetsPrice } = state;\n\n const metadata = (assetsInfo ?? {}) as Record<Caip19AssetId, AssetMetadata>;\n\n const hasPrices =\n Boolean(assetsPrice) &&\n ((): boolean => {\n for (const key in assetsPrice) {\n if (Object.prototype.hasOwnProperty.call(assetsPrice, key)) {\n return true;\n }\n }\n return false;\n })();\n\n const accountsToAggregate = accounts;\n\n const assetInfoCache = makeAssetInfoCache();\n const merged = new Map<Caip19AssetId, AggRow>();\n\n for (const account of accountsToAggregate) {\n const accountId = account.id;\n const accountBalances =\n assetsBalance?.[accountId] ?? ({} as Record<Caip19AssetId, AssetBalance>);\n\n mergeBalancesIntoMap({\n out: merged,\n accountBalances,\n metadata,\n assetPreferences,\n enabledNetworkMap,\n assetInfoCache,\n });\n }\n\n // Materialize entries once\n const entries: AggregatedBalanceEntry[] = new Array(merged.size);\n let idx = 0;\n\n // If prices exist, compute totals in a single pass over merged.\n let totalBalanceInFiat = 0;\n let previousTotalInFiat = 0;\n let weightedNumerator = 0;\n\n for (const [assetId, row] of merged.entries()) {\n const { amount } = row;\n const entry: AggregatedBalanceEntry = {\n assetId,\n amount: amount.toFixed(),\n ...(row.decimals === undefined ? {} : { decimals: row.decimals }),\n ...(row.symbol === undefined ? {} : { symbol: row.symbol }),\n ...(row.name === undefined ? {} : { name: row.name }),\n };\n entries[idx] = entry;\n idx += 1;\n\n if (hasPrices) {\n const { price, pricePercentChange1d } = getPriceDatumFast(\n assetsPrice,\n assetId,\n );\n const contribution = amount.multipliedBy(price).toNumber();\n if (contribution > 0) {\n totalBalanceInFiat += contribution;\n weightedNumerator += contribution * pricePercentChange1d;\n\n // A -100% move makes the denominator zero; treat it as flat so the\n // previous total never goes to infinity.\n const denom = Number((1 + pricePercentChange1d / 100).toFixed(8));\n previousTotalInFiat +=\n denom === 0 ? contribution : contribution / denom;\n }\n }\n }\n\n if (trace) {\n const durationMs = performance.now() - startTime;\n const uniqueNetworks = new Set<CaipChainId>();\n for (const assetId of merged.keys()) {\n const info = getAssetInfo(assetInfoCache, assetId);\n uniqueNetworks.add(info.chainId);\n }\n trace(\n {\n name: TRACE_AGGREGATED_BALANCE_SELECTOR,\n data: {\n duration_ms: durationMs,\n asset_count: merged.size,\n network_count: uniqueNetworks.size,\n account_count: accountsToAggregate.length,\n },\n tags: { controller: 'AssetsController' },\n },\n () => undefined,\n ).catch(() => {\n // Telemetry failure must not break.\n });\n }\n\n if (hasPrices) {\n const pricePercentChange1d =\n totalBalanceInFiat > 0 ? weightedNumerator / totalBalanceInFiat : 0;\n return {\n entries,\n totalBalanceInFiat,\n pricePercentChange1d,\n previousTotalInFiat,\n };\n }\n\n return { entries };\n}\n\n/**\n * Aggregate balances for an explicit list of account ids.\n *\n * Prefer this over {@link getAggregatedBalanceForAccount} when the set of\n * accounts to aggregate is already known (e.g. all accounts in a group), since\n * it does not require a \"selected account\" and therefore avoids the brittle\n * account-resolution heuristics.\n *\n * @param state - AssetsController state slice.\n * @param accountIds - Account ids whose balances should be aggregated.\n * @param enabledNetworkMap - Optional map of enabled networks keyed by namespace.\n * @param trace - Optional trace callback for telemetry spans.\n * @returns Aggregated balance entries plus fiat totals when prices are present.\n */\nexport function getAggregatedBalanceForAccountIds(\n state: AssetsControllerState,\n accountIds: AccountId[],\n enabledNetworkMap?: EnabledNetworkMap,\n trace?: TraceCallback,\n): AggregatedBalanceForAccount {\n const accounts: AccountLike[] = accountIds.map((id) => ({ id }));\n return aggregateBalances(state, accounts, enabledNetworkMap, trace);\n}\n\nexport function getAggregatedBalanceForAccount(\n state: AssetsControllerState,\n selectedInternalAccount: InternalAccount,\n enabledNetworkMap?: EnabledNetworkMap,\n accountTreeState?: AccountTreeControllerState,\n internalAccountsOrAccountIds?: InternalAccount[] | AccountId[],\n accountsById?: AccountsById,\n trace?: TraceCallback,\n): AggregatedBalanceForAccount {\n const accountsToAggregate = resolveAccountsToAggregate({\n selectedInternalAccount,\n accountTreeState,\n internalAccountsOrAccountIds,\n accountsById,\n });\n return aggregateBalances(\n state,\n accountsToAggregate,\n enabledNetworkMap,\n trace,\n );\n}\n\n// ============================================================================\n// WALLET- AND GROUP-LEVEL BALANCE CALCULATIONS\n// ============================================================================\n\n/**\n * Default user currency used when {@link AssetsControllerState.selectedCurrency}\n * is not set.\n */\nconst DEFAULT_USER_CURRENCY = 'usd';\n\nexport type AccountGroupBalance = {\n walletId: string;\n groupId: string;\n totalBalanceInUserCurrency: number;\n userCurrency: string;\n};\n\nexport type WalletBalance = {\n walletId: string;\n groups: Record<string, AccountGroupBalance>;\n totalBalanceInUserCurrency: number;\n userCurrency: string;\n};\n\nexport type AllWalletsBalance = {\n wallets: Record<string, WalletBalance>;\n totalBalanceInUserCurrency: number;\n userCurrency: string;\n};\n\nexport type BalanceChangePeriod = '1d' | '7d' | '30d';\n\nexport type BalanceChangeResult = {\n period: BalanceChangePeriod;\n currentTotalInUserCurrency: number;\n previousTotalInUserCurrency: number;\n amountChangeInUserCurrency: number;\n percentChange: number;\n userCurrency: string;\n};\n\n/**\n * Resolve the user currency for a balance calculation, falling back to a\n * sensible default when the controller has no selected currency.\n *\n * @param assetsControllerState - AssetsController state slice.\n * @returns The user currency code.\n */\nfunction getUserCurrency(assetsControllerState: AssetsControllerState): string {\n return assetsControllerState.selectedCurrency ?? DEFAULT_USER_CURRENCY;\n}\n\n/**\n * Resolve the current and previous totals for a change calculation.\n *\n * The AssetsController state only exposes a 1d price change, so non-`1d`\n * periods produce a zeroed change (previous equals current).\n *\n * @param totalBalanceInFiat - Aggregated current balance in user currency.\n * @param previousTotalInFiat - Aggregated prior balance summed per asset.\n * @param period - Period to compute the change for.\n * @returns The current and previous totals in user currency.\n */\nfunction getCurrentAndPrevious(\n totalBalanceInFiat: number,\n previousTotalInFiat: number,\n period: BalanceChangePeriod,\n): { current: number; previous: number } {\n const current = totalBalanceInFiat;\n const previous = period === '1d' ? previousTotalInFiat : current;\n return { current, previous };\n}\n\n/**\n * Build a {@link BalanceChangeResult} from current/previous totals.\n *\n * @param current - Current total in user currency.\n * @param previous - Previous total in user currency.\n * @param period - Period the change was computed for.\n * @param userCurrency - User currency code.\n * @returns The change result with delta and percent change.\n */\nfunction buildBalanceChangeResult(\n current: number,\n previous: number,\n period: BalanceChangePeriod,\n userCurrency: string,\n): BalanceChangeResult {\n const amountChange = current - previous;\n const percentChange = previous === 0 ? 0 : (amountChange / previous) * 100;\n return {\n period,\n currentTotalInUserCurrency: Number(current.toFixed(8)),\n previousTotalInUserCurrency: Number(previous.toFixed(8)),\n amountChangeInUserCurrency: Number(amountChange.toFixed(8)),\n percentChange: Number(percentChange.toFixed(8)),\n userCurrency,\n };\n}\n\n/**\n * Calculate aggregated balances for all wallets and groups.\n *\n * Mirrors the legacy `@metamask/assets-controllers` `calculateBalanceForAllWallets`\n * output shape, but sources every group total from the unified AssetsController\n * state via {@link getAggregatedBalanceForAccountIds}. The account tree is walked\n * to aggregate each group individually.\n *\n * @param assetsControllerState - AssetsController state slice.\n * @param accountTreeState - AccountTreeController state.\n * @param enabledNetworkMap - Map of enabled networks keyed by namespace.\n * @param trace - Optional trace callback forwarded to the aggregation selector.\n * @returns Aggregated balances for all wallets and groups.\n */\nexport function calculateBalanceForAllWallets(\n assetsControllerState: AssetsControllerState,\n accountTreeState: AccountTreeControllerState,\n enabledNetworkMap?: EnabledNetworkMap,\n trace?: TraceCallback,\n): AllWalletsBalance {\n const userCurrency = getUserCurrency(assetsControllerState);\n const wallets: AllWalletsBalance['wallets'] = {};\n let totalBalanceInUserCurrency = 0;\n\n type WalletWithGroups = { groups?: Record<string, unknown> };\n for (const [walletId, wallet] of Object.entries(\n accountTreeState.accountTree?.wallets ?? {},\n )) {\n const walletBalance: WalletBalance = {\n walletId,\n groups: {},\n totalBalanceInUserCurrency: 0,\n userCurrency,\n };\n\n const groups = (wallet as WalletWithGroups)?.groups ?? {};\n for (const groupId of Object.keys(groups)) {\n const accountIds = getAccountIdsForGroup(accountTreeState, groupId);\n const { totalBalanceInFiat = 0 } = getAggregatedBalanceForAccountIds(\n assetsControllerState,\n accountIds,\n enabledNetworkMap,\n trace,\n );\n\n walletBalance.groups[groupId] = {\n walletId,\n groupId,\n totalBalanceInUserCurrency: totalBalanceInFiat,\n userCurrency,\n };\n walletBalance.totalBalanceInUserCurrency += totalBalanceInFiat;\n }\n\n wallets[walletId] = walletBalance;\n totalBalanceInUserCurrency += walletBalance.totalBalanceInUserCurrency;\n }\n\n return { wallets, totalBalanceInUserCurrency, userCurrency };\n}\n\n/**\n * Calculate the portfolio value change for a single account group and period.\n *\n * @param assetsControllerState - AssetsController state slice.\n * @param accountTreeState - AccountTreeController state.\n * @param groupId - Account group id to compute the change for.\n * @param period - Change period (`1d` | `7d` | `30d`).\n * @param enabledNetworkMap - Map of enabled networks keyed by namespace.\n * @param trace - Optional trace callback forwarded to the aggregation selector.\n * @returns The change result for the requested period.\n */\nexport function calculateBalanceChangeForAccountGroup(\n assetsControllerState: AssetsControllerState,\n accountTreeState: AccountTreeControllerState,\n groupId: string,\n period: BalanceChangePeriod,\n enabledNetworkMap?: EnabledNetworkMap,\n trace?: TraceCallback,\n): BalanceChangeResult {\n const userCurrency = getUserCurrency(assetsControllerState);\n const accountIds = getAccountIdsForGroup(accountTreeState, groupId);\n const { totalBalanceInFiat = 0, previousTotalInFiat = totalBalanceInFiat } =\n getAggregatedBalanceForAccountIds(\n assetsControllerState,\n accountIds,\n enabledNetworkMap,\n trace,\n );\n\n const { current, previous } = getCurrentAndPrevious(\n totalBalanceInFiat,\n previousTotalInFiat,\n period,\n );\n\n return buildBalanceChangeResult(current, previous, period, userCurrency);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"types.cjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAyfA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,SAAgB,YAAY,CAC1B,SAAqB,EACrB,UAAsB;IAEtB,OAAO,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACzB,MAAM,cAAc,GAAG,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC;QAC7C,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;QAEtE,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;QAED,OAAO,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC;AACJ,CAAC;AAdD,oCAcC","sourcesContent":["import type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { CaipAssetType, CaipChainId, Json } from '@metamask/utils';\n\n/**\n * CAIP-19 compliant asset identifier\n * Format: \"{chainId}/{assetNamespace}:{assetReference}[/tokenId]\"\n *\n * Examples:\n * - Native: \"eip155:1/slip44:60\" (ETH)\n * - ERC20: \"eip155:1/erc20:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\" (USDC)\n * - ERC721: \"eip155:1/erc721:0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D/1234\" (BAYC #1234)\n * - SPL: \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/token:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\"\n */\nexport type Caip19AssetId = CaipAssetType;\n\n/**\n * InternalAccount UUID from AccountsController\n * Not the blockchain address!\n */\nexport type AccountId = string;\n\n/**\n * CAIP-2 chain identifier\n */\nexport type ChainId = CaipChainId;\n\n// ============================================================================\n// ASSET TYPES - Defined by metadata structure\n// ============================================================================\n\n/**\n * Asset types define the metadata structure, not blockchain implementation.\n * - \"fungible\" includes: native, erc20, spl - all share balance, symbol, decimals\n * - \"nft\" includes: erc721, erc1155 - include tokenId, image, attributes\n */\nexport type AssetType = 'fungible' | 'nft' | 'collectible';\n\n/**\n * Token standards - blockchain implementation details\n */\nexport type TokenStandard =\n | 'native'\n | 'erc20'\n | 'erc721'\n | 'erc1155'\n | 'spl'\n | string;\n\n// ============================================================================\n// METADATA TYPES (vary by asset type)\n// ============================================================================\n\n/**\n * UI preferences for an asset (stored in assetPreferences state, not in metadata).\n */\nexport type AssetPreferences = {\n /** Whether the asset is hidden from display */\n hidden?: boolean;\n};\n\n/**\n * Base metadata attributes shared by ALL asset types.\n */\nexport type BaseAssetMetadata = {\n /** Token standard - how it's implemented on the blockchain */\n type: TokenStandard;\n /** Display symbol (e.g., \"ETH\", \"USDC\") */\n symbol: string;\n /** Full name (e.g., \"Ethereum\", \"USD Coin\") */\n name: string;\n /** Token decimals (18 for ETH, 6 for USDC, etc.) */\n decimals: number;\n /** Logo URL or data URI */\n image?: string;\n};\n\n// ============================================================================\n// TOKEN CONTRACT DATA TYPES\n// ============================================================================\n\n/** Fee information for token transfers */\nexport type TokenFees = {\n avgFee: number;\n maxFee: number;\n minFee: number;\n};\n\n/** Honeypot detection status */\nexport type HoneypotStatus = {\n honeypotIs: boolean;\n goPlus?: boolean;\n};\n\n/** Storage slot information for the contract */\nexport type StorageSlots = {\n balance: number;\n approval: number;\n};\n\n/** Localized description */\nexport type LocalizedDescription = {\n en: string;\n};\n\n// ============================================================================\n// ASSET METADATA TYPES\n// ============================================================================\n\n/**\n * Metadata for fungible tokens.\n * Structure mirrors V3AssetResponse from the Tokens API.\n *\n * Differences from V3AssetResponse:\n * - `type` is derived from assetId namespace (not in API response)\n * - `image` maps from API's `iconUrl`\n * - `assetId` is not stored (used as the key)\n */\nexport type FungibleAssetMetadata = {\n /** Token type derived from assetId namespace */\n type: 'native' | 'erc20' | 'spl';\n /** CoinGecko ID for price lookups */\n coingeckoId?: string;\n /** Number of token list occurrences */\n occurrences?: number;\n /** DEX/aggregator integrations */\n aggregators?: string[];\n /** Asset labels/tags (e.g., \"stable_coin\") */\n labels?: string[];\n /** Whether the token supports ERC-20 permit */\n erc20Permit?: boolean;\n /** Fee information for token transfers */\n fees?: TokenFees;\n /** Honeypot detection status */\n honeypotStatus?: HoneypotStatus;\n /** Storage slot information for the contract */\n storage?: StorageSlots;\n /** Whether the contract is verified */\n isContractVerified?: boolean;\n /** Localized description */\n description?: LocalizedDescription;\n} & BaseAssetMetadata;\n\n/**\n * Metadata for ERC721 NFTs\n * Asset Type: \"nft\"\n */\nexport type ERC721AssetMetadata = {\n type: 'erc721';\n decimals: 0;\n /** Collection name */\n collectionName?: string;\n /** Collection size */\n collectionSize?: number;\n /** NFT traits/attributes - must be Json-serializable */\n traits?: Record<string, Json>;\n /** Rarity score */\n rarity?: number;\n /** Verification status */\n verified?: boolean;\n} & BaseAssetMetadata;\n\n/**\n * Metadata for ERC1155 multi-tokens\n */\nexport type ERC1155AssetMetadata = {\n type: 'erc1155';\n /** Token URI */\n tokenUri?: string;\n /** Token category */\n category?: string;\n /** Spam detection flag */\n isSpam?: boolean;\n} & BaseAssetMetadata;\n\n/**\n * Union type representing all possible asset metadata types.\n * All types must be JSON-serializable.\n */\nexport type AssetMetadata =\n | FungibleAssetMetadata\n | ERC721AssetMetadata\n | ERC1155AssetMetadata\n | (BaseAssetMetadata & { [key: string]: Json });\n\n// ============================================================================\n// PRICE TYPES (vary by asset type)\n// ============================================================================\n\n/**\n * Base price attributes.\n */\nexport type BaseAssetPrice = {\n /** Current price in selected currency */\n price: number;\n /** Timestamp of last price update */\n lastUpdated: number;\n};\n\n/**\n * Price data for fungible tokens (native, ERC20, SPL)\n * Matches V3SpotPricesResponse from the Price API.\n */\nexport type FungibleAssetPrice = BaseAssetPrice & {\n assetPriceType: 'fungible';\n /** CoinGecko ID */\n id?: string;\n /** Market capitalization */\n marketCap?: number;\n /** All-time high price */\n allTimeHigh?: number;\n /** All-time low price */\n allTimeLow?: number;\n /** 24h trading volume */\n totalVolume?: number;\n /** 24h high price */\n high1d?: number;\n /** 24h low price */\n low1d?: number;\n /** Circulating supply */\n circulatingSupply?: number;\n /** Fully diluted market cap */\n dilutedMarketCap?: number;\n /** 24h market cap change percentage */\n marketCapPercentChange1d?: number;\n /** 24h price change in USD */\n priceChange1d?: number;\n /** 1h price change percentage */\n pricePercentChange1h?: number;\n /** 24h price change percentage */\n pricePercentChange1d?: number;\n /** 7d price change percentage */\n pricePercentChange7d?: number;\n /** 14d price change percentage */\n pricePercentChange14d?: number;\n /** 30d price change percentage */\n pricePercentChange30d?: number;\n /** 200d price change percentage */\n pricePercentChange200d?: number;\n /** 1y price change percentage */\n pricePercentChange1y?: number;\n /** Current price in USD */\n usdPrice: number;\n};\n\n/**\n * Price data for NFT collections\n */\nexport type NFTAssetPrice = BaseAssetPrice & {\n assetPriceType: 'nft';\n /** Floor price */\n floorPrice?: number;\n /** Last sale price */\n lastSalePrice?: number;\n /** Collection trading volume */\n collectionVolume?: number;\n /** Average price */\n averagePrice?: number;\n /** Number of sales in 24h */\n sales24h?: number;\n};\n\n/**\n * Union type representing all possible asset price types.\n * All types must be JSON-serializable.\n */\nexport type AssetPrice = FungibleAssetPrice | NFTAssetPrice;\n\n// ============================================================================\n// BALANCE TYPES (vary by asset type)\n// ============================================================================\n\n/**\n * Balance data for fungible tokens (native, ERC20, SPL).\n */\nexport type FungibleAssetBalance = {\n /** Raw balance amount as string (e.g., \"1000000000\" for 1000 USDC) */\n amount: string;\n};\n\n/**\n * Balance data for ERC721 NFTs.\n * Each tokenId has its own CAIP-19 asset ID, so always \"1\".\n */\nexport type ERC721AssetBalance = {\n /** Always \"1\" for ERC721 (non-fungible) */\n amount: '1';\n};\n\n/**\n * Balance data for ERC1155 multi-tokens.\n */\nexport type ERC1155AssetBalance = {\n /** Quantity owned of this specific tokenId */\n amount: string;\n};\n\n/**\n * Union type representing all possible asset balance types.\n * All types must be JSON-serializable.\n */\nexport type AssetBalance =\n | FungibleAssetBalance\n | ERC721AssetBalance\n | ERC1155AssetBalance\n | { amount: string; [key: string]: Json };\n\n// ============================================================================\n// DATA SOURCE TYPES\n// ============================================================================\n\n/**\n * Data type dimension - what kind of data\n */\nexport type DataType = 'balance' | 'metadata' | 'price';\n\n/**\n * Account with its supported chains (enabled chains ∩ account scope).\n * Pre-computed by the controller so data sources do not need to implement\n * account-scope logic; they iterate over supportedChains for each account.\n */\nexport type AccountWithSupportedChains = {\n account: InternalAccount;\n supportedChains: ChainId[];\n};\n\n/**\n * Request for data from data sources\n */\nexport type DataRequest = {\n /** Accounts with their supported chains (enabled ∩ account scope). Data sources use this instead of computing accountSupportsChain. */\n accountsWithSupportedChains: AccountWithSupportedChains[];\n /** CAIP-2 chain IDs (union of chains in this request) */\n chainIds: ChainId[];\n /** Filter by asset types */\n assetTypes?: AssetType[];\n /** Which data to fetch */\n dataTypes: DataType[];\n /** Specific CAIP-19 asset IDs */\n customAssets?: Caip19AssetId[];\n /**\n * When true, the data source should poll only the user's `customAssets`\n * for the requested chains and skip refreshing the regular tracked\n * balances. Used by the AssetsController to issue a supplemental RPC\n * subscription on chains that another data source is already covering.\n */\n customAssetsOnly?: boolean;\n /** Force fresh fetch, bypass cache */\n forceUpdate?: boolean;\n /** Hint for polling interval (ms) - used by data sources that implement polling */\n updateInterval?: number;\n /** Specific CAIP-19 asset IDs for price update */\n assetsForPriceUpdate?: Caip19AssetId[];\n};\n\n/**\n * Response from data sources\n */\nexport type DataResponse = {\n /** Metadata for assets (shared across accounts) */\n assetsInfo?: Record<Caip19AssetId, AssetMetadata>;\n /** Price data for assets (shared across accounts) */\n assetsPrice?: Record<Caip19AssetId, AssetPrice>;\n /** Balance data per account */\n assetsBalance?: Record<AccountId, Record<Caip19AssetId, AssetBalance>>;\n /** Errors encountered, keyed by chain ID */\n errors?: Record<ChainId, string>;\n /** Detected assets (assets that do not have metadata) */\n detectedAssets?: Record<AccountId, Caip19AssetId[]>;\n /**\n * How to apply this response to state. See {@link AssetsUpdateMode}.\n * Defaults to `'merge'` if omitted.\n */\n updateMode?: AssetsUpdateMode;\n};\n\n/**\n * Type of {@link DataResponse.updateMode}: how the controller applies the response to state.\n *\n * - **full**: Response is the full set for the scope. Assets in state but not in the\n * response are cleared (except custom assets). Use for initial fetch or full refresh.\n * - **merge**: Only assets present in the response are updated; nothing is removed.\n * Use for event-driven or incremental updates.\n */\nexport type AssetsUpdateMode = 'full' | 'merge';\n\n// ============================================================================\n// DATA SOURCE <-> CONTROLLER (DIRECT CALLS, NO MESSENGER PER SOURCE)\n// ============================================================================\n\n/**\n * Callbacks for data sources to report to AssetsController.\n * Passed to data sources so they report by direct call instead of messenger.\n */\nexport type AssetsControllerReport = {\n onActiveChainsUpdate: (dataSourceId: string, activeChains: ChainId[]) => void;\n onAssetsUpdate: (response: DataResponse, sourceId: string) => Promise<void>;\n};\n\n/** Request passed from controller to data source when subscribing */\nexport type DataSourceSubscriptionRequest = {\n request: DataRequest;\n subscriptionId: string;\n isUpdate: boolean;\n};\n\n/**\n * Interface for balance data sources that the controller calls directly.\n * No messenger is required for controller <-> data source communication.\n */\nexport type BalanceDataSource = {\n getAssetsMiddleware: () => Middleware;\n subscribe: (request: DataSourceSubscriptionRequest) => Promise<void>;\n unsubscribe: (subscriptionId: string) => Promise<void>;\n getName: () => string;\n};\n\n/**\n * Interface for the price data source (subscribe/unsubscribe + middleware).\n * Controller calls these methods directly.\n */\nexport type PriceDataSourceInterface = {\n getAssetsMiddleware: () => Middleware;\n subscribe: (request: DataSourceSubscriptionRequest) => Promise<void>;\n unsubscribe: (subscriptionId: string) => Promise<void>;\n};\n\n/**\n * Middleware-only source (e.g. detection, token enrichment).\n * Controller calls getAssetsMiddleware() directly.\n */\nexport type MiddlewareDataSource = {\n getAssetsMiddleware: () => Middleware;\n};\n\n// ============================================================================\n// UNIFIED MIDDLEWARE TYPES\n// ============================================================================\n\n/**\n * Internal state structure for AssetsController following normalized design.\n *\n * Keys use CAIP identifiers:\n * - assetsInfo keys: CAIP-19 asset IDs (e.g., \"eip155:1/erc20:0x...\")\n * - assetsBalance outer keys: Account IDs (InternalAccount.id UUIDs)\n * - assetsBalance inner keys: CAIP-19 asset IDs\n * - assetsPrice keys: CAIP-19 asset IDs\n * - customAssets outer keys: Account IDs (InternalAccount.id UUIDs)\n * - customAssets inner values: CAIP-19 asset IDs array\n * - assetPreferences keys: CAIP-19 asset IDs\n */\nexport type AssetsControllerStateInternal = {\n /** Shared metadata for all assets (stored once per asset) */\n assetsInfo: Record<Caip19AssetId, AssetMetadata>;\n /** Per-account balance data */\n assetsBalance: Record<AccountId, Record<Caip19AssetId, AssetBalance>>;\n /** Price data for assets */\n assetsPrice: Record<Caip19AssetId, AssetPrice>;\n /** Custom assets added by users per account */\n customAssets: Record<AccountId, Caip19AssetId[]>;\n /** UI preferences per asset (e.g. hidden) - separate from metadata */\n assetPreferences: Record<Caip19AssetId, AssetPreferences>;\n};\n\n/**\n * Base context for all middleware operations.\n * Contains the common interface shared by fetch and subscribe.\n */\nexport type Context = {\n /** The data request */\n request: DataRequest;\n /** The response data (mutated by middlewares) */\n response: DataResponse;\n /** Get current assets state */\n getAssetsState: () => AssetsControllerStateInternal;\n /**\n * Optional breakdown of latency (ms) per data source, e.g. from parallel\n * middlewares. Keys are source names (often \"MiddlewareName.SourceName\").\n * Merged into the controller's durationByDataSource for tracing.\n */\n durationByDataSource?: Record<string, number>;\n};\n\n/**\n * Next function for middleware chain\n */\nexport type NextFunction = (context: Context) => Promise<Context>;\n\n/**\n * Middleware function - works for both fetch and subscribe operations.\n */\nexport type Middleware = (\n context: Context,\n next: NextFunction,\n) => Promise<Context>;\n\n/**\n * An assets data source: any object that can participate in the assets\n * middleware chain with a display name (e.g. for tracing). Used by\n * createParallelMiddleware and by the controller when executing the chain.\n */\nexport type AssetsDataSource = {\n getName(): string;\n assetsMiddleware: Middleware;\n};\n\n/**\n * Wraps a middleware to only execute if specific dataTypes are requested.\n *\n * @param dataTypes - DataTypes that must be in the request for middleware to run\n * @param middleware - The middleware to conditionally execute\n * @returns A middleware that skips execution if none of the dataTypes are requested\n *\n * @example\n * ```typescript\n * // Only runs for metadata requests\n * const metadataMiddleware = forDataTypes(['metadata'], async (ctx, next) => {\n * const result = await next(ctx);\n * // Enrich metadata...\n * return result;\n * });\n *\n * // Runs for balance or price requests\n * const balanceOrPriceMiddleware = forDataTypes(['balance', 'price'], async (ctx, next) => {\n * const result = await next(ctx);\n * // Process balances or prices...\n * return result;\n * });\n * ```\n */\nexport function forDataTypes(\n dataTypes: DataType[],\n middleware: Middleware,\n): Middleware {\n return async (ctx, next) => {\n const requestedTypes = ctx.request.dataTypes;\n const shouldRun = dataTypes.some((dt) => requestedTypes.includes(dt));\n\n if (!shouldRun) {\n return next(ctx);\n }\n\n return middleware(ctx, next);\n };\n}\n\n/**\n * Context for fetch operations.\n * Extends base Context - no additional fields needed for fetch.\n */\nexport type FetchContext = Context;\n\n// Legacy aliases for backwards compatibility\nexport type FetchNextFunction = NextFunction;\nexport type FetchMiddleware = Middleware;\n\n/**\n * Subscription response returned when subscribing to asset updates.\n */\nexport type SubscriptionResponse = {\n /** Chains actively subscribed */\n chains: ChainId[];\n /** Account ID being watched */\n accountId: AccountId;\n /** Asset types being watched */\n assetTypes: AssetType[];\n /** Data types being kept fresh */\n dataTypes: DataType[];\n /** Cleanup function */\n unsubscribe: () => void;\n};\n\n// ============================================================================\n// COMBINED ASSET TYPE (for UI)\n// ============================================================================\n\n/**\n * Combined asset type matching state structure: balance, metadata, price\n */\nexport type Asset = {\n /** CAIP-19 asset ID */\n id: Caip19AssetId;\n /** CAIP-2 chain ID (extracted from id) */\n chainId: ChainId;\n /** Balance data */\n balance: AssetBalance;\n /** Metadata (symbol, name, decimals, etc.) */\n metadata: AssetMetadata;\n /** Price data */\n price: AssetPrice;\n /** Computed fiat value (balance × price) */\n fiatValue: number;\n};\n\n// ============================================================================\n// EVENT TYPES\n// ============================================================================\n\n/**\n * Event emitted when balances change\n */\nexport type BalanceChangeEvent = {\n accountId: AccountId;\n assetId: Caip19AssetId;\n previousAmount: string;\n newAmount: string;\n timestamp: number;\n};\n\n/**\n * Event emitted when prices change\n */\nexport type PriceChangeEvent = {\n assetIds: Caip19AssetId[];\n timestamp: number;\n};\n\n/**\n * Event emitted when metadata changes\n */\nexport type MetadataChangeEvent = {\n assetId: Caip19AssetId;\n changes: Partial<AssetMetadata>;\n};\n\n/**\n * Event emitted when assets without metadata are detected\n */\nexport type AssetsDetectedEvent = {\n accountId: AccountId;\n assetIds: Caip19AssetId[];\n};\n"]}
1
+ {"version":3,"file":"types.cjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAygBA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,SAAgB,YAAY,CAC1B,SAAqB,EACrB,UAAsB;IAEtB,OAAO,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACzB,MAAM,cAAc,GAAG,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC;QAC7C,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;QAEtE,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;QAED,OAAO,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC;AACJ,CAAC;AAdD,oCAcC","sourcesContent":["import type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { CaipAssetType, CaipChainId, Json } from '@metamask/utils';\n\n/**\n * CAIP-19 compliant asset identifier\n * Format: \"{chainId}/{assetNamespace}:{assetReference}[/tokenId]\"\n *\n * Examples:\n * - Native: \"eip155:1/slip44:60\" (ETH)\n * - ERC20: \"eip155:1/erc20:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\" (USDC)\n * - ERC721: \"eip155:1/erc721:0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D/1234\" (BAYC #1234)\n * - SPL: \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/token:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\"\n */\nexport type Caip19AssetId = CaipAssetType;\n\n/**\n * InternalAccount UUID from AccountsController\n * Not the blockchain address!\n */\nexport type AccountId = string;\n\n/**\n * CAIP-2 chain identifier\n */\nexport type ChainId = CaipChainId;\n\n// ============================================================================\n// ASSET TYPES - Defined by metadata structure\n// ============================================================================\n\n/**\n * Asset types define the metadata structure, not blockchain implementation.\n * - \"fungible\" includes: native, erc20, spl - all share balance, symbol, decimals\n * - \"nft\" includes: erc721, erc1155 - include tokenId, image, attributes\n */\nexport type AssetType = 'fungible' | 'nft' | 'collectible';\n\n/**\n * Token standards - blockchain implementation details\n */\nexport type TokenStandard =\n | 'native'\n | 'erc20'\n | 'erc721'\n | 'erc1155'\n | 'spl'\n | string;\n\n// ============================================================================\n// METADATA TYPES (vary by asset type)\n// ============================================================================\n\n/**\n * UI preferences for an asset (stored in assetPreferences state, not in metadata).\n */\nexport type AssetPreferences = {\n /** Whether the asset is hidden from display */\n hidden?: boolean;\n};\n\n/**\n * Base metadata attributes shared by ALL asset types.\n */\nexport type BaseAssetMetadata = {\n /** Token standard - how it's implemented on the blockchain */\n type: TokenStandard;\n /** Display symbol (e.g., \"ETH\", \"USDC\") */\n symbol: string;\n /** Full name (e.g., \"Ethereum\", \"USD Coin\") */\n name: string;\n /** Token decimals (18 for ETH, 6 for USDC, etc.) */\n decimals: number;\n /** Logo URL or data URI */\n image?: string;\n};\n\n// ============================================================================\n// TOKEN CONTRACT DATA TYPES\n// ============================================================================\n\n/** Fee information for token transfers */\nexport type TokenFees = {\n avgFee: number;\n maxFee: number;\n minFee: number;\n};\n\n/** Honeypot detection status */\nexport type HoneypotStatus = {\n honeypotIs: boolean;\n goPlus?: boolean;\n};\n\n/** Storage slot information for the contract */\nexport type StorageSlots = {\n balance: number;\n approval: number;\n};\n\n/** Localized description */\nexport type LocalizedDescription = {\n en: string;\n};\n\n// ============================================================================\n// ASSET METADATA TYPES\n// ============================================================================\n\n/**\n * Metadata for fungible tokens.\n * Structure mirrors V3AssetResponse from the Tokens API.\n *\n * Differences from V3AssetResponse:\n * - `type` is derived from assetId namespace (not in API response)\n * - `image` maps from API's `iconUrl`\n * - `assetId` is not stored (used as the key)\n */\nexport type FungibleAssetMetadata = {\n /** Token type derived from assetId namespace */\n type: 'native' | 'erc20' | 'spl';\n /** CoinGecko ID for price lookups */\n coingeckoId?: string;\n /** Number of token list occurrences */\n occurrences?: number;\n /** DEX/aggregator integrations */\n aggregators?: string[];\n /** Asset labels/tags (e.g., \"stable_coin\") */\n labels?: string[];\n /** Whether the token supports ERC-20 permit */\n erc20Permit?: boolean;\n /** Fee information for token transfers */\n fees?: TokenFees;\n /** Honeypot detection status */\n honeypotStatus?: HoneypotStatus;\n /** Storage slot information for the contract */\n storage?: StorageSlots;\n /** Whether the contract is verified */\n isContractVerified?: boolean;\n /** Localized description */\n description?: LocalizedDescription;\n} & BaseAssetMetadata;\n\n/**\n * Metadata for ERC721 NFTs\n * Asset Type: \"nft\"\n */\nexport type ERC721AssetMetadata = {\n type: 'erc721';\n decimals: 0;\n /** Collection name */\n collectionName?: string;\n /** Collection size */\n collectionSize?: number;\n /** NFT traits/attributes - must be Json-serializable */\n traits?: Record<string, Json>;\n /** Rarity score */\n rarity?: number;\n /** Verification status */\n verified?: boolean;\n} & BaseAssetMetadata;\n\n/**\n * Metadata for ERC1155 multi-tokens\n */\nexport type ERC1155AssetMetadata = {\n type: 'erc1155';\n /** Token URI */\n tokenUri?: string;\n /** Token category */\n category?: string;\n /** Spam detection flag */\n isSpam?: boolean;\n} & BaseAssetMetadata;\n\n/**\n * Union type representing all possible asset metadata types.\n * All types must be JSON-serializable.\n */\nexport type AssetMetadata =\n | FungibleAssetMetadata\n | ERC721AssetMetadata\n | ERC1155AssetMetadata\n | (BaseAssetMetadata & { [key: string]: Json });\n\n// ============================================================================\n// PRICE TYPES (vary by asset type)\n// ============================================================================\n\n/**\n * Base price attributes.\n */\nexport type BaseAssetPrice = {\n /** Current price in selected currency */\n price: number;\n /** Timestamp of last price update */\n lastUpdated: number;\n};\n\n/**\n * Price data for fungible tokens (native, ERC20, SPL)\n * Matches V3SpotPricesResponse from the Price API.\n */\nexport type FungibleAssetPrice = BaseAssetPrice & {\n assetPriceType: 'fungible';\n /** CoinGecko ID */\n id?: string;\n /** Market capitalization */\n marketCap?: number;\n /** All-time high price */\n allTimeHigh?: number;\n /** All-time low price */\n allTimeLow?: number;\n /** 24h trading volume */\n totalVolume?: number;\n /** 24h high price */\n high1d?: number;\n /** 24h low price */\n low1d?: number;\n /** Circulating supply */\n circulatingSupply?: number;\n /** Fully diluted market cap */\n dilutedMarketCap?: number;\n /** 24h market cap change percentage */\n marketCapPercentChange1d?: number;\n /** 24h price change in USD */\n priceChange1d?: number;\n /** 1h price change percentage */\n pricePercentChange1h?: number;\n /** 24h price change percentage */\n pricePercentChange1d?: number;\n /** 7d price change percentage */\n pricePercentChange7d?: number;\n /** 14d price change percentage */\n pricePercentChange14d?: number;\n /** 30d price change percentage */\n pricePercentChange30d?: number;\n /** 200d price change percentage */\n pricePercentChange200d?: number;\n /** 1y price change percentage */\n pricePercentChange1y?: number;\n /** Current price in USD */\n usdPrice: number;\n};\n\n/**\n * Price data for NFT collections\n */\nexport type NFTAssetPrice = BaseAssetPrice & {\n assetPriceType: 'nft';\n /** Floor price */\n floorPrice?: number;\n /** Last sale price */\n lastSalePrice?: number;\n /** Collection trading volume */\n collectionVolume?: number;\n /** Average price */\n averagePrice?: number;\n /** Number of sales in 24h */\n sales24h?: number;\n};\n\n/**\n * Union type representing all possible asset price types.\n * All types must be JSON-serializable.\n */\nexport type AssetPrice = FungibleAssetPrice | NFTAssetPrice;\n\n// ============================================================================\n// BALANCE TYPES (vary by asset type)\n// ============================================================================\n\n/**\n * Balance data for fungible tokens (native, ERC20, SPL).\n */\nexport type FungibleAssetBalance = {\n /** Raw balance amount as string (e.g., \"1000000000\" for 1000 USDC) */\n amount: string;\n};\n\n/**\n * Balance data for ERC721 NFTs.\n * Each tokenId has its own CAIP-19 asset ID, so always \"1\".\n */\nexport type ERC721AssetBalance = {\n /** Always \"1\" for ERC721 (non-fungible) */\n amount: '1';\n};\n\n/**\n * Balance data for ERC1155 multi-tokens.\n */\nexport type ERC1155AssetBalance = {\n /** Quantity owned of this specific tokenId */\n amount: string;\n};\n\n/**\n * Union type representing all possible asset balance types.\n * All types must be JSON-serializable.\n */\nexport type AssetBalance =\n | FungibleAssetBalance\n | ERC721AssetBalance\n | ERC1155AssetBalance\n | { amount: string; [key: string]: Json };\n\n// ============================================================================\n// DATA SOURCE TYPES\n// ============================================================================\n\n/**\n * Data type dimension - what kind of data\n */\nexport type DataType = 'balance' | 'metadata' | 'price';\n\n/**\n * Account with its supported chains (enabled chains ∩ account scope).\n * Pre-computed by the controller so data sources do not need to implement\n * account-scope logic; they iterate over supportedChains for each account.\n */\nexport type AccountWithSupportedChains = {\n account: InternalAccount;\n supportedChains: ChainId[];\n};\n\n/**\n * Request for data from data sources\n */\nexport type DataRequest = {\n /** Accounts with their supported chains (enabled ∩ account scope). Data sources use this instead of computing accountSupportsChain. */\n accountsWithSupportedChains: AccountWithSupportedChains[];\n /** CAIP-2 chain IDs (union of chains in this request) */\n chainIds: ChainId[];\n /** Filter by asset types */\n assetTypes?: AssetType[];\n /** Which data to fetch */\n dataTypes: DataType[];\n /** Specific CAIP-19 asset IDs */\n customAssets?: Caip19AssetId[];\n /**\n * When true, the data source should poll only the user's `customAssets`\n * for the requested chains and skip refreshing the regular tracked\n * balances. Used by the AssetsController to issue a supplemental RPC\n * subscription on chains that another data source is already covering.\n */\n customAssetsOnly?: boolean;\n /** Force fresh fetch, bypass cache */\n forceUpdate?: boolean;\n /** Hint for polling interval (ms) - used by data sources that implement polling */\n updateInterval?: number;\n /** Specific CAIP-19 asset IDs for price update */\n assetsForPriceUpdate?: Caip19AssetId[];\n};\n\n/**\n * Response from data sources\n */\nexport type DataResponse = {\n /** Metadata for assets (shared across accounts) */\n assetsInfo?: Record<Caip19AssetId, AssetMetadata>;\n /** Price data for assets (shared across accounts) */\n assetsPrice?: Record<Caip19AssetId, AssetPrice>;\n /** Balance data per account */\n assetsBalance?: Record<AccountId, Record<Caip19AssetId, AssetBalance>>;\n /** Errors encountered, keyed by chain ID */\n errors?: Record<ChainId, string>;\n /** Detected assets (assets that do not have metadata) */\n detectedAssets?: Record<AccountId, Caip19AssetId[]>;\n /**\n * How to apply this response to state. See {@link AssetsUpdateMode}.\n * Defaults to `'merge'` if omitted.\n */\n updateMode?: AssetsUpdateMode;\n /**\n * When set with `updateMode: 'merge'`, balances on chains present in\n * `assetsBalance` replace the prior chain slice (stale tokens on those chains\n * are dropped). Custom assets on covered chains are preserved. Used for\n * `getAssets({ forceUpdate: true })` so unlock/startup reflects the API snapshot\n * without switching to `updateMode: 'full'`.\n */\n replaceCoveredChainBalances?: boolean;\n};\n\n/**\n * Type of {@link DataResponse.updateMode}: how the controller applies the response to state.\n *\n * - **full**: Response is the full set for the scope. Assets in state but not in the\n * response are cleared (except custom assets). Use for initial fetch or full refresh.\n * - **merge**: By default only assets present in the response are updated;\n * nothing is removed. When {@link DataResponse.replaceCoveredChainBalances}\n * is true, balances on chains present in the response replace the prior chain\n * slice (stale tokens on those chains are dropped; custom assets preserved).\n * Metadata and prices from the response are applied. Use for event-driven updates.\n * - **update**: Balance-only overlay — incoming balance amounts are patched in place;\n * existing balances, metadata, and prices are never removed or overwritten.\n * Missing metadata and prices from the response are seeded so RPC-only chains\n * can render on first fetch. Use for force refresh when the API may return a\n * partial chain snapshot.\n */\nexport type AssetsUpdateMode = 'full' | 'merge' | 'update';\n\n// ============================================================================\n// DATA SOURCE <-> CONTROLLER (DIRECT CALLS, NO MESSENGER PER SOURCE)\n// ============================================================================\n\n/**\n * Callbacks for data sources to report to AssetsController.\n * Passed to data sources so they report by direct call instead of messenger.\n */\nexport type AssetsControllerReport = {\n onActiveChainsUpdate: (dataSourceId: string, activeChains: ChainId[]) => void;\n onAssetsUpdate: (response: DataResponse, sourceId: string) => Promise<void>;\n};\n\n/** Request passed from controller to data source when subscribing */\nexport type DataSourceSubscriptionRequest = {\n request: DataRequest;\n subscriptionId: string;\n isUpdate: boolean;\n};\n\n/**\n * Interface for balance data sources that the controller calls directly.\n * No messenger is required for controller <-> data source communication.\n */\nexport type BalanceDataSource = {\n getAssetsMiddleware: () => Middleware;\n subscribe: (request: DataSourceSubscriptionRequest) => Promise<void>;\n unsubscribe: (subscriptionId: string) => Promise<void>;\n getName: () => string;\n};\n\n/**\n * Interface for the price data source (subscribe/unsubscribe + middleware).\n * Controller calls these methods directly.\n */\nexport type PriceDataSourceInterface = {\n getAssetsMiddleware: () => Middleware;\n subscribe: (request: DataSourceSubscriptionRequest) => Promise<void>;\n unsubscribe: (subscriptionId: string) => Promise<void>;\n};\n\n/**\n * Middleware-only source (e.g. detection, token enrichment).\n * Controller calls getAssetsMiddleware() directly.\n */\nexport type MiddlewareDataSource = {\n getAssetsMiddleware: () => Middleware;\n};\n\n// ============================================================================\n// UNIFIED MIDDLEWARE TYPES\n// ============================================================================\n\n/**\n * Internal state structure for AssetsController following normalized design.\n *\n * Keys use CAIP identifiers:\n * - assetsInfo keys: CAIP-19 asset IDs (e.g., \"eip155:1/erc20:0x...\")\n * - assetsBalance outer keys: Account IDs (InternalAccount.id UUIDs)\n * - assetsBalance inner keys: CAIP-19 asset IDs\n * - assetsPrice keys: CAIP-19 asset IDs\n * - customAssets outer keys: Account IDs (InternalAccount.id UUIDs)\n * - customAssets inner values: CAIP-19 asset IDs array\n * - assetPreferences keys: CAIP-19 asset IDs\n */\nexport type AssetsControllerStateInternal = {\n /** Shared metadata for all assets (stored once per asset) */\n assetsInfo: Record<Caip19AssetId, AssetMetadata>;\n /** Per-account balance data */\n assetsBalance: Record<AccountId, Record<Caip19AssetId, AssetBalance>>;\n /** Price data for assets */\n assetsPrice: Record<Caip19AssetId, AssetPrice>;\n /** Custom assets added by users per account */\n customAssets: Record<AccountId, Caip19AssetId[]>;\n /** UI preferences per asset (e.g. hidden) - separate from metadata */\n assetPreferences: Record<Caip19AssetId, AssetPreferences>;\n};\n\n/**\n * Base context for all middleware operations.\n * Contains the common interface shared by fetch and subscribe.\n */\nexport type Context = {\n /** The data request */\n request: DataRequest;\n /** The response data (mutated by middlewares) */\n response: DataResponse;\n /** Get current assets state */\n getAssetsState: () => AssetsControllerStateInternal;\n /**\n * Optional breakdown of latency (ms) per data source, e.g. from parallel\n * middlewares. Keys are source names (often \"MiddlewareName.SourceName\").\n * Merged into the controller's durationByDataSource for tracing.\n */\n durationByDataSource?: Record<string, number>;\n};\n\n/**\n * Next function for middleware chain\n */\nexport type NextFunction = (context: Context) => Promise<Context>;\n\n/**\n * Middleware function - works for both fetch and subscribe operations.\n */\nexport type Middleware = (\n context: Context,\n next: NextFunction,\n) => Promise<Context>;\n\n/**\n * An assets data source: any object that can participate in the assets\n * middleware chain with a display name (e.g. for tracing). Used by\n * createParallelMiddleware and by the controller when executing the chain.\n */\nexport type AssetsDataSource = {\n getName(): string;\n assetsMiddleware: Middleware;\n};\n\n/**\n * Wraps a middleware to only execute if specific dataTypes are requested.\n *\n * @param dataTypes - DataTypes that must be in the request for middleware to run\n * @param middleware - The middleware to conditionally execute\n * @returns A middleware that skips execution if none of the dataTypes are requested\n *\n * @example\n * ```typescript\n * // Only runs for metadata requests\n * const metadataMiddleware = forDataTypes(['metadata'], async (ctx, next) => {\n * const result = await next(ctx);\n * // Enrich metadata...\n * return result;\n * });\n *\n * // Runs for balance or price requests\n * const balanceOrPriceMiddleware = forDataTypes(['balance', 'price'], async (ctx, next) => {\n * const result = await next(ctx);\n * // Process balances or prices...\n * return result;\n * });\n * ```\n */\nexport function forDataTypes(\n dataTypes: DataType[],\n middleware: Middleware,\n): Middleware {\n return async (ctx, next) => {\n const requestedTypes = ctx.request.dataTypes;\n const shouldRun = dataTypes.some((dt) => requestedTypes.includes(dt));\n\n if (!shouldRun) {\n return next(ctx);\n }\n\n return middleware(ctx, next);\n };\n}\n\n/**\n * Context for fetch operations.\n * Extends base Context - no additional fields needed for fetch.\n */\nexport type FetchContext = Context;\n\n// Legacy aliases for backwards compatibility\nexport type FetchNextFunction = NextFunction;\nexport type FetchMiddleware = Middleware;\n\n/**\n * Subscription response returned when subscribing to asset updates.\n */\nexport type SubscriptionResponse = {\n /** Chains actively subscribed */\n chains: ChainId[];\n /** Account ID being watched */\n accountId: AccountId;\n /** Asset types being watched */\n assetTypes: AssetType[];\n /** Data types being kept fresh */\n dataTypes: DataType[];\n /** Cleanup function */\n unsubscribe: () => void;\n};\n\n// ============================================================================\n// COMBINED ASSET TYPE (for UI)\n// ============================================================================\n\n/**\n * Combined asset type matching state structure: balance, metadata, price\n */\nexport type Asset = {\n /** CAIP-19 asset ID */\n id: Caip19AssetId;\n /** CAIP-2 chain ID (extracted from id) */\n chainId: ChainId;\n /** Balance data */\n balance: AssetBalance;\n /** Metadata (symbol, name, decimals, etc.) */\n metadata: AssetMetadata;\n /** Price data */\n price: AssetPrice;\n /** Computed fiat value (balance × price) */\n fiatValue: number;\n};\n\n// ============================================================================\n// EVENT TYPES\n// ============================================================================\n\n/**\n * Event emitted when balances change\n */\nexport type BalanceChangeEvent = {\n accountId: AccountId;\n assetId: Caip19AssetId;\n previousAmount: string;\n newAmount: string;\n timestamp: number;\n};\n\n/**\n * Event emitted when prices change\n */\nexport type PriceChangeEvent = {\n assetIds: Caip19AssetId[];\n timestamp: number;\n};\n\n/**\n * Event emitted when metadata changes\n */\nexport type MetadataChangeEvent = {\n assetId: Caip19AssetId;\n changes: Partial<AssetMetadata>;\n};\n\n/**\n * Event emitted when assets without metadata are detected\n */\nexport type AssetsDetectedEvent = {\n accountId: AccountId;\n assetIds: Caip19AssetId[];\n};\n"]}
package/dist/types.d.cts CHANGED
@@ -307,16 +307,32 @@ export type DataResponse = {
307
307
  * Defaults to `'merge'` if omitted.
308
308
  */
309
309
  updateMode?: AssetsUpdateMode;
310
+ /**
311
+ * When set with `updateMode: 'merge'`, balances on chains present in
312
+ * `assetsBalance` replace the prior chain slice (stale tokens on those chains
313
+ * are dropped). Custom assets on covered chains are preserved. Used for
314
+ * `getAssets({ forceUpdate: true })` so unlock/startup reflects the API snapshot
315
+ * without switching to `updateMode: 'full'`.
316
+ */
317
+ replaceCoveredChainBalances?: boolean;
310
318
  };
311
319
  /**
312
320
  * Type of {@link DataResponse.updateMode}: how the controller applies the response to state.
313
321
  *
314
322
  * - **full**: Response is the full set for the scope. Assets in state but not in the
315
323
  * response are cleared (except custom assets). Use for initial fetch or full refresh.
316
- * - **merge**: Only assets present in the response are updated; nothing is removed.
317
- * Use for event-driven or incremental updates.
318
- */
319
- export type AssetsUpdateMode = 'full' | 'merge';
324
+ * - **merge**: By default only assets present in the response are updated;
325
+ * nothing is removed. When {@link DataResponse.replaceCoveredChainBalances}
326
+ * is true, balances on chains present in the response replace the prior chain
327
+ * slice (stale tokens on those chains are dropped; custom assets preserved).
328
+ * Metadata and prices from the response are applied. Use for event-driven updates.
329
+ * - **update**: Balance-only overlay — incoming balance amounts are patched in place;
330
+ * existing balances, metadata, and prices are never removed or overwritten.
331
+ * Missing metadata and prices from the response are seeded so RPC-only chains
332
+ * can render on first fetch. Use for force refresh when the API may return a
333
+ * partial chain snapshot.
334
+ */
335
+ export type AssetsUpdateMode = 'full' | 'merge' | 'update';
320
336
  /**
321
337
  * Callbacks for data sources to report to AssetsController.
322
338
  * Passed to data sources so they report by direct call instead of messenger.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.d.mts CHANGED
@@ -307,16 +307,32 @@ export type DataResponse = {
307
307
  * Defaults to `'merge'` if omitted.
308
308
  */
309
309
  updateMode?: AssetsUpdateMode;
310
+ /**
311
+ * When set with `updateMode: 'merge'`, balances on chains present in
312
+ * `assetsBalance` replace the prior chain slice (stale tokens on those chains
313
+ * are dropped). Custom assets on covered chains are preserved. Used for
314
+ * `getAssets({ forceUpdate: true })` so unlock/startup reflects the API snapshot
315
+ * without switching to `updateMode: 'full'`.
316
+ */
317
+ replaceCoveredChainBalances?: boolean;
310
318
  };
311
319
  /**
312
320
  * Type of {@link DataResponse.updateMode}: how the controller applies the response to state.
313
321
  *
314
322
  * - **full**: Response is the full set for the scope. Assets in state but not in the
315
323
  * response are cleared (except custom assets). Use for initial fetch or full refresh.
316
- * - **merge**: Only assets present in the response are updated; nothing is removed.
317
- * Use for event-driven or incremental updates.
318
- */
319
- export type AssetsUpdateMode = 'full' | 'merge';
324
+ * - **merge**: By default only assets present in the response are updated;
325
+ * nothing is removed. When {@link DataResponse.replaceCoveredChainBalances}
326
+ * is true, balances on chains present in the response replace the prior chain
327
+ * slice (stale tokens on those chains are dropped; custom assets preserved).
328
+ * Metadata and prices from the response are applied. Use for event-driven updates.
329
+ * - **update**: Balance-only overlay — incoming balance amounts are patched in place;
330
+ * existing balances, metadata, and prices are never removed or overwritten.
331
+ * Missing metadata and prices from the response are seeded so RPC-only chains
332
+ * can render on first fetch. Use for force refresh when the API may return a
333
+ * partial chain snapshot.
334
+ */
335
+ export type AssetsUpdateMode = 'full' | 'merge' | 'update';
320
336
  /**
321
337
  * Callbacks for data sources to report to AssetsController.
322
338
  * Passed to data sources so they report by direct call instead of messenger.