@metamask-previews/assets-controller 11.2.1-preview-e0f702919 → 11.2.1-preview-397d3ad4d
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 +2 -3
- package/dist/AssetsController.cjs +131 -188
- 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 +131 -188
- package/dist/AssetsController.mjs.map +1 -1
- package/dist/data-sources/SnapDataSource.cjs +8 -49
- package/dist/data-sources/SnapDataSource.cjs.map +1 -1
- package/dist/data-sources/SnapDataSource.d.cts +9 -0
- package/dist/data-sources/SnapDataSource.d.cts.map +1 -1
- package/dist/data-sources/SnapDataSource.d.mts +9 -0
- package/dist/data-sources/SnapDataSource.d.mts.map +1 -1
- package/dist/data-sources/SnapDataSource.mjs +8 -49
- package/dist/data-sources/SnapDataSource.mjs.map +1 -1
- package/dist/selectors/balance.cjs +1 -19
- 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 +1 -19
- package/dist/selectors/balance.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,10 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
-
###
|
|
10
|
+
### Fixed
|
|
11
11
|
|
|
12
|
-
-
|
|
13
|
-
- Pipeline traces (`AssetsFullFetch`, `AssetsUpdatePipeline`, per-source timings, etc.) run on cold start only (first `#start` fetch per unlock session); later fetches/updates skip Sentry wrapping. Subscription errors and the one-shot state-size trace remain enabled.
|
|
12
|
+
- `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))
|
|
14
13
|
|
|
15
14
|
## [11.2.1]
|
|
16
15
|
|
|
@@ -13,7 +13,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
13
13
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
15
|
};
|
|
16
|
-
var _AssetsController_instances, _AssetsController_isEnabled, _AssetsController_isBasicFunctionality, _AssetsController_defaultUpdateInterval, _AssetsController_trace, _AssetsController_captureException, _AssetsController_firstInitFetchReported, _AssetsController_stateSizeReported, _AssetsController_emitTrace,
|
|
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_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");
|
|
@@ -72,7 +72,6 @@ const DEFAULT_POLLING_INTERVAL_MS = 30000;
|
|
|
72
72
|
// ============================================================================
|
|
73
73
|
const TRACE_FIRST_INIT_FETCH = 'AssetsControllerFirstInitFetch';
|
|
74
74
|
const TRACE_FULL_FETCH = 'AssetsFullFetch';
|
|
75
|
-
const TRACE_BACKGROUND_FETCH = 'AssetsBackgroundFetch';
|
|
76
75
|
const TRACE_DATA_SOURCE_TIMING = 'AssetsDataSourceTiming';
|
|
77
76
|
const TRACE_DATA_SOURCE_ERROR = 'AssetsDataSourceError';
|
|
78
77
|
const TRACE_UPDATE_PIPELINE = 'AssetsUpdatePipeline';
|
|
@@ -367,6 +366,7 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
367
366
|
__classPrivateFieldSet(this, _AssetsController_snapDataSource, new SnapDataSource_js_1.SnapDataSource({
|
|
368
367
|
messenger: this.messenger,
|
|
369
368
|
onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
|
|
369
|
+
onAssetsUpdate: (response) => this.handleAssetsUpdate(response, 'SnapDataSource'),
|
|
370
370
|
}), "f");
|
|
371
371
|
__classPrivateFieldSet(this, _AssetsController_rpcDataSource, new RpcDataSource_js_1.RpcDataSource({
|
|
372
372
|
messenger: this.messenger,
|
|
@@ -456,111 +456,94 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
456
456
|
customAssets.push(...accountCustomAssets);
|
|
457
457
|
}
|
|
458
458
|
if (options?.forceUpdate) {
|
|
459
|
-
|
|
459
|
+
const startTime = performance.now();
|
|
460
|
+
const request = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildDataRequest).call(this, accounts, chainIds, {
|
|
461
|
+
assetTypes,
|
|
462
|
+
dataTypes,
|
|
463
|
+
customAssets: customAssets.length > 0 ? customAssets : undefined,
|
|
464
|
+
forceUpdate: true,
|
|
465
|
+
assetsForPriceUpdate: options?.assetsForPriceUpdate,
|
|
466
|
+
});
|
|
467
|
+
// Fast pipeline: accountsApi + stakedBalance → detection → token + price.
|
|
468
|
+
// Snap and RPC are excluded here due to their latency (snap triggers account
|
|
469
|
+
// creation, RPC is slow on many chains). Results are committed to state
|
|
470
|
+
// immediately so the UI can display balances without waiting for them.
|
|
471
|
+
//
|
|
472
|
+
// Fast/slow pipelines use merge so partial API snapshots cannot wipe
|
|
473
|
+
// tokens missing from the response (e.g. USDC when only native balance
|
|
474
|
+
// is returned). Balances present in the response are still refreshed.
|
|
475
|
+
const fastSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
476
|
+
? [
|
|
477
|
+
(0, ParallelMiddleware_js_1.createParallelBalanceMiddleware)([
|
|
478
|
+
__classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f"),
|
|
479
|
+
__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"),
|
|
480
|
+
]),
|
|
481
|
+
// Graduation must run BEFORE the RPC fallback so it only sees
|
|
482
|
+
// AccountsApi/Websocket balances. RPC intentionally carries
|
|
483
|
+
// custom assets and must never trigger graduation.
|
|
484
|
+
__classPrivateFieldGet(this, _AssetsController_customAssetGraduationMiddleware, "f"),
|
|
485
|
+
__classPrivateFieldGet(this, _AssetsController_rpcFallbackMiddleware, "f"),
|
|
486
|
+
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
487
|
+
(0, ParallelMiddleware_js_1.createParallelMiddleware)([
|
|
488
|
+
__classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
|
|
489
|
+
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
|
|
490
|
+
]),
|
|
491
|
+
]
|
|
492
|
+
: [__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f")];
|
|
493
|
+
const { response, durationByDataSource } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, fastSources, request);
|
|
494
|
+
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
495
|
+
...response,
|
|
496
|
+
updateMode: 'merge',
|
|
497
|
+
replaceCoveredChainBalances: true,
|
|
498
|
+
});
|
|
499
|
+
// Background pipeline: snap and RPC run in parallel after the fast path
|
|
500
|
+
// commits to state. Their balances are merged together before detection.
|
|
501
|
+
// Token + price enrichment matches the pre-split behavior: only when basic
|
|
502
|
+
// functionality is on (RPC-only mode must not call token/price APIs).
|
|
503
|
+
const slowPipelineChainIds = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSlowPipelineChainIds).call(this, chainIds, response);
|
|
504
|
+
if (slowPipelineChainIds.length > 0) {
|
|
505
|
+
const slowSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
506
|
+
? [__classPrivateFieldGet(this, _AssetsController_snapDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")]
|
|
507
|
+
: [__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")];
|
|
508
|
+
const slowRequest = { ...request, chainIds: slowPipelineChainIds };
|
|
509
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, [
|
|
510
|
+
(0, ParallelMiddleware_js_1.createParallelBalanceMiddleware)(slowSources),
|
|
511
|
+
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
512
|
+
...(__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
513
|
+
? [
|
|
514
|
+
(0, ParallelMiddleware_js_1.createParallelMiddleware)([
|
|
515
|
+
__classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
|
|
516
|
+
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
|
|
517
|
+
]),
|
|
518
|
+
]
|
|
519
|
+
: []),
|
|
520
|
+
], slowRequest)
|
|
521
|
+
.then(({ response: slowResponse }) => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, { ...slowResponse, updateMode: 'merge' }))
|
|
522
|
+
.catch((error) => log('Background pipeline failed', { error }));
|
|
523
|
+
}
|
|
524
|
+
const durationMs = performance.now() - startTime;
|
|
525
|
+
// Emit trace for every full fetch (Assets Health dashboard)
|
|
526
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_FULL_FETCH, {
|
|
527
|
+
duration_ms: durationMs,
|
|
460
528
|
chain_count: chainIds.length,
|
|
461
529
|
account_count: accounts.length,
|
|
462
530
|
basic_functionality: __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this),
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
// creation, RPC is slow on many chains). Results are committed to state
|
|
475
|
-
// immediately so the UI can display balances without waiting for them.
|
|
476
|
-
//
|
|
477
|
-
// Fast/slow pipelines use merge so partial API snapshots cannot wipe
|
|
478
|
-
// tokens missing from the response (e.g. USDC when only native balance
|
|
479
|
-
// is returned). Balances present in the response are still refreshed.
|
|
480
|
-
const fastSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
481
|
-
? [
|
|
482
|
-
(0, ParallelMiddleware_js_1.createParallelBalanceMiddleware)([
|
|
483
|
-
__classPrivateFieldGet(this, _AssetsController_accountsApiDataSource, "f"),
|
|
484
|
-
__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"),
|
|
485
|
-
]),
|
|
486
|
-
// Graduation must run BEFORE the RPC fallback so it only sees
|
|
487
|
-
// AccountsApi/Websocket balances. RPC intentionally carries
|
|
488
|
-
// custom assets and must never trigger graduation.
|
|
489
|
-
__classPrivateFieldGet(this, _AssetsController_customAssetGraduationMiddleware, "f"),
|
|
490
|
-
__classPrivateFieldGet(this, _AssetsController_rpcFallbackMiddleware, "f"),
|
|
491
|
-
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
492
|
-
(0, ParallelMiddleware_js_1.createParallelMiddleware)([
|
|
493
|
-
__classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
|
|
494
|
-
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
|
|
495
|
-
]),
|
|
496
|
-
]
|
|
497
|
-
: [__classPrivateFieldGet(this, _AssetsController_stakedBalanceDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f")];
|
|
498
|
-
const { response, durationByDataSource } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, fastSources, request, {}, parentContext);
|
|
499
|
-
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
500
|
-
...response,
|
|
501
|
-
updateMode: 'merge',
|
|
502
|
-
replaceCoveredChainBalances: true,
|
|
503
|
-
});
|
|
504
|
-
// Background pipeline: snap and RPC run in parallel after the fast path
|
|
505
|
-
// commits to state. Their balances are merged together before detection.
|
|
506
|
-
// Token + price enrichment matches the pre-split behavior: only when basic
|
|
507
|
-
// functionality is on (RPC-only mode must not call token/price APIs).
|
|
508
|
-
// Own parent span so timings nest instead of becoming extra root traces
|
|
509
|
-
// after the fast-path parent has ended.
|
|
510
|
-
const slowPipelineChainIds = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSlowPipelineChainIds).call(this, chainIds, response);
|
|
511
|
-
if (slowPipelineChainIds.length > 0) {
|
|
512
|
-
const slowSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
513
|
-
? [__classPrivateFieldGet(this, _AssetsController_snapDataSource, "f"), __classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")]
|
|
514
|
-
: [__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")];
|
|
515
|
-
const slowRequest = { ...request, chainIds: slowPipelineChainIds };
|
|
516
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_withTrace).call(this, TRACE_BACKGROUND_FETCH, {
|
|
517
|
-
chain_count: slowPipelineChainIds.length,
|
|
518
|
-
account_count: accounts.length,
|
|
519
|
-
}, async (slowParentContext) => {
|
|
520
|
-
const { response: slowResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, [
|
|
521
|
-
(0, ParallelMiddleware_js_1.createParallelBalanceMiddleware)(slowSources),
|
|
522
|
-
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
523
|
-
...(__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
524
|
-
? [
|
|
525
|
-
(0, ParallelMiddleware_js_1.createParallelMiddleware)([
|
|
526
|
-
__classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
|
|
527
|
-
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
|
|
528
|
-
]),
|
|
529
|
-
]
|
|
530
|
-
: []),
|
|
531
|
-
], slowRequest, {}, slowParentContext);
|
|
532
|
-
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
533
|
-
...slowResponse,
|
|
534
|
-
updateMode: 'merge',
|
|
535
|
-
});
|
|
536
|
-
}).catch((error) => log('Background pipeline failed', { error }));
|
|
537
|
-
}
|
|
538
|
-
const durationMs = performance.now() - startTime;
|
|
539
|
-
// Summary fields for Assets Health (nested under the parent span so
|
|
540
|
-
// they do not create additional root transactions).
|
|
541
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_FULL_FETCH, {
|
|
531
|
+
asset_count: response.assetsBalance
|
|
532
|
+
? Object.values(response.assetsBalance).reduce((sum, acct) => sum + Object.keys(acct).length, 0)
|
|
533
|
+
: 0,
|
|
534
|
+
price_count: response.assetsPrice
|
|
535
|
+
? Object.keys(response.assetsPrice).length
|
|
536
|
+
: 0,
|
|
537
|
+
...durationByDataSource,
|
|
538
|
+
});
|
|
539
|
+
if (!__classPrivateFieldGet(this, _AssetsController_firstInitFetchReported, "f")) {
|
|
540
|
+
__classPrivateFieldSet(this, _AssetsController_firstInitFetchReported, true, "f");
|
|
541
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_FIRST_INIT_FETCH, {
|
|
542
542
|
duration_ms: durationMs,
|
|
543
|
-
|
|
544
|
-
account_count: accounts.length,
|
|
545
|
-
basic_functionality: __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this),
|
|
546
|
-
asset_count: response.assetsBalance
|
|
547
|
-
? Object.values(response.assetsBalance).reduce((sum, acct) => sum + Object.keys(acct).length, 0)
|
|
548
|
-
: 0,
|
|
549
|
-
price_count: response.assetsPrice
|
|
550
|
-
? Object.keys(response.assetsPrice).length
|
|
551
|
-
: 0,
|
|
543
|
+
chain_ids: JSON.stringify(chainIds),
|
|
552
544
|
...durationByDataSource,
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_FIRST_INIT_FETCH, {
|
|
556
|
-
duration_ms: durationMs,
|
|
557
|
-
chain_ids: JSON.stringify(chainIds),
|
|
558
|
-
...durationByDataSource,
|
|
559
|
-
}, { controller: 'AssetsController' }, parentContext);
|
|
560
|
-
// Mark after emitting so the first-init span itself is not gated.
|
|
561
|
-
__classPrivateFieldSet(this, _AssetsController_firstInitFetchReported, true, "f");
|
|
562
|
-
}
|
|
563
|
-
});
|
|
545
|
+
});
|
|
546
|
+
}
|
|
564
547
|
}
|
|
565
548
|
const result = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetsFromState).call(this, accounts, chainIds, assetTypes);
|
|
566
549
|
return result;
|
|
@@ -939,67 +922,57 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
939
922
|
* @param request - Optional original request for context when enriching
|
|
940
923
|
*/
|
|
941
924
|
async handleAssetsUpdate(response, sourceId, request) {
|
|
925
|
+
const updateStart = performance.now();
|
|
942
926
|
log('Assets updated from data source', {
|
|
943
927
|
sourceId,
|
|
944
928
|
hasBalance: Boolean(response.assetsBalance),
|
|
945
929
|
hasPrice: Boolean(response.assetsPrice),
|
|
946
930
|
});
|
|
947
|
-
|
|
931
|
+
const resolvedRequest = request ?? {
|
|
932
|
+
accountsWithSupportedChains: [],
|
|
933
|
+
chainIds: [],
|
|
934
|
+
dataTypes: ['balance', 'metadata', 'price'],
|
|
935
|
+
};
|
|
936
|
+
// RPC-only mode (basic functionality off): never run token/price APIs. Strip
|
|
937
|
+
// those data types so downstream middleware cannot treat them as requested.
|
|
938
|
+
const pipelineRequest = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
939
|
+
? resolvedRequest
|
|
940
|
+
: {
|
|
941
|
+
...resolvedRequest,
|
|
942
|
+
dataTypes: resolvedRequest.dataTypes.filter((dt) => dt !== 'metadata' && dt !== 'price'),
|
|
943
|
+
};
|
|
944
|
+
// Graduate custom assets only when AccountsAPI / Websocket reports them.
|
|
945
|
+
// RPC already fetches custom assets on purpose, and Snap handles non-EVM
|
|
946
|
+
// chains the rule does not apply to, so skip the middleware for those.
|
|
947
|
+
const shouldGraduateCustomAssets = sourceId === 'AccountsApiDataSource' ||
|
|
948
|
+
sourceId === 'BackendWebsocketDataSource' ||
|
|
949
|
+
sourceId === 'AccountActivityService';
|
|
950
|
+
const enrichmentSources = [
|
|
951
|
+
...(shouldGraduateCustomAssets
|
|
952
|
+
? [__classPrivateFieldGet(this, _AssetsController_customAssetGraduationMiddleware, "f")]
|
|
953
|
+
: []),
|
|
954
|
+
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
955
|
+
];
|
|
956
|
+
if (__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)) {
|
|
957
|
+
enrichmentSources.push((0, ParallelMiddleware_js_1.createParallelMiddleware)([
|
|
958
|
+
__classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
|
|
959
|
+
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
|
|
960
|
+
]));
|
|
961
|
+
}
|
|
962
|
+
const { response: enrichedResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, enrichmentSources, pipelineRequest, response);
|
|
963
|
+
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
964
|
+
...enrichedResponse,
|
|
965
|
+
replaceCoveredChainBalances: response.replaceCoveredChainBalances,
|
|
966
|
+
});
|
|
967
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_UPDATE_PIPELINE, {
|
|
948
968
|
source: sourceId,
|
|
969
|
+
duration_ms: performance.now() - updateStart,
|
|
949
970
|
has_balance: Boolean(response.assetsBalance),
|
|
950
971
|
has_price: Boolean(response.assetsPrice),
|
|
972
|
+
has_metadata: Boolean(enrichedResponse.assetsInfo),
|
|
951
973
|
balance_account_count: response.assetsBalance
|
|
952
974
|
? Object.keys(response.assetsBalance).length
|
|
953
975
|
: 0,
|
|
954
|
-
}, async (parentContext) => {
|
|
955
|
-
const updateStart = performance.now();
|
|
956
|
-
const resolvedRequest = request ?? {
|
|
957
|
-
accountsWithSupportedChains: [],
|
|
958
|
-
chainIds: [],
|
|
959
|
-
dataTypes: ['balance', 'metadata', 'price'],
|
|
960
|
-
};
|
|
961
|
-
// RPC-only mode (basic functionality off): never run token/price APIs. Strip
|
|
962
|
-
// those data types so downstream middleware cannot treat them as requested.
|
|
963
|
-
const pipelineRequest = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
|
|
964
|
-
? resolvedRequest
|
|
965
|
-
: {
|
|
966
|
-
...resolvedRequest,
|
|
967
|
-
dataTypes: resolvedRequest.dataTypes.filter((dt) => dt !== 'metadata' && dt !== 'price'),
|
|
968
|
-
};
|
|
969
|
-
// Graduate custom assets only when AccountsAPI / Websocket reports them.
|
|
970
|
-
// RPC already fetches custom assets on purpose, and Snap handles non-EVM
|
|
971
|
-
// chains the rule does not apply to, so skip the middleware for those.
|
|
972
|
-
const shouldGraduateCustomAssets = sourceId === 'AccountsApiDataSource' ||
|
|
973
|
-
sourceId === 'BackendWebsocketDataSource' ||
|
|
974
|
-
sourceId === 'AccountActivityService';
|
|
975
|
-
const enrichmentSources = [
|
|
976
|
-
...(shouldGraduateCustomAssets
|
|
977
|
-
? [__classPrivateFieldGet(this, _AssetsController_customAssetGraduationMiddleware, "f")]
|
|
978
|
-
: []),
|
|
979
|
-
__classPrivateFieldGet(this, _AssetsController_detectionMiddleware, "f"),
|
|
980
|
-
];
|
|
981
|
-
if (__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)) {
|
|
982
|
-
enrichmentSources.push((0, ParallelMiddleware_js_1.createParallelMiddleware)([
|
|
983
|
-
__classPrivateFieldGet(this, _AssetsController_tokenDataSource, "f"),
|
|
984
|
-
__classPrivateFieldGet(this, _AssetsController_priceDataSource, "f"),
|
|
985
|
-
]));
|
|
986
|
-
}
|
|
987
|
-
const { response: enrichedResponse } = await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_executeMiddlewares).call(this, enrichmentSources, pipelineRequest, response, parentContext);
|
|
988
|
-
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, {
|
|
989
|
-
...enrichedResponse,
|
|
990
|
-
replaceCoveredChainBalances: response.replaceCoveredChainBalances,
|
|
991
|
-
});
|
|
992
|
-
// Summary fields for Assets Health (nested under the parent span).
|
|
993
|
-
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_UPDATE_PIPELINE, {
|
|
994
|
-
source: sourceId,
|
|
995
|
-
duration_ms: performance.now() - updateStart,
|
|
996
|
-
has_balance: Boolean(response.assetsBalance),
|
|
997
|
-
has_price: Boolean(response.assetsPrice),
|
|
998
|
-
has_metadata: Boolean(enrichedResponse.assetsInfo),
|
|
999
|
-
balance_account_count: response.assetsBalance
|
|
1000
|
-
? Object.keys(response.assetsBalance).length
|
|
1001
|
-
: 0,
|
|
1002
|
-
}, { controller: 'AssetsController' }, parentContext);
|
|
1003
976
|
});
|
|
1004
977
|
}
|
|
1005
978
|
// ============================================================================
|
|
@@ -1041,42 +1014,13 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
1041
1014
|
exports.AssetsController = AssetsController;
|
|
1042
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(), _AssetsController_emitTrace = function _AssetsController_emitTrace(name, data, tags = {
|
|
1043
1016
|
controller: 'AssetsController',
|
|
1044
|
-
}
|
|
1017
|
+
}) {
|
|
1045
1018
|
if (!__classPrivateFieldGet(this, _AssetsController_trace, "f")) {
|
|
1046
1019
|
return;
|
|
1047
1020
|
}
|
|
1048
|
-
|
|
1049
|
-
// subspans (parentContext set) and error/state-size traces still allowed.
|
|
1050
|
-
if (__classPrivateFieldGet(this, _AssetsController_firstInitFetchReported, "f") &&
|
|
1051
|
-
parentContext === undefined &&
|
|
1052
|
-
name !== TRACE_SUBSCRIPTION_ERROR &&
|
|
1053
|
-
name !== TRACE_STATE_SIZE) {
|
|
1054
|
-
return;
|
|
1055
|
-
}
|
|
1056
|
-
__classPrivateFieldGet(this, _AssetsController_trace, "f").call(this, { name, data, tags, parentContext }, () => undefined)?.catch(() => {
|
|
1021
|
+
__classPrivateFieldGet(this, _AssetsController_trace, "f").call(this, { name, data, tags }, () => undefined)?.catch(() => {
|
|
1057
1022
|
// Telemetry failure must not break.
|
|
1058
1023
|
});
|
|
1059
|
-
}, _AssetsController_withTrace =
|
|
1060
|
-
/**
|
|
1061
|
-
* Run work inside a parent Sentry span and pass its context so callers can
|
|
1062
|
-
* emit nested subspans via {@link #emitTrace}.
|
|
1063
|
-
*
|
|
1064
|
-
* Only wraps work on cold start (before the first init fetch is reported).
|
|
1065
|
-
* Later calls still run `fn`, but without creating a Sentry parent span.
|
|
1066
|
-
*
|
|
1067
|
-
* @param name - Parent span name.
|
|
1068
|
-
* @param data - Key-value pairs attached as span data.
|
|
1069
|
-
* @param fn - Work to run; receives the parent span context.
|
|
1070
|
-
* @param tags - Key-value pairs used for Sentry filtering.
|
|
1071
|
-
* @returns The result of `fn`.
|
|
1072
|
-
*/
|
|
1073
|
-
async function _AssetsController_withTrace(name, data, fn, tags = {
|
|
1074
|
-
controller: 'AssetsController',
|
|
1075
|
-
}) {
|
|
1076
|
-
if (!__classPrivateFieldGet(this, _AssetsController_trace, "f") || __classPrivateFieldGet(this, _AssetsController_firstInitFetchReported, "f")) {
|
|
1077
|
-
return fn(undefined);
|
|
1078
|
-
}
|
|
1079
|
-
return await __classPrivateFieldGet(this, _AssetsController_trace, "f").call(this, { name, data, tags }, (parentContext) => fn(parentContext));
|
|
1080
1024
|
}, _AssetsController_emitStateSizeTrace = function _AssetsController_emitStateSizeTrace() {
|
|
1081
1025
|
if (!__classPrivateFieldGet(this, _AssetsController_trace, "f") || __classPrivateFieldGet(this, _AssetsController_stateSizeReported, "f")) {
|
|
1082
1026
|
return;
|
|
@@ -1440,10 +1384,9 @@ async function _AssetsController_runStartupRefresh(accounts) {
|
|
|
1440
1384
|
* @param sources - Data sources or middlewares with getName() and assetsMiddleware (executed in order).
|
|
1441
1385
|
* @param request - The data request.
|
|
1442
1386
|
* @param initialResponse - Optional initial response (for enriching existing data).
|
|
1443
|
-
* @param parentContext - Optional parent Sentry span; per-source timings nest under it.
|
|
1444
1387
|
* @returns Response and durationByDataSource (exclusive ms per source name).
|
|
1445
1388
|
*/
|
|
1446
|
-
async function _AssetsController_executeMiddlewares(sources, request, initialResponse = {}
|
|
1389
|
+
async function _AssetsController_executeMiddlewares(sources, request, initialResponse = {}) {
|
|
1447
1390
|
const names = sources.map((source) => source.getName());
|
|
1448
1391
|
const middlewares = sources.map((source) => source.assetsMiddleware);
|
|
1449
1392
|
const inclusive = [];
|
|
@@ -1487,14 +1430,14 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1487
1430
|
durationByDataSource[key] = ms;
|
|
1488
1431
|
}
|
|
1489
1432
|
}
|
|
1490
|
-
// Emit per-source timing
|
|
1433
|
+
// Emit per-source timing traces for the Assets Health dashboard
|
|
1491
1434
|
for (const [sourceName, durationMs] of Object.entries(durationByDataSource)) {
|
|
1492
1435
|
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_DATA_SOURCE_TIMING, {
|
|
1493
1436
|
source: sourceName,
|
|
1494
1437
|
duration_ms: durationMs,
|
|
1495
1438
|
chain_count: request.chainIds.length,
|
|
1496
1439
|
account_count: request.accountsWithSupportedChains.length,
|
|
1497
|
-
}
|
|
1440
|
+
});
|
|
1498
1441
|
}
|
|
1499
1442
|
// Failed middlewares: Issues (optional) + perf/Dashboard spans
|
|
1500
1443
|
if (middlewareErrors.length > 0) {
|
|
@@ -1518,7 +1461,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1518
1461
|
controller: 'AssetsController',
|
|
1519
1462
|
severity: 'error',
|
|
1520
1463
|
error_type: assetsError.name,
|
|
1521
|
-
}
|
|
1464
|
+
});
|
|
1522
1465
|
}
|
|
1523
1466
|
return { response: result.response, durationByDataSource };
|
|
1524
1467
|
}, _AssetsController_fetchMissingPricesWithoutCache = function _AssetsController_fetchMissingPricesWithoutCache(accounts, chainIds) {
|