@metamask/assets-controller 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -1
- package/dist/AssetsController-method-action-types.cjs +1 -1
- package/dist/AssetsController-method-action-types.cjs.map +1 -1
- package/dist/AssetsController-method-action-types.d.cts +1 -1
- package/dist/AssetsController-method-action-types.d.mts +1 -1
- package/dist/AssetsController-method-action-types.mjs +1 -1
- package/dist/AssetsController-method-action-types.mjs.map +1 -1
- package/dist/AssetsController.cjs +123 -22
- 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 +123 -22
- package/dist/AssetsController.mjs.map +1 -1
- package/dist/data-sources/RpcDataSource.cjs +18 -22
- package/dist/data-sources/RpcDataSource.cjs.map +1 -1
- package/dist/data-sources/RpcDataSource.d.cts.map +1 -1
- package/dist/data-sources/RpcDataSource.d.mts.map +1 -1
- package/dist/data-sources/RpcDataSource.mjs +18 -22
- package/dist/data-sources/RpcDataSource.mjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/clients/MulticallClient.cjs +3 -6
- package/dist/data-sources/evm-rpc-services/clients/MulticallClient.cjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/clients/MulticallClient.d.cts.map +1 -1
- package/dist/data-sources/evm-rpc-services/clients/MulticallClient.d.mts.map +1 -1
- package/dist/data-sources/evm-rpc-services/clients/MulticallClient.mjs +1 -4
- package/dist/data-sources/evm-rpc-services/clients/MulticallClient.mjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/index.cjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/index.d.cts +1 -1
- package/dist/data-sources/evm-rpc-services/index.d.cts.map +1 -1
- package/dist/data-sources/evm-rpc-services/index.d.mts +1 -1
- package/dist/data-sources/evm-rpc-services/index.d.mts.map +1 -1
- package/dist/data-sources/evm-rpc-services/index.mjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.cjs +87 -76
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.cjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.cts +20 -8
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.cts.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.mts +20 -8
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.mts.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.mjs +85 -74
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.mjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/types/index.cjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/types/index.d.cts +1 -1
- package/dist/data-sources/evm-rpc-services/types/index.d.cts.map +1 -1
- package/dist/data-sources/evm-rpc-services/types/index.d.mts +1 -1
- package/dist/data-sources/evm-rpc-services/types/index.d.mts.map +1 -1
- package/dist/data-sources/evm-rpc-services/types/index.mjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/types/services.cjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/types/services.d.cts +9 -17
- package/dist/data-sources/evm-rpc-services/types/services.d.cts.map +1 -1
- package/dist/data-sources/evm-rpc-services/types/services.d.mts +9 -17
- package/dist/data-sources/evm-rpc-services/types/services.d.mts.map +1 -1
- package/dist/data-sources/evm-rpc-services/types/services.mjs.map +1 -1
- package/dist/selectors/balance.cjs +26 -1
- package/dist/selectors/balance.cjs.map +1 -1
- package/dist/selectors/balance.d.cts +2 -1
- package/dist/selectors/balance.d.cts.map +1 -1
- package/dist/selectors/balance.d.mts +2 -1
- package/dist/selectors/balance.d.mts.map +1 -1
- package/dist/selectors/balance.mjs +26 -1
- package/dist/selectors/balance.mjs.map +1 -1
- package/dist/utils/constants.cjs +5 -0
- package/dist/utils/constants.cjs.map +1 -0
- package/dist/utils/constants.d.cts +2 -0
- package/dist/utils/constants.d.cts.map +1 -0
- package/dist/utils/constants.d.mts +2 -0
- package/dist/utils/constants.d.mts.map +1 -0
- package/dist/utils/constants.mjs +2 -0
- package/dist/utils/constants.mjs.map +1 -0
- package/package.json +14 -14
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,42 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [3.2.0]
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Add Sentry traces for Assets Health dashboard ([#8310](https://github.com/MetaMask/core/pull/8310))
|
|
15
|
+
- `AssetsDataSourceTiming` — per-source latency for each middleware in the fetch pipeline
|
|
16
|
+
- `AssetsDataSourceError` — tracks middleware failures with source names and error counts
|
|
17
|
+
- `AssetsFullFetch` — end-to-end fetch timing with asset/price/chain/account counts
|
|
18
|
+
- `AssetsUpdatePipeline` — enrichment pipeline timing for pushed data source updates
|
|
19
|
+
- `AssetsSubscriptionError` — subscription failure tracking per data source
|
|
20
|
+
- `AssetsStateSize` — entry counts for balances, metadata, prices, custom assets, unique assets, and network count (once on app start)
|
|
21
|
+
- `AggregatedBalanceSelector` — balance selector computation time with asset/network/account counts
|
|
22
|
+
- Add optional `trace` parameter to `getAggregatedBalanceForAccount` selector
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- Bump `@metamask/account-tree-controller` from `^5.0.1` to `^6.0.0` ([#8317](https://github.com/MetaMask/core/pull/8317))
|
|
27
|
+
- Bump `@metamask/assets-controllers` from `^101.0.1` to `^102.0.0` ([#8317](https://github.com/MetaMask/core/pull/8317))
|
|
28
|
+
- Bump `@metamask/base-controller` from `^9.0.0` to `^9.0.1` ([#8317](https://github.com/MetaMask/core/pull/8317))
|
|
29
|
+
- Bump `@metamask/client-controller` from `^1.0.0` to `^1.0.1` ([#8317](https://github.com/MetaMask/core/pull/8317))
|
|
30
|
+
- Bump `@metamask/core-backend` from `^6.2.0` to `^6.2.1` ([#8317](https://github.com/MetaMask/core/pull/8317))
|
|
31
|
+
- Bump `@metamask/keyring-controller` from `^25.1.0` to `^25.1.1` ([#8317](https://github.com/MetaMask/core/pull/8317))
|
|
32
|
+
- Bump `@metamask/messenger` from `^0.3.0` to `^1.0.0` ([#8317](https://github.com/MetaMask/core/pull/8317))
|
|
33
|
+
- Bump `@metamask/network-controller` from `^30.0.0` to `^30.0.1` ([#8317](https://github.com/MetaMask/core/pull/8317))
|
|
34
|
+
- Bump `@metamask/network-enablement-controller` from `^5.0.0` to `^5.0.1` ([#8317](https://github.com/MetaMask/core/pull/8317))
|
|
35
|
+
- Bump `@metamask/permission-controller` from `^12.2.1` to `^12.3.0` ([#8317](https://github.com/MetaMask/core/pull/8317))
|
|
36
|
+
- Bump `@metamask/polling-controller` from `^16.0.3` to `^16.0.4` ([#8317](https://github.com/MetaMask/core/pull/8317))
|
|
37
|
+
- Bump `@metamask/preferences-controller` from `^23.0.0` to `^23.1.0` ([#8317](https://github.com/MetaMask/core/pull/8317))
|
|
38
|
+
- Bump `@metamask/transaction-controller` from `^63.1.0` to `^63.3.1` ([#8301](https://github.com/MetaMask/core/pull/8301), [#8313](https://github.com/MetaMask/core/pull/8313), [#8317](https://github.com/MetaMask/core/pull/8317))
|
|
39
|
+
|
|
40
|
+
## [3.1.1]
|
|
41
|
+
|
|
42
|
+
### Fixed
|
|
43
|
+
|
|
44
|
+
- Refactored `BalanceFetcher` and `RpcDataSource` to ensure the correct `assetId` is used for EVM native assets that are not ETH ([#8284](https://github.com/MetaMask/core/pull/8284))
|
|
45
|
+
|
|
10
46
|
## [3.1.0]
|
|
11
47
|
|
|
12
48
|
### Changed
|
|
@@ -202,7 +238,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
202
238
|
- Refactor `RpcDataSource` to delegate polling to `BalanceFetcher` and `TokenDetector` services ([#7709](https://github.com/MetaMask/core/pull/7709))
|
|
203
239
|
- Refactor `BalanceFetcher` and `TokenDetector` to extend `StaticIntervalPollingControllerOnly` for independent polling management ([#7709](https://github.com/MetaMask/core/pull/7709))
|
|
204
240
|
|
|
205
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@3.
|
|
241
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@3.2.0...HEAD
|
|
242
|
+
[3.2.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@3.1.1...@metamask/assets-controller@3.2.0
|
|
243
|
+
[3.1.1]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@3.1.0...@metamask/assets-controller@3.1.1
|
|
206
244
|
[3.1.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@3.0.0...@metamask/assets-controller@3.1.0
|
|
207
245
|
[3.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@2.4.0...@metamask/assets-controller@3.0.0
|
|
208
246
|
[2.4.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@2.3.0...@metamask/assets-controller@2.4.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetsController-method-action-types.cjs","sourceRoot":"","sources":["../src/AssetsController-method-action-types.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated
|
|
1
|
+
{"version":3,"file":"AssetsController-method-action-types.cjs","sourceRoot":"","sources":["../src/AssetsController-method-action-types.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { AssetsController } from './AssetsController';\n\nexport type AssetsControllerGetAssetsAction = {\n type: `AssetsController:getAssets`;\n handler: AssetsController['getAssets'];\n};\n\nexport type AssetsControllerGetAssetsBalanceAction = {\n type: `AssetsController:getAssetsBalance`;\n handler: AssetsController['getAssetsBalance'];\n};\n\nexport type AssetsControllerGetAssetMetadataAction = {\n type: `AssetsController:getAssetMetadata`;\n handler: AssetsController['getAssetMetadata'];\n};\n\nexport type AssetsControllerGetAssetsPriceAction = {\n type: `AssetsController:getAssetsPrice`;\n handler: AssetsController['getAssetsPrice'];\n};\n\n/**\n * Returns exchange rates in the format expected by the bridge controller\n * (conversionRates, currencyRates, marketData, currentCurrency) so that\n * when useAssetsControllerForRates is true the bridge can use a single\n * action instead of MultichainAssetsRatesController, TokenRatesController,\n * and CurrencyRateController.\n *\n * @returns Bridge-compatible exchange rate state derived from assetsPrice and selectedCurrency.\n */\nexport type AssetsControllerGetExchangeRatesForBridgeAction = {\n type: `AssetsController:getExchangeRatesForBridge`;\n handler: AssetsController['getExchangeRatesForBridge'];\n};\n\n/**\n * Returns state in the legacy format expected by transaction-pay-controller\n * (TokenBalancesController, AccountTrackerController, TokensController,\n * TokenRatesController, CurrencyRateController shapes) so that when\n * useAssetsController is true the transaction-pay-controller can use a\n * single action instead of five separate getState calls.\n *\n * @returns Legacy-compatible state for transaction-pay-controller.\n */\nexport type AssetsControllerGetStateForTransactionPayAction = {\n type: `AssetsController:getStateForTransactionPay`;\n handler: AssetsController['getStateForTransactionPay'];\n};\n\n/**\n * Add a custom asset for an account.\n * Custom assets are included in subscription and fetch operations.\n * Adding a custom asset also unhides it if it was previously hidden.\n *\n * When `pendingMetadata` is provided (e.g. from the extension's pending-tokens\n * flow), the token metadata is persisted immediately into `assetsInfo` so the\n * UI can render it without waiting for the next pipeline fetch.\n *\n * @param accountId - The account ID to add the custom asset for.\n * @param assetId - The CAIP-19 asset ID to add.\n * @param pendingMetadata - Optional token metadata from the UI (pendingTokens format).\n */\nexport type AssetsControllerAddCustomAssetAction = {\n type: `AssetsController:addCustomAsset`;\n handler: AssetsController['addCustomAsset'];\n};\n\n/**\n * Remove a custom asset from an account.\n *\n * @param accountId - The account ID to remove the custom asset from.\n * @param assetId - The CAIP-19 asset ID to remove.\n */\nexport type AssetsControllerRemoveCustomAssetAction = {\n type: `AssetsController:removeCustomAsset`;\n handler: AssetsController['removeCustomAsset'];\n};\n\n/**\n * Get all custom assets for an account.\n *\n * @param accountId - The account ID to get custom assets for.\n * @returns Array of CAIP-19 asset IDs for the account's custom assets.\n */\nexport type AssetsControllerGetCustomAssetsAction = {\n type: `AssetsController:getCustomAssets`;\n handler: AssetsController['getCustomAssets'];\n};\n\n/**\n * Hide an asset globally.\n * Hidden assets are excluded from the asset list returned by getAssets.\n * The hidden state is stored in assetPreferences.\n *\n * @param assetId - The CAIP-19 asset ID to hide.\n */\nexport type AssetsControllerHideAssetAction = {\n type: `AssetsController:hideAsset`;\n handler: AssetsController['hideAsset'];\n};\n\n/**\n * Unhide an asset globally.\n *\n * @param assetId - The CAIP-19 asset ID to unhide.\n */\nexport type AssetsControllerUnhideAssetAction = {\n type: `AssetsController:unhideAsset`;\n handler: AssetsController['unhideAsset'];\n};\n\n/**\n * Union of all AssetsController action types.\n */\nexport type AssetsControllerMethodActions =\n | AssetsControllerGetAssetsAction\n | AssetsControllerGetAssetsBalanceAction\n | AssetsControllerGetAssetMetadataAction\n | AssetsControllerGetAssetsPriceAction\n | AssetsControllerGetExchangeRatesForBridgeAction\n | AssetsControllerGetStateForTransactionPayAction\n | AssetsControllerAddCustomAssetAction\n | AssetsControllerRemoveCustomAssetAction\n | AssetsControllerGetCustomAssetsAction\n | AssetsControllerHideAssetAction\n | AssetsControllerUnhideAssetAction;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetsController-method-action-types.mjs","sourceRoot":"","sources":["../src/AssetsController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated
|
|
1
|
+
{"version":3,"file":"AssetsController-method-action-types.mjs","sourceRoot":"","sources":["../src/AssetsController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { AssetsController } from './AssetsController';\n\nexport type AssetsControllerGetAssetsAction = {\n type: `AssetsController:getAssets`;\n handler: AssetsController['getAssets'];\n};\n\nexport type AssetsControllerGetAssetsBalanceAction = {\n type: `AssetsController:getAssetsBalance`;\n handler: AssetsController['getAssetsBalance'];\n};\n\nexport type AssetsControllerGetAssetMetadataAction = {\n type: `AssetsController:getAssetMetadata`;\n handler: AssetsController['getAssetMetadata'];\n};\n\nexport type AssetsControllerGetAssetsPriceAction = {\n type: `AssetsController:getAssetsPrice`;\n handler: AssetsController['getAssetsPrice'];\n};\n\n/**\n * Returns exchange rates in the format expected by the bridge controller\n * (conversionRates, currencyRates, marketData, currentCurrency) so that\n * when useAssetsControllerForRates is true the bridge can use a single\n * action instead of MultichainAssetsRatesController, TokenRatesController,\n * and CurrencyRateController.\n *\n * @returns Bridge-compatible exchange rate state derived from assetsPrice and selectedCurrency.\n */\nexport type AssetsControllerGetExchangeRatesForBridgeAction = {\n type: `AssetsController:getExchangeRatesForBridge`;\n handler: AssetsController['getExchangeRatesForBridge'];\n};\n\n/**\n * Returns state in the legacy format expected by transaction-pay-controller\n * (TokenBalancesController, AccountTrackerController, TokensController,\n * TokenRatesController, CurrencyRateController shapes) so that when\n * useAssetsController is true the transaction-pay-controller can use a\n * single action instead of five separate getState calls.\n *\n * @returns Legacy-compatible state for transaction-pay-controller.\n */\nexport type AssetsControllerGetStateForTransactionPayAction = {\n type: `AssetsController:getStateForTransactionPay`;\n handler: AssetsController['getStateForTransactionPay'];\n};\n\n/**\n * Add a custom asset for an account.\n * Custom assets are included in subscription and fetch operations.\n * Adding a custom asset also unhides it if it was previously hidden.\n *\n * When `pendingMetadata` is provided (e.g. from the extension's pending-tokens\n * flow), the token metadata is persisted immediately into `assetsInfo` so the\n * UI can render it without waiting for the next pipeline fetch.\n *\n * @param accountId - The account ID to add the custom asset for.\n * @param assetId - The CAIP-19 asset ID to add.\n * @param pendingMetadata - Optional token metadata from the UI (pendingTokens format).\n */\nexport type AssetsControllerAddCustomAssetAction = {\n type: `AssetsController:addCustomAsset`;\n handler: AssetsController['addCustomAsset'];\n};\n\n/**\n * Remove a custom asset from an account.\n *\n * @param accountId - The account ID to remove the custom asset from.\n * @param assetId - The CAIP-19 asset ID to remove.\n */\nexport type AssetsControllerRemoveCustomAssetAction = {\n type: `AssetsController:removeCustomAsset`;\n handler: AssetsController['removeCustomAsset'];\n};\n\n/**\n * Get all custom assets for an account.\n *\n * @param accountId - The account ID to get custom assets for.\n * @returns Array of CAIP-19 asset IDs for the account's custom assets.\n */\nexport type AssetsControllerGetCustomAssetsAction = {\n type: `AssetsController:getCustomAssets`;\n handler: AssetsController['getCustomAssets'];\n};\n\n/**\n * Hide an asset globally.\n * Hidden assets are excluded from the asset list returned by getAssets.\n * The hidden state is stored in assetPreferences.\n *\n * @param assetId - The CAIP-19 asset ID to hide.\n */\nexport type AssetsControllerHideAssetAction = {\n type: `AssetsController:hideAsset`;\n handler: AssetsController['hideAsset'];\n};\n\n/**\n * Unhide an asset globally.\n *\n * @param assetId - The CAIP-19 asset ID to unhide.\n */\nexport type AssetsControllerUnhideAssetAction = {\n type: `AssetsController:unhideAsset`;\n handler: AssetsController['unhideAsset'];\n};\n\n/**\n * Union of all AssetsController action types.\n */\nexport type AssetsControllerMethodActions =\n | AssetsControllerGetAssetsAction\n | AssetsControllerGetAssetsBalanceAction\n | AssetsControllerGetAssetMetadataAction\n | AssetsControllerGetAssetsPriceAction\n | AssetsControllerGetExchangeRatesForBridgeAction\n | AssetsControllerGetStateForTransactionPayAction\n | AssetsControllerAddCustomAssetAction\n | AssetsControllerRemoveCustomAssetAction\n | AssetsControllerGetCustomAssetsAction\n | AssetsControllerHideAssetAction\n | AssetsControllerUnhideAssetAction;\n"]}
|
|
@@ -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_uiOpen, _AssetsController_keyringUnlocked, _AssetsController_controllerMutex, _AssetsController_activeSubscriptions, _AssetsController_enabledChains, _AssetsController_selectedAccounts_get, _AssetsController_backendWebsocketDataSource, _AssetsController_accountsApiDataSource, _AssetsController_snapDataSource, _AssetsController_rpcDataSource, _AssetsController_stakedBalanceDataSource, _AssetsController_allBalanceDataSources_get, _AssetsController_priceDataSource, _AssetsController_detectionMiddleware, _AssetsController_tokenDataSource, _AssetsController_unsubscribeBasicFunctionality, _AssetsController_onActiveChainsUpdated, _AssetsController_initializeState, _AssetsController_extractEnabledChains, _AssetsController_normalizeChainReference, _AssetsController_subscribeToEvents, _AssetsController_updateActive, _AssetsController_registerActionHandlers, _AssetsController_handleActiveChainsUpdate, _AssetsController_executeMiddlewares, _AssetsController_resolveNativeAssetIds, _AssetsController_getNativeAssetIdsForEnabledChains, _AssetsController_getNativeAssetIdsForAccount, _AssetsController_ensureNativeBalancesDefaultZero, _AssetsController_updateState, _AssetsController_getAssetsFromState, _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_firstInitFetchReported, _AssetsController_stateSizeReported, _AssetsController_emitTrace, _AssetsController_emitStateSizeTrace, _AssetsController_uiOpen, _AssetsController_keyringUnlocked, _AssetsController_controllerMutex, _AssetsController_activeSubscriptions, _AssetsController_enabledChains, _AssetsController_selectedAccounts_get, _AssetsController_backendWebsocketDataSource, _AssetsController_accountsApiDataSource, _AssetsController_snapDataSource, _AssetsController_rpcDataSource, _AssetsController_stakedBalanceDataSource, _AssetsController_allBalanceDataSources_get, _AssetsController_priceDataSource, _AssetsController_detectionMiddleware, _AssetsController_tokenDataSource, _AssetsController_unsubscribeBasicFunctionality, _AssetsController_onActiveChainsUpdated, _AssetsController_initializeState, _AssetsController_extractEnabledChains, _AssetsController_normalizeChainReference, _AssetsController_subscribeToEvents, _AssetsController_updateActive, _AssetsController_registerActionHandlers, _AssetsController_handleActiveChainsUpdate, _AssetsController_executeMiddlewares, _AssetsController_resolveNativeAssetIds, _AssetsController_getNativeAssetIdsForEnabledChains, _AssetsController_getNativeAssetIdsForAccount, _AssetsController_ensureNativeBalancesDefaultZero, _AssetsController_updateState, _AssetsController_getAssetsFromState, _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");
|
|
@@ -53,6 +53,16 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
53
53
|
];
|
|
54
54
|
/** Default polling interval hint for data sources (30 seconds) */
|
|
55
55
|
const DEFAULT_POLLING_INTERVAL_MS = 30000;
|
|
56
|
+
// ============================================================================
|
|
57
|
+
// TRACE NAMES — used in Sentry spans (search these strings in Discover)
|
|
58
|
+
// ============================================================================
|
|
59
|
+
const TRACE_FIRST_INIT_FETCH = 'AssetsControllerFirstInitFetch';
|
|
60
|
+
const TRACE_FULL_FETCH = 'AssetsFullFetch';
|
|
61
|
+
const TRACE_DATA_SOURCE_TIMING = 'AssetsDataSourceTiming';
|
|
62
|
+
const TRACE_DATA_SOURCE_ERROR = 'AssetsDataSourceError';
|
|
63
|
+
const TRACE_UPDATE_PIPELINE = 'AssetsUpdatePipeline';
|
|
64
|
+
const TRACE_SUBSCRIPTION_ERROR = 'AssetsSubscriptionError';
|
|
65
|
+
const TRACE_STATE_SIZE = 'AssetsStateSize';
|
|
56
66
|
const log = (0, logger_1.createModuleLogger)(logger_1.projectLogger, CONTROLLER_NAME);
|
|
57
67
|
/**
|
|
58
68
|
* Returns the default state for AssetsController.
|
|
@@ -220,6 +230,8 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
220
230
|
_AssetsController_trace.set(this, void 0);
|
|
221
231
|
/** Whether we have already reported first init fetch for this session (reset on #stop). */
|
|
222
232
|
_AssetsController_firstInitFetchReported.set(this, false);
|
|
233
|
+
/** Whether we have already reported state size for this session (reset on #stop). */
|
|
234
|
+
_AssetsController_stateSizeReported.set(this, false);
|
|
223
235
|
/** Whether the client (UI) is open. Combined with #keyringUnlocked for #updateActive. */
|
|
224
236
|
_AssetsController_uiOpen.set(this, false);
|
|
225
237
|
/** Whether the keyring is unlocked. Combined with #uiOpen for #updateActive. */
|
|
@@ -335,7 +347,7 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
335
347
|
customAssets.push(...accountCustomAssets);
|
|
336
348
|
}
|
|
337
349
|
if (options?.forceUpdate) {
|
|
338
|
-
const startTime =
|
|
350
|
+
const startTime = performance.now();
|
|
339
351
|
const request = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildDataRequest).call(this, accounts, chainIds, {
|
|
340
352
|
assetTypes,
|
|
341
353
|
dataTypes,
|
|
@@ -369,23 +381,28 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
369
381
|
options.chainIds.length < __classPrivateFieldGet(this, _AssetsController_enabledChains, "f").size;
|
|
370
382
|
const updateMode = options?.updateMode ?? (isPartialChainFetch ? 'merge' : 'full');
|
|
371
383
|
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, { ...response, updateMode });
|
|
372
|
-
|
|
384
|
+
const durationMs = performance.now() - startTime;
|
|
385
|
+
// Emit trace for every full fetch (Assets Health dashboard)
|
|
386
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_FULL_FETCH, {
|
|
387
|
+
duration_ms: durationMs,
|
|
388
|
+
chain_count: chainIds.length,
|
|
389
|
+
account_count: accounts.length,
|
|
390
|
+
basic_functionality: __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this),
|
|
391
|
+
asset_count: response.assetsBalance
|
|
392
|
+
? Object.values(response.assetsBalance).reduce((sum, acct) => sum + Object.keys(acct).length, 0)
|
|
393
|
+
: 0,
|
|
394
|
+
price_count: response.assetsPrice
|
|
395
|
+
? Object.keys(response.assetsPrice).length
|
|
396
|
+
: 0,
|
|
397
|
+
...durationByDataSource,
|
|
398
|
+
});
|
|
399
|
+
if (!__classPrivateFieldGet(this, _AssetsController_firstInitFetchReported, "f")) {
|
|
373
400
|
__classPrivateFieldSet(this, _AssetsController_firstInitFetchReported, true, "f");
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
duration_ms: durationMs,
|
|
380
|
-
chain_ids: JSON.stringify(chainIds),
|
|
381
|
-
...durationByDataSource,
|
|
382
|
-
},
|
|
383
|
-
tags: { controller: 'AssetsController' },
|
|
384
|
-
}, () => undefined);
|
|
385
|
-
}
|
|
386
|
-
catch {
|
|
387
|
-
// Telemetry failure must not break.
|
|
388
|
-
}
|
|
401
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_FIRST_INIT_FETCH, {
|
|
402
|
+
duration_ms: durationMs,
|
|
403
|
+
chain_ids: JSON.stringify(chainIds),
|
|
404
|
+
...durationByDataSource,
|
|
405
|
+
});
|
|
389
406
|
}
|
|
390
407
|
}
|
|
391
408
|
const result = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getAssetsFromState).call(this, accounts, chainIds, assetTypes);
|
|
@@ -711,6 +728,7 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
711
728
|
* @param request - Optional original request for context when enriching
|
|
712
729
|
*/
|
|
713
730
|
async handleAssetsUpdate(response, sourceId, request) {
|
|
731
|
+
const updateStart = performance.now();
|
|
714
732
|
log('Assets updated from data source', {
|
|
715
733
|
sourceId,
|
|
716
734
|
hasBalance: Boolean(response.assetsBalance),
|
|
@@ -730,6 +748,16 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
730
748
|
dataTypes: ['balance', 'metadata', 'price'],
|
|
731
749
|
}, response);
|
|
732
750
|
await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, enrichedResponse);
|
|
751
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_UPDATE_PIPELINE, {
|
|
752
|
+
source: sourceId,
|
|
753
|
+
duration_ms: performance.now() - updateStart,
|
|
754
|
+
has_balance: Boolean(response.assetsBalance),
|
|
755
|
+
has_price: Boolean(response.assetsPrice),
|
|
756
|
+
has_metadata: Boolean(enrichedResponse.assetsInfo),
|
|
757
|
+
balance_account_count: response.assetsBalance
|
|
758
|
+
? Object.keys(response.assetsBalance).length
|
|
759
|
+
: 0,
|
|
760
|
+
});
|
|
733
761
|
}
|
|
734
762
|
// ============================================================================
|
|
735
763
|
// CLEANUP
|
|
@@ -766,7 +794,53 @@ class AssetsController extends base_controller_1.BaseController {
|
|
|
766
794
|
}
|
|
767
795
|
}
|
|
768
796
|
exports.AssetsController = AssetsController;
|
|
769
|
-
_AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctionality = new WeakMap(), _AssetsController_defaultUpdateInterval = new WeakMap(), _AssetsController_trace = new WeakMap(), _AssetsController_firstInitFetchReported = new WeakMap(), _AssetsController_uiOpen = new WeakMap(), _AssetsController_keyringUnlocked = new WeakMap(), _AssetsController_controllerMutex = new WeakMap(), _AssetsController_activeSubscriptions = new WeakMap(), _AssetsController_enabledChains = 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_onActiveChainsUpdated = new WeakMap(), _AssetsController_instances = new WeakSet(),
|
|
797
|
+
_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_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_onActiveChainsUpdated = new WeakMap(), _AssetsController_instances = new WeakSet(), _AssetsController_emitTrace = function _AssetsController_emitTrace(name, data, tags = {
|
|
798
|
+
controller: 'AssetsController',
|
|
799
|
+
}) {
|
|
800
|
+
if (!__classPrivateFieldGet(this, _AssetsController_trace, "f")) {
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
__classPrivateFieldGet(this, _AssetsController_trace, "f").call(this, { name, data, tags }, () => undefined).catch(() => {
|
|
804
|
+
// Telemetry failure must not break.
|
|
805
|
+
});
|
|
806
|
+
}, _AssetsController_emitStateSizeTrace = function _AssetsController_emitStateSizeTrace() {
|
|
807
|
+
if (!__classPrivateFieldGet(this, _AssetsController_trace, "f") || __classPrivateFieldGet(this, _AssetsController_stateSizeReported, "f")) {
|
|
808
|
+
return;
|
|
809
|
+
}
|
|
810
|
+
__classPrivateFieldSet(this, _AssetsController_stateSizeReported, true, "f");
|
|
811
|
+
const { assetsBalance: balances, customAssets, assetsInfo, assetsPrice, } = this.state;
|
|
812
|
+
// Count balance entries and collect unique asset IDs / chain IDs in one pass.
|
|
813
|
+
let balanceEntries = 0;
|
|
814
|
+
const uniqueAssets = new Set();
|
|
815
|
+
const uniqueNetworks = new Set();
|
|
816
|
+
for (const acct of Object.values(balances)) {
|
|
817
|
+
const assetIds = Object.keys(acct);
|
|
818
|
+
balanceEntries += assetIds.length;
|
|
819
|
+
for (const assetId of assetIds) {
|
|
820
|
+
uniqueAssets.add(assetId);
|
|
821
|
+
// CAIP-19 format: "eip155:1/slip44:60" — chainId is everything before "/"
|
|
822
|
+
const slash = assetId.indexOf('/');
|
|
823
|
+
if (slash > 0) {
|
|
824
|
+
uniqueNetworks.add(assetId.slice(0, slash));
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
let customAssetEntries = 0;
|
|
829
|
+
for (const ids of Object.values(customAssets)) {
|
|
830
|
+
if (Array.isArray(ids)) {
|
|
831
|
+
customAssetEntries += ids.length;
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_STATE_SIZE, {
|
|
835
|
+
balance_entries: balanceEntries,
|
|
836
|
+
balance_accounts: Object.keys(balances).length,
|
|
837
|
+
unique_asset_count: uniqueAssets.size,
|
|
838
|
+
network_count: uniqueNetworks.size,
|
|
839
|
+
metadata_entries: Object.keys(assetsInfo).length,
|
|
840
|
+
price_entries: Object.keys(assetsPrice).length,
|
|
841
|
+
custom_asset_entries: customAssetEntries,
|
|
842
|
+
});
|
|
843
|
+
}, _AssetsController_selectedAccounts_get = function _AssetsController_selectedAccounts_get() {
|
|
770
844
|
return this.messenger.call('AccountTreeController:getAccountsFromSelectedAccountGroup');
|
|
771
845
|
}, _AssetsController_allBalanceDataSources_get = function _AssetsController_allBalanceDataSources_get() {
|
|
772
846
|
return [
|
|
@@ -888,19 +962,22 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
888
962
|
const middlewares = sources.map((source) => source.assetsMiddleware);
|
|
889
963
|
const inclusive = [];
|
|
890
964
|
const wrapped = middlewares.map((middleware, i) => (async (ctx, next) => {
|
|
891
|
-
const start =
|
|
965
|
+
const start = performance.now();
|
|
892
966
|
try {
|
|
893
967
|
return await middleware(ctx, next);
|
|
894
968
|
}
|
|
895
969
|
finally {
|
|
896
|
-
inclusive[i] =
|
|
970
|
+
inclusive[i] = performance.now() - start;
|
|
897
971
|
}
|
|
898
972
|
}));
|
|
899
|
-
const
|
|
973
|
+
const middlewareErrors = [];
|
|
974
|
+
const chain = wrapped.reduceRight((next, middleware, index) => async (ctx) => {
|
|
900
975
|
try {
|
|
901
976
|
return await middleware(ctx, next);
|
|
902
977
|
}
|
|
903
978
|
catch (error) {
|
|
979
|
+
const sourceName = names[index] ?? `middleware_${index}`;
|
|
980
|
+
middlewareErrors.push(sourceName);
|
|
904
981
|
console.error('[AssetsController] Middleware failed:', error);
|
|
905
982
|
return next(ctx);
|
|
906
983
|
}
|
|
@@ -924,6 +1001,23 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
924
1001
|
durationByDataSource[key] = ms;
|
|
925
1002
|
}
|
|
926
1003
|
}
|
|
1004
|
+
// Emit per-source timing traces for the Assets Health dashboard
|
|
1005
|
+
for (const [sourceName, durationMs] of Object.entries(durationByDataSource)) {
|
|
1006
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_DATA_SOURCE_TIMING, {
|
|
1007
|
+
source: sourceName,
|
|
1008
|
+
duration_ms: durationMs,
|
|
1009
|
+
chain_count: request.chainIds.length,
|
|
1010
|
+
account_count: request.accountsWithSupportedChains.length,
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
1013
|
+
// Emit error traces for failed middlewares
|
|
1014
|
+
if (middlewareErrors.length > 0) {
|
|
1015
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_DATA_SOURCE_ERROR, {
|
|
1016
|
+
failed_sources: middlewareErrors.join(','),
|
|
1017
|
+
error_count: middlewareErrors.length,
|
|
1018
|
+
chain_count: request.chainIds.length,
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
927
1021
|
return { response: result.response, durationByDataSource };
|
|
928
1022
|
}, _AssetsController_resolveNativeAssetIds = function _AssetsController_resolveNativeAssetIds(chains) {
|
|
929
1023
|
const { nativeAssetIdentifiers } = this.messenger.call('NetworkEnablementController:getState');
|
|
@@ -1064,6 +1158,8 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1064
1158
|
}
|
|
1065
1159
|
}
|
|
1066
1160
|
});
|
|
1161
|
+
// Emit state size trace (throttled to avoid JSON.stringify on every update)
|
|
1162
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitStateSizeTrace).call(this);
|
|
1067
1163
|
// Calculate changed prices
|
|
1068
1164
|
const changedPriceAssets = normalizedResponse.assetsPrice
|
|
1069
1165
|
? Object.keys(normalizedResponse.assetsPrice).filter((assetId) => !(0, lodash_1.isEqual)(previousPrices[assetId], normalizedResponse.assetsPrice?.[assetId]))
|
|
@@ -1211,6 +1307,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1211
1307
|
hasPriceSubscription: __classPrivateFieldGet(this, _AssetsController_activeSubscriptions, "f").has('ds:PriceDataSource'),
|
|
1212
1308
|
});
|
|
1213
1309
|
__classPrivateFieldSet(this, _AssetsController_firstInitFetchReported, false, "f");
|
|
1310
|
+
__classPrivateFieldSet(this, _AssetsController_stateSizeReported, false, "f");
|
|
1214
1311
|
// Stop price subscription first (uses direct messenger call)
|
|
1215
1312
|
this.unsubscribeAssetsPrice();
|
|
1216
1313
|
// Stop balance subscriptions by properly notifying data sources via messenger
|
|
@@ -1327,6 +1424,10 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
|
|
|
1327
1424
|
};
|
|
1328
1425
|
source.subscribe(subscribeReq).catch((error) => {
|
|
1329
1426
|
console.error(`[AssetsController] Failed to subscribe to '${sourceId}':`, error);
|
|
1427
|
+
__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_emitTrace).call(this, TRACE_SUBSCRIPTION_ERROR, {
|
|
1428
|
+
source: sourceId,
|
|
1429
|
+
error_message: String(error),
|
|
1430
|
+
});
|
|
1330
1431
|
});
|
|
1331
1432
|
// Track subscription
|
|
1332
1433
|
const subscription = {
|