@metamask-previews/assets-controller 6.1.0-preview-7e80c49 → 6.1.0-preview-127523577

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 (90) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/AssetsController.cjs +59 -6
  3. package/dist/AssetsController.cjs.map +1 -1
  4. package/dist/AssetsController.d.cts +8 -1
  5. package/dist/AssetsController.d.cts.map +1 -1
  6. package/dist/AssetsController.d.mts +8 -1
  7. package/dist/AssetsController.d.mts.map +1 -1
  8. package/dist/AssetsController.mjs +59 -6
  9. package/dist/AssetsController.mjs.map +1 -1
  10. package/dist/data-sources/AccountsApiDataSource.cjs +6 -3
  11. package/dist/data-sources/AccountsApiDataSource.cjs.map +1 -1
  12. package/dist/data-sources/AccountsApiDataSource.d.cts +6 -0
  13. package/dist/data-sources/AccountsApiDataSource.d.cts.map +1 -1
  14. package/dist/data-sources/AccountsApiDataSource.d.mts +6 -0
  15. package/dist/data-sources/AccountsApiDataSource.d.mts.map +1 -1
  16. package/dist/data-sources/AccountsApiDataSource.mjs +7 -4
  17. package/dist/data-sources/AccountsApiDataSource.mjs.map +1 -1
  18. package/dist/data-sources/PriceDataSource.cjs +12 -8
  19. package/dist/data-sources/PriceDataSource.cjs.map +1 -1
  20. package/dist/data-sources/PriceDataSource.d.cts +5 -0
  21. package/dist/data-sources/PriceDataSource.d.cts.map +1 -1
  22. package/dist/data-sources/PriceDataSource.d.mts +5 -0
  23. package/dist/data-sources/PriceDataSource.d.mts.map +1 -1
  24. package/dist/data-sources/PriceDataSource.mjs +12 -8
  25. package/dist/data-sources/PriceDataSource.mjs.map +1 -1
  26. package/dist/data-sources/TokenDataSource.cjs +8 -4
  27. package/dist/data-sources/TokenDataSource.cjs.map +1 -1
  28. package/dist/data-sources/TokenDataSource.d.cts +5 -0
  29. package/dist/data-sources/TokenDataSource.d.cts.map +1 -1
  30. package/dist/data-sources/TokenDataSource.d.mts +5 -0
  31. package/dist/data-sources/TokenDataSource.d.mts.map +1 -1
  32. package/dist/data-sources/TokenDataSource.mjs +8 -4
  33. package/dist/data-sources/TokenDataSource.mjs.map +1 -1
  34. package/dist/errors.cjs +25 -0
  35. package/dist/errors.cjs.map +1 -0
  36. package/dist/errors.d.cts +25 -0
  37. package/dist/errors.d.cts.map +1 -0
  38. package/dist/errors.d.mts +25 -0
  39. package/dist/errors.d.mts.map +1 -0
  40. package/dist/errors.mjs +21 -0
  41. package/dist/errors.mjs.map +1 -0
  42. package/dist/index.cjs +5 -1
  43. package/dist/index.cjs.map +1 -1
  44. package/dist/index.d.cts +3 -1
  45. package/dist/index.d.cts.map +1 -1
  46. package/dist/index.d.mts +3 -1
  47. package/dist/index.d.mts.map +1 -1
  48. package/dist/index.mjs +2 -1
  49. package/dist/index.mjs.map +1 -1
  50. package/dist/middlewares/CustomAssetGraduationMiddleware.cjs +121 -0
  51. package/dist/middlewares/CustomAssetGraduationMiddleware.cjs.map +1 -0
  52. package/dist/middlewares/CustomAssetGraduationMiddleware.d.cts +25 -0
  53. package/dist/middlewares/CustomAssetGraduationMiddleware.d.cts.map +1 -0
  54. package/dist/middlewares/CustomAssetGraduationMiddleware.d.mts +25 -0
  55. package/dist/middlewares/CustomAssetGraduationMiddleware.d.mts.map +1 -0
  56. package/dist/middlewares/CustomAssetGraduationMiddleware.mjs +117 -0
  57. package/dist/middlewares/CustomAssetGraduationMiddleware.mjs.map +1 -0
  58. package/dist/middlewares/RpcFallbackMiddleware.cjs +90 -0
  59. package/dist/middlewares/RpcFallbackMiddleware.cjs.map +1 -0
  60. package/dist/middlewares/RpcFallbackMiddleware.d.cts +23 -0
  61. package/dist/middlewares/RpcFallbackMiddleware.d.cts.map +1 -0
  62. package/dist/middlewares/RpcFallbackMiddleware.d.mts +23 -0
  63. package/dist/middlewares/RpcFallbackMiddleware.d.mts.map +1 -0
  64. package/dist/middlewares/RpcFallbackMiddleware.mjs +86 -0
  65. package/dist/middlewares/RpcFallbackMiddleware.mjs.map +1 -0
  66. package/dist/middlewares/index.cjs +5 -1
  67. package/dist/middlewares/index.cjs.map +1 -1
  68. package/dist/middlewares/index.d.cts +4 -0
  69. package/dist/middlewares/index.d.cts.map +1 -1
  70. package/dist/middlewares/index.d.mts +4 -0
  71. package/dist/middlewares/index.d.mts.map +1 -1
  72. package/dist/middlewares/index.mjs +2 -0
  73. package/dist/middlewares/index.mjs.map +1 -1
  74. package/dist/utils/fetchWithTimeout.cjs +30 -0
  75. package/dist/utils/fetchWithTimeout.cjs.map +1 -0
  76. package/dist/utils/fetchWithTimeout.d.cts +11 -0
  77. package/dist/utils/fetchWithTimeout.d.cts.map +1 -0
  78. package/dist/utils/fetchWithTimeout.d.mts +11 -0
  79. package/dist/utils/fetchWithTimeout.d.mts.map +1 -0
  80. package/dist/utils/fetchWithTimeout.mjs +26 -0
  81. package/dist/utils/fetchWithTimeout.mjs.map +1 -0
  82. package/dist/utils/index.cjs +3 -1
  83. package/dist/utils/index.cjs.map +1 -1
  84. package/dist/utils/index.d.cts +1 -0
  85. package/dist/utils/index.d.cts.map +1 -1
  86. package/dist/utils/index.d.mts +1 -0
  87. package/dist/utils/index.d.mts.map +1 -1
  88. package/dist/utils/index.mjs +1 -0
  89. package/dist/utils/index.mjs.map +1 -1
  90. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Added
