@metamask-previews/assets-controller 11.2.1-preview-6316943cb → 11.2.1-preview-0b2e3c9b4
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 +6 -3
- package/dist/AssetsController.cjs +237 -133
- package/dist/AssetsController.cjs.map +1 -1
- package/dist/AssetsController.d.cts.map +1 -1
- package/dist/AssetsController.d.mts.map +1 -1
- package/dist/AssetsController.mjs +237 -133
- package/dist/AssetsController.mjs.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.cjs +11 -2
- package/dist/data-sources/AccountsApiDataSource.cjs.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.d.cts.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.d.mts.map +1 -1
- package/dist/data-sources/AccountsApiDataSource.mjs +10 -1
- package/dist/data-sources/AccountsApiDataSource.mjs.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.cjs +20 -12
- package/dist/data-sources/BackendWebsocketDataSource.cjs.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.d.cts +1 -2
- package/dist/data-sources/BackendWebsocketDataSource.d.cts.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.d.mts +1 -2
- package/dist/data-sources/BackendWebsocketDataSource.d.mts.map +1 -1
- package/dist/data-sources/BackendWebsocketDataSource.mjs +20 -12
- package/dist/data-sources/BackendWebsocketDataSource.mjs.map +1 -1
- package/dist/selectors/balance.cjs +52 -12
- package/dist/selectors/balance.cjs.map +1 -1
- package/dist/selectors/balance.d.cts.map +1 -1
- package/dist/selectors/balance.d.mts.map +1 -1
- package/dist/selectors/balance.mjs +52 -12
- package/dist/selectors/balance.mjs.map +1 -1
- package/dist/utils/index.cjs +1 -3
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.cts +0 -1
- package/dist/utils/index.d.cts.map +1 -1
- package/dist/utils/index.d.mts +0 -1
- package/dist/utils/index.d.mts.map +1 -1
- package/dist/utils/index.mjs +0 -1
- package/dist/utils/index.mjs.map +1 -1
- package/dist/utils/trace.cjs +120 -0
- package/dist/utils/trace.cjs.map +1 -0
- package/dist/utils/trace.d.cts +52 -0
- package/dist/utils/trace.d.cts.map +1 -0
- package/dist/utils/trace.d.mts +52 -0
- package/dist/utils/trace.d.mts.map +1 -0
- package/dist/utils/trace.mjs +115 -0
- package/dist/utils/trace.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/utils/caip.cjs +0 -24
- package/dist/utils/caip.cjs.map +0 -1
- package/dist/utils/caip.d.cts +0 -11
- package/dist/utils/caip.d.cts.map +0 -1
- package/dist/utils/caip.d.mts +0 -11
- package/dist/utils/caip.d.mts.map +0 -1
- package/dist/utils/caip.mjs +0 -20
- package/dist/utils/caip.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,19 +9,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
### Added
|
|
11
11
|
|
|
12
|
-
- Add stage-gated ingestion of the Snaps → AssetsController migration networks (Solana, Stellar, Tron) ([#9647](https://github.com/MetaMask/core/pull/9647))
|
|
13
|
-
- `AssetsController` and `BackendWebsocketDataSource` now resolve a per-network migration stage from `RemoteFeatureFlagController` state (via `RemoteFeatureFlagController:getState`) using the `networkAssetsSnapsMigrationSolana`, `networkAssetsSnapsMigrationStellar`, and `networkAssetsSnapsMigrationTron` flags. Migration networks are only ingested and surfaced as active chains from `SnapsAssetsMigrationStage.ReadAssetsControllerWithFallback` onward, and left to the Snap when the stage is `Off` (the fail-safe when the flag is missing). Non-migration namespaces (e.g. `eip155`) are never gated.
|
|
14
|
-
|
|
15
12
|
- `SnapDataSource` now preserves optional balance `metadata` from snap keyrings into `assetsBalance` when handling `AccountsController:accountBalancesUpdated` and `getAccountBalances` results ([#9564](https://github.com/MetaMask/core/pull/9564))
|
|
16
13
|
|
|
17
14
|
### Changed
|
|
18
15
|
|
|
16
|
+
- Nest AssetsController Sentry spans (`AssetsDataSourceTiming`, `AssetsDataSourceError`, `AssetsControllerFirstInitFetch`, pipeline summaries) as subspans under parent `AssetsFullFetch` / `AssetsUpdatePipeline` / `AssetsBackgroundFetch` traces, and emit a single `AggregatedBalanceSelector` span for `calculateBalanceForAllWallets` instead of one root span per account group, to avoid Sentry rate limits ([#9672](https://github.com/MetaMask/core/pull/9672))
|
|
17
|
+
- Pipeline / data-source / update enrichment spans emit only on the unlock (first-init) fetch per session; later polls, force updates, and subscription enrichment skip tracing.
|
|
18
|
+
- Tracing helpers live in `utils/trace.ts` (`emitTrace` / `withTrace`); omit `trace` to no-op so call sites stay free of gating `if`s. Fast and background fetch lanes are sibling `withTrace` calls (not nested).
|
|
19
|
+
- Dashboard-facing spans (`AssetsFullFetch`, `AssetsUpdatePipeline`, `AggregatedBalanceSelector`, etc.) record `duration_ms` as a Sentry measurement (and backdate `startTime`) so Spans widgets charting `p95(duration_ms)` receive data. Nesting parents use `AssetsFetchPipeline` / `AssetsUpdateEnrichment` / `AssetsBackgroundFetch` / `AggregatedBalance`.
|
|
20
|
+
- `AggregatedBalanceSelector` is nested under an `AggregatedBalance` parent span via `parentContext`.
|
|
19
21
|
- Bump `@metamask/keyring-api` from `^23.5.0` to `^23.7.0` ([#9676](https://github.com/MetaMask/core/pull/9676))
|
|
20
22
|
- Bump `@metamask/keyring-internal-api` from `^11.0.1` to `^11.0.2` ([#9676](https://github.com/MetaMask/core/pull/9676))
|
|
21
23
|
- Bump `@metamask/keyring-snap-client` from `^9.2.0` to `^9.2.1` ([#9676](https://github.com/MetaMask/core/pull/9676))
|
|
22
24
|
|
|
23
25
|
### Fixed
|
|
24
26
|
|
|
27
|
+
- `withTrace` treats a rejected parent `trace` promise as best-effort (like `emitTrace`), so Sentry/adapter failures cannot fail full fetches or `handleAssetsUpdate` enrichment ([#9672](https://github.com/MetaMask/core/pull/9672))
|
|
25
28
|
- `SnapDataSource` now delivers snap-sourced balance updates directly to `AssetsController` via a constructor-supplied `onAssetsUpdate` callback instead of fanning out to `activeSubscriptions`, so updates (e.g. Tron energy/bandwidth) are no longer dropped when no active subscription is tracked for the chain in the SnapDataSource ([#9656](https://github.com/MetaMask/core/pull/9656))
|
|
26
29
|
|
|
27
30
|
## [11.2.1]
|
|
@@ -13,7 +13,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
13
13
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
15
|
};
|
|
16
|
-
var _AssetsController_instances, _AssetsController_isEnabled, _AssetsController_isBasicFunctionality, _AssetsController_defaultUpdateInterval, _AssetsController_trace, _AssetsController_captureException, _AssetsController_firstInitFetchReported, _AssetsController_stateSizeReported,
|
|
16
|
+
var _AssetsController_instances, _AssetsController_isEnabled, _AssetsController_isBasicFunctionality, _AssetsController_defaultUpdateInterval, _AssetsController_trace, _AssetsController_captureException, _AssetsController_firstInitFetchReported, _AssetsController_stateSizeReported, _AssetsController_emitStateSizeTrace, _AssetsController_uiOpen, _AssetsController_keyringUnlocked, _AssetsController_controllerMutex, _AssetsController_accountRefreshMutex, _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_onTransactionConfirmed, _AssetsController_onAccountActivityBalanceUpdated, _AssetsController_updateActive, _AssetsController_handleAccountTreeStateChange, _AssetsController_runAccountTreeRefresh, _AssetsController_runStartupRefresh, _AssetsController_registerActionHandlers, _AssetsController_handleActiveChainsUpdate, _AssetsController_executeMiddlewares, _AssetsController_fetchMissingPricesWithoutCache, _AssetsController_getNativeAssetMap, _AssetsController_isNativeAsset, _AssetsController_getAssetType, _AssetsController_resolveNativeAssetIds, _AssetsController_getNativeAssetIdsForEnabledChains, _AssetsController_getNativeAssetIdsForAccount, _AssetsController_getSlowPipelineChainIds, _AssetsController_ensureNativeBalancesDefaultZero, _AssetsController_ensureDefaultTrackedAssetsSeeded, _AssetsController_updateState, _AssetsController_getAssetsFromState, _AssetsController_getAssetFromState, _AssetsController_shouldHideNativeToken, _AssetsController_tokenStandardToAssetType, _AssetsController_start, _AssetsController_stop, _AssetsController_subscribeAssets, _AssetsController_subscribeAssetsBalance, _AssetsController_subscribeRpcCustomAssetsSupplement, _AssetsController_unsubscribeBySubscriptionKey, _AssetsController_subscribeStakedBalance, _AssetsController_buildChainToAccountsMap, _AssetsController_subscribeDataSource, _AssetsController_unsubscribeDataSource, _AssetsController_buildDataRequest, _AssetsController_getEnabledChainsForAccount, _AssetsController_handleAccountGroupChanged, _AssetsController_handleEnabledNetworksChanged, _AssetsController_handleNetworkAdded, _AssetsController_refreshActiveChainsOnNetworkSwitch, _AssetsController_getSelectedEvmChainIdFromNetworkState, _AssetsController_handleNetworkDidChange, _AssetsController_refreshAssetsAfterNetworkChange, _AssetsController_refreshAssetsAfterNetworkAdded;
|
|
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");
|
|
@@ -42,6 +42,7 @@ const constants_js_1 = require("./utils/constants.cjs");
|
|
|
42
42
|
const customAssetsRpcSupplement_js_1 = require("./utils/customAssetsRpcSupplement.cjs");
|
|
43
43
|
const index_js_1 = require("./utils/index.cjs");
|
|
44
44
|
const processAccountActivityBalanceUpdates_js_1 = require("./utils/processAccountActivityBalanceUpdates.cjs");
|
|
45
|
+
const trace_js_1 = require("./utils/trace.cjs");
|
|
45
46
|
const NATIVE_ASSETS_QUERY_KEY = ['nativeAssets'];
|
|
46
47
|
/** Stable empty map so memoized formatters are not busted by `?? {}` identity churn. */
|
|
47
48
|
const EMPTY_NATIVE_ASSET_MAP = {};
|
|
@@ -72,9 +73,14 @@ const DEFAULT_POLLING_INTERVAL_MS = 30000;
|
|
|
72
73
|
// ============================================================================
|
|
73
74
|
const TRACE_FIRST_INIT_FETCH = 'AssetsControllerFirstInitFetch';
|
|
74
75
|
const TRACE_FULL_FETCH = 'AssetsFullFetch';
|
|
76
|
+
/** Parent span that nests per-source timings; dashboard charts {@link TRACE_FULL_FETCH}. */
|
|
77
|
+
const TRACE_FETCH_PIPELINE = 'AssetsFetchPipeline';
|
|
78
|
+
const TRACE_BACKGROUND_FETCH = 'AssetsBackgroundFetch';
|
|
75
79
|
const TRACE_DATA_SOURCE_TIMING = 'AssetsDataSourceTiming';
|
|
76
80
|
const TRACE_DATA_SOURCE_ERROR = 'AssetsDataSourceError';
|
|
77
81
|
const TRACE_UPDATE_PIPELINE = 'AssetsUpdatePipeline';
|
|
82
|
+
/** Parent span that nests update enrichment; dashboard charts {@link TRACE_UPDATE_PIPELINE}. */
|
|
83
|
+
const TRACE_UPDATE_PARENT = 'AssetsUpdateEnrichment';
|
|
78
84
|
const TRACE_SUBSCRIPTION_ERROR = 'AssetsSubscriptionError';
|
|
79
85
|
const TRACE_STATE_SIZE = 'AssetsStateSize';
|
|
80
86
|
const log = (0, logger_js_1.createModuleLogger)(logger_js_1.projectLogger, CONTROLLER_NAME);
|
|
@@ -456,7 +462,11 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
456
462
|
customAssets.push(...accountCustomAssets);
|
|
457
463
|
}
|
|
458
464
|
if (options?.forceUpdate) {
|
|
459
|
-
|
|
465
|
+
// Pipeline spans only on unlock/first-init fetch; later forceUpdates pass
|
|
466
|
+
// `undefined` so `emitTrace` / `withTrace` no-op without call-site if/else.
|
|
467
|
+
const pipelineTrace = __classPrivateFieldGet(this, _AssetsController_firstInitFetchReported, "f")
|
|
468
|
+
? undefined
|
|
469
|
+
: __classPrivateFieldGet(this, _AssetsController_trace, "f");
|
|
460
470
|
const request = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildDataRequest).call(this, accounts, chainIds, {
|
|
461
471
|
assetTypes,
|
|
462
472
|
dataTypes,
|
|
@@ -490,59 +500,101 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
490
500
|
]),
|
|
491
501
|
]
|
|
492
502
|
: [__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f")];
|
|
493
|
-
const { response
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
503
|
+
const { response } = await (0, trace_js_1.withTrace)({
|
|
504
|
+
name: TRACE_FETCH_PIPELINE,
|
|
505
|
+
trace: pipelineTrace,
|
|
506
|
+
data: {
|
|
507
|
+
chain_count: chainIds.length,
|
|
508
|
+
account_count: accounts.length,
|
|
509
|
+
basic_functionality: __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this),
|
|
510
|
+
},
|
|
511
|
+
fn: async (parentContext) => {
|
|
512
|
+
const startTime = performance.now();
|
|
513
|
+
const result = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, {
|
|
514
|
+
sources: fastSources,
|
|
515
|
+
request,
|
|
516
|
+
parentContext,
|
|
517
|
+
trace: pipelineTrace,
|
|
518
|
+
});
|
|
519
|
+
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
520
|
+
...result.response,
|
|
521
|
+
updateMode: 'merge',
|
|
522
|
+
replaceCoveredChainBalances: true,
|
|
523
|
+
});
|
|
524
|
+
const durationMs = performance.now() - startTime;
|
|
525
|
+
// Summary fields for Assets Health (nested under the parent span).
|
|
526
|
+
(0, trace_js_1.emitTrace)({
|
|
527
|
+
name: TRACE_FULL_FETCH,
|
|
528
|
+
trace: pipelineTrace,
|
|
529
|
+
data: {
|
|
530
|
+
duration_ms: durationMs,
|
|
531
|
+
chain_count: chainIds.length,
|
|
532
|
+
account_count: accounts.length,
|
|
533
|
+
basic_functionality: __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this),
|
|
534
|
+
asset_count: result.response.assetsBalance
|
|
535
|
+
? Object.values(result.response.assetsBalance).reduce((sum, acct) => sum + Object.keys(acct).length, 0)
|
|
536
|
+
: 0,
|
|
537
|
+
price_count: result.response.assetsPrice
|
|
538
|
+
? Object.keys(result.response.assetsPrice).length
|
|
539
|
+
: 0,
|
|
540
|
+
...result.durationByDataSource,
|
|
541
|
+
},
|
|
542
|
+
parentContext,
|
|
543
|
+
});
|
|
544
|
+
(0, trace_js_1.emitTrace)({
|
|
545
|
+
name: TRACE_FIRST_INIT_FETCH,
|
|
546
|
+
trace: pipelineTrace,
|
|
547
|
+
data: {
|
|
548
|
+
duration_ms: durationMs,
|
|
549
|
+
chain_ids: JSON.stringify(chainIds),
|
|
550
|
+
...result.durationByDataSource,
|
|
551
|
+
},
|
|
552
|
+
parentContext,
|
|
553
|
+
});
|
|
554
|
+
return result;
|
|
555
|
+
},
|
|
498
556
|
});
|
|
499
|
-
//
|
|
500
|
-
|
|
501
|
-
//
|
|
502
|
-
//
|
|
557
|
+
// Mark after the unlock/first forceUpdate so later polls skip pipeline spans.
|
|
558
|
+
__classPrivateFieldSet(this, _AssetsController_firstInitFetchReported, true, "f");
|
|
559
|
+
// Background (slow) lane — flattened sibling of the fast lane (not nested
|
|
560
|
+
// inside its withTrace callback). Still fire-and-forget so UI is not blocked.
|
|
503
561
|
const slowPipelineChainIds = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSlowPipelineChainIds).call(this, chainIds, response);
|
|
504
562
|
if (slowPipelineChainIds.length > 0) {
|
|
505
563
|
const slowSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
506
564
|
? [__classPrivateFieldGet(this, _AssetsController_snapDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")]
|
|
507
565
|
: [__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")];
|
|
508
566
|
const slowRequest = { ...request, chainIds: slowPipelineChainIds };
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
__classPrivateFieldSet(this, _AssetsController_firstInitFetchReported, true, "f");
|
|
541
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_FIRST_INIT_FETCH, {
|
|
542
|
-
duration_ms: durationMs,
|
|
543
|
-
chain_ids: JSON.stringify(chainIds),
|
|
544
|
-
...durationByDataSource,
|
|
545
|
-
});
|
|
567
|
+
(0, trace_js_1.withTrace)({
|
|
568
|
+
name: TRACE_BACKGROUND_FETCH,
|
|
569
|
+
trace: pipelineTrace,
|
|
570
|
+
data: {
|
|
571
|
+
chain_count: slowPipelineChainIds.length,
|
|
572
|
+
account_count: accounts.length,
|
|
573
|
+
},
|
|
574
|
+
fn: async (slowParentContext) => {
|
|
575
|
+
const { response: slowResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, {
|
|
576
|
+
sources: [
|
|
577
|
+
(0, ParallelMiddleware_js_1.createParallelBalanceMiddleware)(slowSources),
|
|
578
|
+
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
579
|
+
...(__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
580
|
+
? [
|
|
581
|
+
(0, ParallelMiddleware_js_1.createParallelMiddleware)([
|
|
582
|
+
__classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
|
|
583
|
+
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
|
|
584
|
+
]),
|
|
585
|
+
]
|
|
586
|
+
: []),
|
|
587
|
+
],
|
|
588
|
+
request: slowRequest,
|
|
589
|
+
parentContext: slowParentContext,
|
|
590
|
+
trace: pipelineTrace,
|
|
591
|
+
});
|
|
592
|
+
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
593
|
+
...slowResponse,
|
|
594
|
+
updateMode: 'merge',
|
|
595
|
+
});
|
|
596
|
+
},
|
|
597
|
+
}).catch((error) => log('Background pipeline failed', { error }));
|
|
546
598
|
}
|
|
547
599
|
}
|
|
548
600
|
const result = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetsFromState).call(this, accounts, chainIds, assetTypes);
|
|
@@ -922,57 +974,87 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
922
974
|
* @param request - Optional original request for context when enriching
|
|
923
975
|
*/
|
|
924
976
|
async handleAssetsUpdate(response, sourceId, request) {
|
|
925
|
-
const updateStart = performance.now();
|
|
926
977
|
log('Assets updated from data source', {
|
|
927
978
|
sourceId,
|
|
928
979
|
hasBalance: Boolean(response.assetsBalance),
|
|
929
980
|
hasPrice: Boolean(response.assetsPrice),
|
|
930
981
|
});
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
:
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
982
|
+
// Enrichment spans only before unlock/first-init fetch completes.
|
|
983
|
+
const pipelineTrace = __classPrivateFieldGet(this, _AssetsController_firstInitFetchReported, "f")
|
|
984
|
+
? undefined
|
|
985
|
+
: __classPrivateFieldGet(this, _AssetsController_trace, "f");
|
|
986
|
+
await (0, trace_js_1.withTrace)({
|
|
987
|
+
name: TRACE_UPDATE_PARENT,
|
|
988
|
+
trace: pipelineTrace,
|
|
989
|
+
data: {
|
|
990
|
+
source: sourceId,
|
|
991
|
+
has_balance: Boolean(response.assetsBalance),
|
|
992
|
+
has_price: Boolean(response.assetsPrice),
|
|
993
|
+
balance_account_count: response.assetsBalance
|
|
994
|
+
? Object.keys(response.assetsBalance).length
|
|
995
|
+
: 0,
|
|
996
|
+
},
|
|
997
|
+
fn: async (parentContext) => {
|
|
998
|
+
const updateStart = performance.now();
|
|
999
|
+
const resolvedRequest = request ?? {
|
|
1000
|
+
accountsWithSupportedChains: [],
|
|
1001
|
+
chainIds: [],
|
|
1002
|
+
dataTypes: ['balance', 'metadata', 'price'],
|
|
1003
|
+
};
|
|
1004
|
+
// RPC-only mode (basic functionality off): never run token/price APIs. Strip
|
|
1005
|
+
// those data types so downstream middleware cannot treat them as requested.
|
|
1006
|
+
const pipelineRequest = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
1007
|
+
? resolvedRequest
|
|
1008
|
+
: {
|
|
1009
|
+
...resolvedRequest,
|
|
1010
|
+
dataTypes: resolvedRequest.dataTypes.filter((dt) => dt !== 'metadata' && dt !== 'price'),
|
|
1011
|
+
};
|
|
1012
|
+
// Graduate custom assets only when AccountsAPI / Websocket reports them.
|
|
1013
|
+
// RPC already fetches custom assets on purpose, and Snap handles non-EVM
|
|
1014
|
+
// chains the rule does not apply to, so skip the middleware for those.
|
|
1015
|
+
const shouldGraduateCustomAssets = sourceId === 'AccountsApiDataSource' ||
|
|
1016
|
+
sourceId === 'BackendWebsocketDataSource' ||
|
|
1017
|
+
sourceId === 'AccountActivityService';
|
|
1018
|
+
const enrichmentSources = [
|
|
1019
|
+
...(shouldGraduateCustomAssets
|
|
1020
|
+
? [__classPrivateFieldGet(this, _AssetsController_customAssetGraduationMiddleware, "f")]
|
|
1021
|
+
: []),
|
|
1022
|
+
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
1023
|
+
];
|
|
1024
|
+
if (__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)) {
|
|
1025
|
+
enrichmentSources.push((0, ParallelMiddleware_js_1.createParallelMiddleware)([
|
|
1026
|
+
__classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
|
|
1027
|
+
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
|
|
1028
|
+
]));
|
|
1029
|
+
}
|
|
1030
|
+
const { response: enrichedResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, {
|
|
1031
|
+
sources: enrichmentSources,
|
|
1032
|
+
request: pipelineRequest,
|
|
1033
|
+
initialResponse: response,
|
|
1034
|
+
parentContext,
|
|
1035
|
+
trace: pipelineTrace,
|
|
1036
|
+
});
|
|
1037
|
+
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
1038
|
+
...enrichedResponse,
|
|
1039
|
+
replaceCoveredChainBalances: response.replaceCoveredChainBalances,
|
|
1040
|
+
});
|
|
1041
|
+
// Summary fields for Assets Health (nested under the parent span).
|
|
1042
|
+
(0, trace_js_1.emitTrace)({
|
|
1043
|
+
name: TRACE_UPDATE_PIPELINE,
|
|
1044
|
+
trace: pipelineTrace,
|
|
1045
|
+
data: {
|
|
1046
|
+
source: sourceId,
|
|
1047
|
+
duration_ms: performance.now() - updateStart,
|
|
1048
|
+
has_balance: Boolean(response.assetsBalance),
|
|
1049
|
+
has_price: Boolean(response.assetsPrice),
|
|
1050
|
+
has_metadata: Boolean(enrichedResponse.assetsInfo),
|
|
1051
|
+
balance_account_count: response.assetsBalance
|
|
1052
|
+
? Object.keys(response.assetsBalance).length
|
|
1053
|
+
: 0,
|
|
1054
|
+
},
|
|
1055
|
+
parentContext,
|
|
1056
|
+
});
|
|
1057
|
+
},
|
|
976
1058
|
});
|
|
977
1059
|
}
|
|
978
1060
|
// ============================================================================
|
|
@@ -1012,16 +1094,7 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
1012
1094
|
}
|
|
1013
1095
|
}
|
|
1014
1096
|
exports.AssetsController = AssetsController;
|
|
1015
|
-
_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_accountRefreshMutex = 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(),
|
|
1016
|
-
controller: 'AssetsController',
|
|
1017
|
-
}) {
|
|
1018
|
-
if (!__classPrivateFieldGet(this, _AssetsController_trace, "f")) {
|
|
1019
|
-
return;
|
|
1020
|
-
}
|
|
1021
|
-
__classPrivateFieldGet(this, _AssetsController_trace, "f").call(this, { name, data, tags }, () => undefined)?.catch(() => {
|
|
1022
|
-
// Telemetry failure must not break.
|
|
1023
|
-
});
|
|
1024
|
-
}, _AssetsController_emitStateSizeTrace = function _AssetsController_emitStateSizeTrace() {
|
|
1097
|
+
_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_accountRefreshMutex = 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_emitStateSizeTrace = function _AssetsController_emitStateSizeTrace() {
|
|
1025
1098
|
if (!__classPrivateFieldGet(this, _AssetsController_trace, "f") || __classPrivateFieldGet(this, _AssetsController_stateSizeReported, "f")) {
|
|
1026
1099
|
return;
|
|
1027
1100
|
}
|
|
@@ -1049,14 +1122,20 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
|
|
|
1049
1122
|
customAssetEntries += ids.length;
|
|
1050
1123
|
}
|
|
1051
1124
|
}
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1125
|
+
(0, trace_js_1.emitTrace)({
|
|
1126
|
+
name: TRACE_STATE_SIZE,
|
|
1127
|
+
trace: __classPrivateFieldGet(this, _AssetsController_trace, "f"),
|
|
1128
|
+
data: {
|
|
1129
|
+
balance_entries: balanceEntries,
|
|
1130
|
+
balance_accounts: Object.keys(balances).length,
|
|
1131
|
+
// `asset_count` matches the Assets Health dashboard widget field name.
|
|
1132
|
+
asset_count: uniqueAssets.size,
|
|
1133
|
+
unique_asset_count: uniqueAssets.size,
|
|
1134
|
+
network_count: uniqueNetworks.size,
|
|
1135
|
+
metadata_entries: Object.keys(assetsInfo).length,
|
|
1136
|
+
price_entries: Object.keys(assetsPrice).length,
|
|
1137
|
+
custom_asset_entries: customAssetEntries,
|
|
1138
|
+
},
|
|
1060
1139
|
});
|
|
1061
1140
|
}, _AssetsController_getSelectedAccounts = function _AssetsController_getSelectedAccounts() {
|
|
1062
1141
|
const accounts = this.messenger.call('AccountTreeController:getAccountsFromSelectedAccountGroup');
|
|
@@ -1381,12 +1460,16 @@ async function _AssetsController_runStartupRefresh(accounts) {
|
|
|
1381
1460
|
* Execute middlewares with request/response context.
|
|
1382
1461
|
* Returns response and exclusive duration per source (sum ≈ wall time).
|
|
1383
1462
|
*
|
|
1384
|
-
* @param
|
|
1385
|
-
* @param
|
|
1386
|
-
* @param
|
|
1463
|
+
* @param params - Middleware execution options.
|
|
1464
|
+
* @param params.sources - Data sources or middlewares with getName() and assetsMiddleware.
|
|
1465
|
+
* @param params.request - The data request.
|
|
1466
|
+
* @param params.initialResponse - Optional initial response (for enriching existing data).
|
|
1467
|
+
* @param params.parentContext - Optional parent Sentry span; per-source timings nest under it.
|
|
1468
|
+
* @param params.trace - Optional trace callback; omit after unlock/first-init to skip spans.
|
|
1387
1469
|
* @returns Response and durationByDataSource (exclusive ms per source name).
|
|
1388
1470
|
*/
|
|
1389
|
-
async function _AssetsController_executeMiddlewares(
|
|
1471
|
+
async function _AssetsController_executeMiddlewares(params) {
|
|
1472
|
+
const { sources, request, initialResponse = {}, parentContext, trace, } = params;
|
|
1390
1473
|
const names = sources.map((source) => source.getName());
|
|
1391
1474
|
const middlewares = sources.map((source) => source.assetsMiddleware);
|
|
1392
1475
|
const inclusive = [];
|
|
@@ -1430,13 +1513,24 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1430
1513
|
durationByDataSource[key] = ms;
|
|
1431
1514
|
}
|
|
1432
1515
|
}
|
|
1433
|
-
// Emit per-source timing
|
|
1516
|
+
// Emit per-source timing as subspans under the parent fetch/update span
|
|
1517
|
+
// (no-op when `trace` is omitted — unlock/first-init only).
|
|
1434
1518
|
for (const [sourceName, durationMs] of Object.entries(durationByDataSource)) {
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1519
|
+
(0, trace_js_1.emitTrace)({
|
|
1520
|
+
name: TRACE_DATA_SOURCE_TIMING,
|
|
1521
|
+
trace,
|
|
1522
|
+
data: {
|
|
1523
|
+
source: sourceName,
|
|
1524
|
+
duration_ms: durationMs,
|
|
1525
|
+
chain_count: request.chainIds.length,
|
|
1526
|
+
account_count: request.accountsWithSupportedChains.length,
|
|
1527
|
+
},
|
|
1528
|
+
tags: {
|
|
1529
|
+
controller: 'AssetsController',
|
|
1530
|
+
// String tag so Spans widgets can group by `source`.
|
|
1531
|
+
source: sourceName,
|
|
1532
|
+
},
|
|
1533
|
+
parentContext,
|
|
1440
1534
|
});
|
|
1441
1535
|
}
|
|
1442
1536
|
// Failed middlewares: Issues (optional) + perf/Dashboard spans
|
|
@@ -1453,14 +1547,20 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1453
1547
|
catch {
|
|
1454
1548
|
// Never let telemetry throw.
|
|
1455
1549
|
}
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1550
|
+
(0, trace_js_1.emitTrace)({
|
|
1551
|
+
name: TRACE_DATA_SOURCE_ERROR,
|
|
1552
|
+
trace,
|
|
1553
|
+
data: {
|
|
1554
|
+
failed_sources: failedSources,
|
|
1555
|
+
error_count: middlewareErrors.length,
|
|
1556
|
+
chain_count: request.chainIds.length,
|
|
1557
|
+
},
|
|
1558
|
+
tags: {
|
|
1559
|
+
controller: 'AssetsController',
|
|
1560
|
+
severity: 'error',
|
|
1561
|
+
error_type: assetsError.name,
|
|
1562
|
+
},
|
|
1563
|
+
parentContext,
|
|
1464
1564
|
});
|
|
1465
1565
|
}
|
|
1466
1566
|
return { response: result.response, durationByDataSource };
|
|
@@ -2082,9 +2182,13 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
2082
2182
|
};
|
|
2083
2183
|
source.subscribe(subscribeReq).catch((error) => {
|
|
2084
2184
|
console.error(`[AssetsController] Failed to subscribe to '${sourceId}':`, error);
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2185
|
+
(0, trace_js_1.emitTrace)({
|
|
2186
|
+
name: TRACE_SUBSCRIPTION_ERROR,
|
|
2187
|
+
trace: __classPrivateFieldGet(this, _AssetsController_trace, "f"),
|
|
2188
|
+
data: {
|
|
2189
|
+
source: sourceId,
|
|
2190
|
+
error_message: String(error),
|
|
2191
|
+
},
|
|
2088
2192
|
});
|
|
2089
2193
|
});
|
|
2090
2194
|
// Track subscription
|