@metamask-previews/assets-controller 3.1.1-preview-dbd93752f → 3.1.1-preview-55f73f6ce

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.
package/CHANGELOG.md CHANGED
@@ -10,13 +10,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
10
10
  ### Added
11
11
 
12
12
  - Add Sentry traces for Assets Health dashboard ([#8310](https://github.com/MetaMask/core/pull/8310))
13
- - `Assets Data Source Timing` — per-source latency for each middleware in the fetch pipeline
14
- - `Assets Data Source Error` — tracks middleware failures with source names and error counts
15
- - `Assets Full Fetch` — end-to-end fetch timing with asset/price/chain/account counts
16
- - `Assets Update Pipeline` — enrichment pipeline timing for pushed data source updates
17
- - `Assets Subscription Error` — subscription failure tracking per data source
18
- - `Assets State Size` — entry counts for balances, metadata, prices, and custom assets (once on app start)
19
- - `Aggregated Balance Selector` — balance selector computation time with asset/network/account counts
13
+ - `AssetsDataSourceTiming` — per-source latency for each middleware in the fetch pipeline
14
+ - `AssetsDataSourceError` — tracks middleware failures with source names and error counts
15
+ - `AssetsFullFetch` — end-to-end fetch timing with asset/price/chain/account counts
16
+ - `AssetsUpdatePipeline` — enrichment pipeline timing for pushed data source updates
17
+ - `AssetsSubscriptionError` — subscription failure tracking per data source
18
+ - `AssetsStateSize` — entry counts for balances, metadata, prices, custom assets, unique assets, and network count (once on app start)
19
+ - `AggregatedBalanceSelector` — balance selector computation time with asset/network/account counts
20
20
  - Add optional `trace` parameter to `getAggregatedBalanceForAccount` selector
21
21
 
22
22
  ### Changed
@@ -53,6 +53,16 @@ const MESSENGER_EXPOSED_METHODS = [
53
53
  ];
54
54
  /** Default polling interval hint for data sources (30 seconds) */
55
55
  const DEFAULT_POLLING_INTERVAL_MS = 30000;
56
+ // ============================================================================
57
+ // TRACE NAMES — used in Sentry spans (search these strings in Discover)
58
+ // ============================================================================
59
+ const TRACE_FIRST_INIT_FETCH = 'AssetsControllerFirstInitFetch';
60
+ const TRACE_FULL_FETCH = 'AssetsFullFetch';
61
+ const TRACE_DATA_SOURCE_TIMING = 'AssetsDataSourceTiming';
62
+ const TRACE_DATA_SOURCE_ERROR = 'AssetsDataSourceError';
63
+ const TRACE_UPDATE_PIPELINE = 'AssetsUpdatePipeline';
64
+ const TRACE_SUBSCRIPTION_ERROR = 'AssetsSubscriptionError';
65
+ const TRACE_STATE_SIZE = 'AssetsStateSize';
56
66
  const log = (0, logger_1.createModuleLogger)(logger_1.projectLogger, CONTROLLER_NAME);
57
67
  /**
58
68
  * Returns the default state for AssetsController.
@@ -373,7 +383,7 @@ class AssetsController extends base_controller_1.BaseController {
373
383
  await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, { ...response, updateMode });
374
384
  const durationMs = Date.now() - startTime;
375
385
  // Emit trace for every full fetch (Assets Health dashboard)
376
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, 'Assets Full Fetch', {
386
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_FULL_FETCH, {
377
387
  duration_ms: durationMs,
378
388
  chain_count: chainIds.length,
379
389
  account_count: accounts.length,
@@ -388,7 +398,7 @@ class AssetsController extends base_controller_1.BaseController {
388
398
  });
389
399
  if (!__classPrivateFieldGet(this, _AssetsController_firstInitFetchReported, "f")) {
390
400
  __classPrivateFieldSet(this, _AssetsController_firstInitFetchReported, true, "f");
391
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, 'AssetsController First Init Fetch', {
401
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_FIRST_INIT_FETCH, {
392
402
  duration_ms: durationMs,
393
403
  chain_ids: JSON.stringify(chainIds),
394
404
  ...durationByDataSource,
@@ -738,7 +748,7 @@ class AssetsController extends base_controller_1.BaseController {
738
748
  dataTypes: ['balance', 'metadata', 'price'],
739
749
  }, response);
740
750
  await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, enrichedResponse);
741
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, 'Assets Update Pipeline', {
751
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_UPDATE_PIPELINE, {
742
752
  source: sourceId,
743
753
  duration_ms: Date.now() - updateStart,
744
754
  has_balance: Boolean(response.assetsBalance),
@@ -804,9 +814,21 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
804
814
  }
805
815
  __classPrivateFieldSet(this, _AssetsController_stateSizeReported, true, "f");
806
816
  const { assetsBalance: balances, customAssets, assetsInfo, assetsPrice, } = this.state;
817
+ // Count balance entries and collect unique asset IDs / chain IDs in one pass.
807
818
  let balanceEntries = 0;
819
+ const uniqueAssets = new Set();
820
+ const uniqueNetworks = new Set();
808
821
  for (const acct of Object.values(balances)) {
809
- balanceEntries += Object.keys(acct).length;
822
+ const assetIds = Object.keys(acct);
823
+ balanceEntries += assetIds.length;
824
+ for (const assetId of assetIds) {
825
+ uniqueAssets.add(assetId);
826
+ // CAIP-19 format: "eip155:1/slip44:60" — chainId is everything before "/"
827
+ const slash = assetId.indexOf('/');
828
+ if (slash > 0) {
829
+ uniqueNetworks.add(assetId.slice(0, slash));
830
+ }
831
+ }
810
832
  }
811
833
  let customAssetEntries = 0;
812
834
  for (const ids of Object.values(customAssets)) {
@@ -814,9 +836,11 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
814
836
  customAssetEntries += ids.length;
815
837
  }
816
838
  }
817
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, 'Assets State Size', {
839
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_STATE_SIZE, {
818
840
  balance_entries: balanceEntries,
819
841
  balance_accounts: Object.keys(balances).length,
842
+ unique_asset_count: uniqueAssets.size,
843
+ network_count: uniqueNetworks.size,
820
844
  metadata_entries: Object.keys(assetsInfo).length,
821
845
  price_entries: Object.keys(assetsPrice).length,
822
846
  custom_asset_entries: customAssetEntries,
@@ -984,7 +1008,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
984
1008
  }
985
1009
  // Emit per-source timing traces for the Assets Health dashboard
986
1010
  for (const [sourceName, durationMs] of Object.entries(durationByDataSource)) {
987
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, 'Assets Data Source Timing', {
1011
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_DATA_SOURCE_TIMING, {
988
1012
  source: sourceName,
989
1013
  duration_ms: durationMs,
990
1014
  chain_count: request.chainIds.length,
@@ -993,7 +1017,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
993
1017
  }
994
1018
  // Emit error traces for failed middlewares
995
1019
  if (middlewareErrors.length > 0) {
996
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, 'Assets Data Source Error', {
1020
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_DATA_SOURCE_ERROR, {
997
1021
  failed_sources: middlewareErrors.join(','),
998
1022
  error_count: middlewareErrors.length,
999
1023
  chain_count: request.chainIds.length,
@@ -1405,7 +1429,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1405
1429
  };
1406
1430
  source.subscribe(subscribeReq).catch((error) => {
1407
1431
  console.error(`[AssetsController] Failed to subscribe to '${sourceId}':`, error);
1408
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, 'Assets Subscription Error', {
1432
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_SUBSCRIPTION_ERROR, {
1409
1433
  source: sourceId,
1410
1434
  error_message: String(error),
1411
1435
  });