11
+
12
+ - Add `CustomAssetGraduationMiddleware` that removes an EVM asset from `customAssets[selectedAccount]` when `AccountsApiDataSource` or `BackendWebsocketDataSource` reports a balance for it ([#8582](https://github.com/MetaMask/core/pull/8582))
13
+ - Non-EVM custom assets (Solana, BTC, Tron) are not affected.
14
+ - `RpcDataSource` continues to be the sole balance fetcher for assets still in `customAssets`.
15
+ - Add `RpcFallbackMiddleware` to the fast pipeline so chains that error in `response.errors` (network error, `unprocessedNetworks`, timeout) fall back to `RpcDataSource` ([#8582](https://github.com/MetaMask/core/pull/8582))
16
+ - Successful RPC results are merged into the response and recovered chains are cleared from `response.errors`.
17
+ - Add a configurable `fetchTimeoutMs` option (default `15000`) to `AccountsApiDataSource`, `PriceDataSource`, and `TokenDataSource` ([#8582](https://github.com/MetaMask/core/pull/8582))
18
+ - On timeout, AccountsAPI marks every requested chain as errored so `RpcFallbackMiddleware` picks them up; price and token enrichment degrade gracefully.
19
+ - Add `fetchWithTimeout` utility that races an async task against a timeout ([#8582](https://github.com/MetaMask/core/pull/8582))
20
+
10
21
  ## [6.1.0]
11
22
 
12
23
  ### Added
@@ -13,7 +13,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
13
13
  var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
15
  };
16
- var _AssetsController_instances, _AssetsController_isEnabled, _AssetsController_isBasicFunctionality, _AssetsController_defaultUpdateInterval, _AssetsController_trace, _AssetsController_firstInitFetchReported, _AssetsController_stateSizeReported, _AssetsController_emitTrace, _AssetsController_emitStateSizeTrace, _AssetsController_uiOpen, _AssetsController_keyringUnlocked, _AssetsController_controllerMutex, _AssetsController_activeSubscriptions, _AssetsController_enabledChains, _AssetsController_lastKnownAccountIds, _AssetsController_getSelectedAccounts, _AssetsController_backendWebsocketDataSource, _AssetsController_accountsApiDataSource, _AssetsController_snapDataSource, _AssetsController_rpcDataSource, _AssetsController_stakedBalanceDataSource, _AssetsController_allBalanceDataSources_get, _AssetsController_priceDataSource, _AssetsController_detectionMiddleware, _AssetsController_tokenDataSource, _AssetsController_unsubscribeBasicFunctionality, _AssetsController_queryApiClient, _AssetsController_onActiveChainsUpdated, _AssetsController_initializeNativeAssetsMap, _AssetsController_initializeState, _AssetsController_extractEnabledChains, _AssetsController_normalizeChainReference, _AssetsController_subscribeToEvents, _AssetsController_onUnapprovedTransactionAdded, _AssetsController_updateActive, _AssetsController_handleAccountTreeStateChange, _AssetsController_registerActionHandlers, _AssetsController_handleActiveChainsUpdate, _AssetsController_executeMiddlewares, _AssetsController_getNativeAssetMap, _AssetsController_isNativeAsset, _AssetsController_resolveNativeAssetIds, _AssetsController_getNativeAssetIdsForEnabledChains, _AssetsController_getNativeAssetIdsForAccount, _AssetsController_ensureNativeBalancesDefaultZero, _AssetsController_updateState, _AssetsController_getAssetsFromState, _AssetsController_shouldHideNativeToken, _AssetsController_tokenStandardToAssetType, _AssetsController_start, _AssetsController_stop, _AssetsController_subscribeAssets, _AssetsController_subscribeAssetsBalance, _AssetsController_subscribeStakedBalance, _AssetsController_buildChainToAccountsMap, _AssetsController_subscribeDataSource, _AssetsController_unsubscribeDataSource, _AssetsController_buildDataRequest, _AssetsController_getEnabledChainsForAccount, _AssetsController_handleAccountGroupChanged, _AssetsController_handleEnabledNetworksChanged;
16
+ var _AssetsController_instances, _AssetsController_isEnabled, _AssetsController_isBasicFunctionality, _AssetsController_defaultUpdateInterval, _AssetsController_trace, _AssetsController_captureException, _AssetsController_firstInitFetchReported, _AssetsController_stateSizeReported, _AssetsController_emitTrace, _AssetsController_emitStateSizeTrace, _AssetsController_uiOpen, _AssetsController_keyringUnlocked, _AssetsController_controllerMutex, _AssetsController_activeSubscriptions, _AssetsController_enabledChains, _AssetsController_lastKnownAccountIds, _AssetsController_getSelectedAccounts, _AssetsController_backendWebsocketDataSource, _AssetsController_accountsApiDataSource, _AssetsController_snapDataSource, _AssetsController_rpcDataSource, _AssetsController_stakedBalanceDataSource, _AssetsController_allBalanceDataSources_get, _AssetsController_priceDataSource, _AssetsController_detectionMiddleware, _AssetsController_customAssetGraduationMiddleware, _AssetsController_rpcFallbackMiddleware, _AssetsController_tokenDataSource, _AssetsController_unsubscribeBasicFunctionality, _AssetsController_queryApiClient, _AssetsController_onActiveChainsUpdated, _AssetsController_initializeNativeAssetsMap, _AssetsController_initializeState, _AssetsController_extractEnabledChains, _AssetsController_normalizeChainReference, _AssetsController_subscribeToEvents, _AssetsController_onUnapprovedTransactionAdded, _AssetsController_updateActive, _AssetsController_handleAccountTreeStateChange, _AssetsController_registerActionHandlers, _AssetsController_handleActiveChainsUpdate, _AssetsController_executeMiddlewares, _AssetsController_getNativeAssetMap, _AssetsController_isNativeAsset, _AssetsController_resolveNativeAssetIds, _AssetsController_getNativeAssetIdsForEnabledChains, _AssetsController_getNativeAssetIdsForAccount, _AssetsController_ensureNativeBalancesDefaultZero, _AssetsController_updateState, _AssetsController_getAssetsFromState, _AssetsController_shouldHideNativeToken, _AssetsController_tokenStandardToAssetType, _AssetsController_start, _AssetsController_stop, _AssetsController_subscribeAssets, _AssetsController_subscribeAssetsBalance, _AssetsController_subscribeStakedBalance, _AssetsController_buildChainToAccountsMap, _AssetsController_subscribeDataSource, _AssetsController_unsubscribeDataSource, _AssetsController_buildDataRequest, _AssetsController_getEnabledChainsForAccount, _AssetsController_handleAccountGroupChanged, _AssetsController_handleEnabledNetworksChanged;
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.AssetsController = exports.getDefaultAssetsControllerState = void 0;
19
19
  const base_controller_1 = require("@metamask/base-controller");
@@ -30,9 +30,12 @@ const RpcDataSource_1 = require("./data-sources/RpcDataSource.cjs");
30
30
  const SnapDataSource_1 = require("./data-sources/SnapDataSource.cjs");
31
31
  const StakedBalanceDataSource_1 = require("./data-sources/StakedBalanceDataSource.cjs");
32
32
  const TokenDataSource_1 = require("./data-sources/TokenDataSource.cjs");
33
+ const errors_1 = require("./errors.cjs");
33
34
  const logger_1 = require("./logger.cjs");
35
+ const CustomAssetGraduationMiddleware_1 = require("./middlewares/CustomAssetGraduationMiddleware.cjs");
34
36
  const DetectionMiddleware_1 = require("./middlewares/DetectionMiddleware.cjs");
35
37
  const ParallelMiddleware_1 = require("./middlewares/ParallelMiddleware.cjs");
38
+ const RpcFallbackMiddleware_1 = require("./middlewares/RpcFallbackMiddleware.cjs");
36
39
  const utils_2 = require("./utils/index.cjs");
37
40
  const constants_1 = require("./utils/constants.cjs");
38
41
  const NATIVE_ASSETS_QUERY_KEY = ['nativeAssets'];
@@ -212,7 +215,7 @@ function normalizeResponse(response) {
212
215
  * - The controller does NOT manage polling - it simply receives pushed updates
213
216
  */
214
217
  class AssetsController extends base_controller_1.BaseController {
215
- constructor({ messenger, state = {}, defaultUpdateInterval = DEFAULT_POLLING_INTERVAL_MS, isEnabled = () => true, isBasicFunctionality, subscribeToBasicFunctionalityChange, queryApiClient, rpcDataSourceConfig, trace, accountsApiDataSourceConfig, priceDataSourceConfig, stakedBalanceDataSourceConfig, isOnboarded, }) {
218
+ constructor({ messenger, state = {}, defaultUpdateInterval = DEFAULT_POLLING_INTERVAL_MS, isEnabled = () => true, isBasicFunctionality, subscribeToBasicFunctionalityChange, queryApiClient, rpcDataSourceConfig, trace, captureException, accountsApiDataSourceConfig, priceDataSourceConfig, stakedBalanceDataSourceConfig, isOnboarded, }) {
216
219
  super({
217
220
  name: CONTROLLER_NAME,
218
221
  messenger,
@@ -231,6 +234,8 @@ class AssetsController extends base_controller_1.BaseController {
231
234
  _AssetsController_defaultUpdateInterval.set(this, void 0);
232
235
  /** Optional trace callback for first init/fetch measurement (duration). */
233
236
  _AssetsController_trace.set(this, void 0);
237
+ /** Optional reporter for Issue-style errors (e.g. Sentry.captureException). */
238
+ _AssetsController_captureException.set(this, void 0);
234
239
  /** Whether we have already reported first init fetch for this session (reset on #stop). */
235
240
  _AssetsController_firstInitFetchReported.set(this, false);
236
241
  /** Whether we have already reported state size for this session (reset on #stop). */
@@ -262,6 +267,8 @@ class AssetsController extends base_controller_1.BaseController {
262
267
  _AssetsController_stakedBalanceDataSource.set(this, void 0);
263
268
  _AssetsController_priceDataSource.set(this, void 0);
264
269
  _AssetsController_detectionMiddleware.set(this, void 0);
270
+ _AssetsController_customAssetGraduationMiddleware.set(this, void 0);
271
+ _AssetsController_rpcFallbackMiddleware.set(this, void 0);
265
272
  _AssetsController_tokenDataSource.set(this, void 0);
266
273
  _AssetsController_unsubscribeBasicFunctionality.set(this, null);
267
274
  _AssetsController_queryApiClient.set(this, void 0);
@@ -270,6 +277,7 @@ class AssetsController extends base_controller_1.BaseController {
270
277
  __classPrivateFieldSet(this, _AssetsController_isBasicFunctionality, isBasicFunctionality ?? (() => true), "f");
271
278
  __classPrivateFieldSet(this, _AssetsController_defaultUpdateInterval, defaultUpdateInterval, "f");
272
279
  __classPrivateFieldSet(this, _AssetsController_trace, trace, "f");
280
+ __classPrivateFieldSet(this, _AssetsController_captureException, captureException, "f");
273
281
  __classPrivateFieldSet(this, _AssetsController_queryApiClient, queryApiClient, "f");
274
282
  const rpcConfig = rpcDataSourceConfig ?? {};
275
283
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_initializeNativeAssetsMap).call(this, queryApiClient);
@@ -324,6 +332,20 @@ class AssetsController extends base_controller_1.BaseController {
324
332
  ...priceDataSourceConfig,
325
333
  }), "f");
326
334
  __classPrivateFieldSet(this, _AssetsController_detectionMiddleware, new DetectionMiddleware_1.DetectionMiddleware(), "f");
335
+ __classPrivateFieldSet(this, _AssetsController_customAssetGraduationMiddleware, new CustomAssetGraduationMiddleware_1.CustomAssetGraduationMiddleware({
336
+ getSelectedAccountId: () => {
337
+ try {
338
+ return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this)[0]?.id;
339
+ }
340
+ catch {
341
+ return undefined;
342
+ }
343
+ },
344
+ removeCustomAsset: (accountId, assetId) => this.removeCustomAsset(accountId, assetId),
345
+ }), "f");
346
+ __classPrivateFieldSet(this, _AssetsController_rpcFallbackMiddleware, new RpcFallbackMiddleware_1.RpcFallbackMiddleware({
347
+ rpcDataSource: __classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f"),
348
+ }), "f");
327
349
  if (!__classPrivateFieldGet(this, _AssetsController_isEnabled, "f")) {
328
350
  log('AssetsController is disabled, skipping initialization');
329
351
  return;
@@ -392,6 +414,11 @@ class AssetsController extends base_controller_1.BaseController {
392
414
  __classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f"),
393
415
  __classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"),
394
416
  ]),
417
+ // Graduation must run BEFORE the RPC fallback so it only sees
418
+ // AccountsApi/Websocket balances. RPC intentionally carries
419
+ // custom assets and must never trigger graduation.
420
+ __classPrivateFieldGet(this, _AssetsController_customAssetGraduationMiddleware, "f"),
421
+ __classPrivateFieldGet(this, _AssetsController_rpcFallbackMiddleware, "f"),
395
422
  __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
396
423
  (0, ParallelMiddleware_1.createParallelMiddleware)([
397
424
  __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
@@ -795,7 +822,17 @@ class AssetsController extends base_controller_1.BaseController {
795
822
  ...resolvedRequest,
796
823
  dataTypes: resolvedRequest.dataTypes.filter((dt) => dt !== 'metadata' && dt !== 'price'),
797
824
  };
798
- const enrichmentSources = [__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f")];
825
+ // Graduate custom assets only when AccountsAPI / Websocket reports them.
826
+ // RPC already fetches custom assets on purpose, and Snap handles non-EVM
827
+ // chains the rule does not apply to, so skip the middleware for those.
828
+ const shouldGraduateCustomAssets = sourceId === 'AccountsApiDataSource' ||
829
+ sourceId === 'BackendWebsocketDataSource';
830
+ const enrichmentSources = [
831
+ ...(shouldGraduateCustomAssets
832
+ ? [__classPrivateFieldGet(this, _AssetsController_customAssetGraduationMiddleware, "f")]
833
+ : []),
834
+ __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
835
+ ];
799
836
  if (__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)) {
800
837
  enrichmentSources.push((0, ParallelMiddleware_1.createParallelMiddleware)([
801
838
  __classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
@@ -850,7 +887,7 @@ class AssetsController extends base_controller_1.BaseController {
850
887
  }
851
888
  }
852
889
  exports.AssetsController = AssetsController;
853
- _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctionality = new WeakMap(), _AssetsController_defaultUpdateInterval = new WeakMap(), _AssetsController_trace = new WeakMap(), _AssetsController_firstInitFetchReported = new WeakMap(), _AssetsController_stateSizeReported = new WeakMap(), _AssetsController_uiOpen = new WeakMap(), _AssetsController_keyringUnlocked = new WeakMap(), _AssetsController_controllerMutex = new WeakMap(), _AssetsController_activeSubscriptions = new WeakMap(), _AssetsController_enabledChains = new WeakMap(), _AssetsController_lastKnownAccountIds = new WeakMap(), _AssetsController_backendWebsocketDataSource = new WeakMap(), _AssetsController_accountsApiDataSource = new WeakMap(), _AssetsController_snapDataSource = new WeakMap(), _AssetsController_rpcDataSource = new WeakMap(), _AssetsController_stakedBalanceDataSource = new WeakMap(), _AssetsController_priceDataSource = new WeakMap(), _AssetsController_detectionMiddleware = new WeakMap(), _AssetsController_tokenDataSource = new WeakMap(), _AssetsController_unsubscribeBasicFunctionality = new WeakMap(), _AssetsController_queryApiClient = new WeakMap(), _AssetsController_onActiveChainsUpdated = new WeakMap(), _AssetsController_instances = new WeakSet(), _AssetsController_emitTrace = function _AssetsController_emitTrace(name, data, tags = {
890
+ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctionality = new WeakMap(), _AssetsController_defaultUpdateInterval = new WeakMap(), _AssetsController_trace = new WeakMap(), _AssetsController_captureException = new WeakMap(), _AssetsController_firstInitFetchReported = new WeakMap(), _AssetsController_stateSizeReported = new WeakMap(), _AssetsController_uiOpen = new WeakMap(), _AssetsController_keyringUnlocked = new WeakMap(), _AssetsController_controllerMutex = new WeakMap(), _AssetsController_activeSubscriptions = new WeakMap(), _AssetsController_enabledChains = new WeakMap(), _AssetsController_lastKnownAccountIds = new WeakMap(), _AssetsController_backendWebsocketDataSource = new WeakMap(), _AssetsController_accountsApiDataSource = new WeakMap(), _AssetsController_snapDataSource = new WeakMap(), _AssetsController_rpcDataSource = new WeakMap(), _AssetsController_stakedBalanceDataSource = new WeakMap(), _AssetsController_priceDataSource = new WeakMap(), _AssetsController_detectionMiddleware = new WeakMap(), _AssetsController_customAssetGraduationMiddleware = new WeakMap(), _AssetsController_rpcFallbackMiddleware = new WeakMap(), _AssetsController_tokenDataSource = new WeakMap(), _AssetsController_unsubscribeBasicFunctionality = new WeakMap(), _AssetsController_queryApiClient = new WeakMap(), _AssetsController_onActiveChainsUpdated = new WeakMap(), _AssetsController_instances = new WeakSet(), _AssetsController_emitTrace = function _AssetsController_emitTrace(name, data, tags = {
854
891
  controller: 'AssetsController',
855
892
  }) {
856
893
  if (!__classPrivateFieldGet(this, _AssetsController_trace, "f")) {
@@ -1160,12 +1197,28 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1160
1197
  account_count: request.accountsWithSupportedChains.length,
1161
1198
  });
1162
1199
  }
1163
- // Emit error traces for failed middlewares
1200
+ // Failed middlewares: Issues (optional) + perf/Dashboard spans
1164
1201
  if (middlewareErrors.length > 0) {
1202
+ const failedSources = middlewareErrors.join(',');
1203
+ const assetsError = new errors_1.AssetsDataSourceError({
1204
+ failedSources,
1205
+ errorCount: middlewareErrors.length,
1206
+ chainCount: request.chainIds.length,
1207
+ });
1208
+ try {
1209
+ __classPrivateFieldGet(this, _AssetsController_captureException, "f")?.call(this, assetsError);
1210
+ }
1211
+ catch {
1212
+ // Never let telemetry throw.
1213
+ }
1165
1214
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_DATA_SOURCE_ERROR, {
1166
- failed_sources: middlewareErrors.join(','),
1215
+ failed_sources: failedSources,
1167
1216
  error_count: middlewareErrors.length,
1168
1217
  chain_count: request.chainIds.length,
1218
+ }, {
1219
+ controller: 'AssetsController',
1220
+ severity: 'error',
1221
+ error_type: assetsError.name,
1169
1222
  });
1170
1223
  }
1171
1224
  return { response: result.response, durationByDataSource };