@metamask-previews/assets-controller 2.0.2-preview-17adacd → 2.1.0-preview-6174615b0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/CHANGELOG.md +5 -1
  2. package/dist/AssetsController.cjs +48 -55
  3. package/dist/AssetsController.cjs.map +1 -1
  4. package/dist/AssetsController.d.cts +4 -11
  5. package/dist/AssetsController.d.cts.map +1 -1
  6. package/dist/AssetsController.d.mts +4 -11
  7. package/dist/AssetsController.d.mts.map +1 -1
  8. package/dist/AssetsController.mjs +48 -55
  9. package/dist/AssetsController.mjs.map +1 -1
  10. package/dist/data-sources/AbstractDataSource.cjs.map +1 -1
  11. package/dist/data-sources/AbstractDataSource.d.cts +3 -3
  12. package/dist/data-sources/AbstractDataSource.d.cts.map +1 -1
  13. package/dist/data-sources/AbstractDataSource.d.mts +3 -3
  14. package/dist/data-sources/AbstractDataSource.d.mts.map +1 -1
  15. package/dist/data-sources/AbstractDataSource.mjs.map +1 -1
  16. package/dist/data-sources/BackendWebsocketDataSource.cjs +2 -2
  17. package/dist/data-sources/BackendWebsocketDataSource.cjs.map +1 -1
  18. package/dist/data-sources/BackendWebsocketDataSource.d.cts +2 -2
  19. package/dist/data-sources/BackendWebsocketDataSource.d.mts +2 -2
  20. package/dist/data-sources/BackendWebsocketDataSource.mjs +2 -2
  21. package/dist/data-sources/BackendWebsocketDataSource.mjs.map +1 -1
  22. package/dist/data-sources/RpcDataSource.cjs +23 -6
  23. package/dist/data-sources/RpcDataSource.cjs.map +1 -1
  24. package/dist/data-sources/RpcDataSource.d.cts.map +1 -1
  25. package/dist/data-sources/RpcDataSource.d.mts.map +1 -1
  26. package/dist/data-sources/RpcDataSource.mjs +23 -6
  27. package/dist/data-sources/RpcDataSource.mjs.map +1 -1
  28. package/dist/data-sources/StakedBalanceDataSource.cjs +41 -3
  29. package/dist/data-sources/StakedBalanceDataSource.cjs.map +1 -1
  30. package/dist/data-sources/StakedBalanceDataSource.d.cts.map +1 -1
  31. package/dist/data-sources/StakedBalanceDataSource.d.mts.map +1 -1
  32. package/dist/data-sources/StakedBalanceDataSource.mjs +41 -3
  33. package/dist/data-sources/StakedBalanceDataSource.mjs.map +1 -1
  34. package/dist/data-sources/evm-rpc-services/services/TokenDetector.cjs.map +1 -1
  35. package/dist/data-sources/evm-rpc-services/services/TokenDetector.d.cts.map +1 -1
  36. package/dist/data-sources/evm-rpc-services/services/TokenDetector.d.mts.map +1 -1
  37. package/dist/data-sources/evm-rpc-services/services/TokenDetector.mjs.map +1 -1
  38. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.1.0]
11
+
10
12
  ### Added
11
13
 
12
14
  - Add `PendingTokenMetadata` type and optional `pendingMetadata` parameter to `addCustomAsset(accountId, assetId, pendingMetadata?)`. When provided (e.g. from the extension's pending-tokens flow), token metadata is written to `assetsInfo` immediately so the UI can render the token without waiting for the pipeline ([#8021](https://github.com/MetaMask/core/pull/8021))
@@ -24,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
24
26
 
25
27
  ### Fixed
26
28
 
29
+ - Avoid unnecessary price and token API requests when data sources report balance-only updates. The controller now forwards the optional `request` from the subscribe callback into `handleAssetsUpdate`; when a data source calls `onAssetsUpdate(response, request)` with `request.dataTypes: ['balance']` (e.g. RpcDataSource balance polling, StakedBalanceDataSource), the controller skips Token and Price enrichment so the price API is not called. Previously every update triggered enrichment and could reset or overwrite existing state ([#8043](https://github.com/MetaMask/core/pull/8043))
27
30
  - Default `assetsBalance` to `0` for native tokens of each account's supported chains using `NetworkEnablementController.nativeAssetIdentifiers`, so native entries are always present in state even before data sources respond ([#8036](https://github.com/MetaMask/core/pull/8036))
28
31
  - Auto-select `'merge'` update mode in `getAssets` when `chainIds` is a subset of enabled chains, preventing partial-chain fetches (e.g. after a swap, adding a custom asset, or data-source chain changes) from wiping balances of other chains ([#8036](https://github.com/MetaMask/core/pull/8036))
29
32
  - Convert WebSocket balance updates in `BackendWebsocketDataSource` from raw smallest-units to human-readable amounts using asset decimals (same behavior as RPC/Accounts API), so `assetsBalance` remains consistent across data sources ([#8032](https://github.com/MetaMask/core/pull/8032))
@@ -125,7 +128,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
125
128
  - Refactor `RpcDataSource` to delegate polling to `BalanceFetcher` and `TokenDetector` services ([#7709](https://github.com/MetaMask/core/pull/7709))
126
129
  - Refactor `BalanceFetcher` and `TokenDetector` to extend `StaticIntervalPollingControllerOnly` for independent polling management ([#7709](https://github.com/MetaMask/core/pull/7709))
127
130
 
128
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@2.0.2...HEAD
131
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@2.1.0...HEAD
132
+ [2.1.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@2.0.2...@metamask/assets-controller@2.1.0
129
133
  [2.0.2]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@2.0.1...@metamask/assets-controller@2.0.2
130
134
  [2.0.1]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@2.0.0...@metamask/assets-controller@2.0.1
131
135
  [2.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@1.0.0...@metamask/assets-controller@2.0.0
@@ -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_trackMetaMetricsEvent, _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_initializeState, _AssetsController_extractEnabledChains, _AssetsController_normalizeChainReference, _AssetsController_subscribeToEvents, _AssetsController_updateActive, _AssetsController_registerActionHandlers, _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_trackMetaMetricsEvent, _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;
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");
@@ -241,36 +241,37 @@ class AssetsController extends base_controller_1.BaseController {
241
241
  _AssetsController_detectionMiddleware.set(this, void 0);
242
242
  _AssetsController_tokenDataSource.set(this, void 0);
243
243
  _AssetsController_unsubscribeBasicFunctionality.set(this, null);
244
+ _AssetsController_onActiveChainsUpdated.set(this, void 0);
244
245
  __classPrivateFieldSet(this, _AssetsController_isEnabled, isEnabled(), "f");
245
246
  __classPrivateFieldSet(this, _AssetsController_isBasicFunctionality, isBasicFunctionality ?? (() => true), "f");
246
247
  __classPrivateFieldSet(this, _AssetsController_defaultUpdateInterval, defaultUpdateInterval, "f");
247
248
  __classPrivateFieldSet(this, _AssetsController_trackMetaMetricsEvent, trackMetaMetricsEvent, "f");
248
249
  const rpcConfig = rpcDataSourceConfig ?? {};
249
- const onActiveChainsUpdated = (dataSourceName, chains, previousChains) => {
250
- this.handleActiveChainsUpdate(dataSourceName, chains, previousChains);
251
- };
250
+ __classPrivateFieldSet(this, _AssetsController_onActiveChainsUpdated, (dataSourceName, chains, previousChains) => {
251
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleActiveChainsUpdate).call(this, dataSourceName, chains, previousChains);
252
+ }, "f");
252
253
  __classPrivateFieldSet(this, _AssetsController_backendWebsocketDataSource, new BackendWebsocketDataSource_1.BackendWebsocketDataSource({
253
254
  messenger: this.messenger,
254
255
  queryApiClient,
255
- onActiveChainsUpdated,
256
+ onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
256
257
  }), "f");
257
258
  __classPrivateFieldSet(this, _AssetsController_accountsApiDataSource, new AccountsApiDataSource_1.AccountsApiDataSource({
258
259
  queryApiClient,
259
- onActiveChainsUpdated,
260
+ onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
260
261
  ...accountsApiDataSourceConfig,
261
262
  }), "f");
262
263
  __classPrivateFieldSet(this, _AssetsController_snapDataSource, new SnapDataSource_1.SnapDataSource({
263
264
  messenger: this.messenger,
264
- onActiveChainsUpdated,
265
+ onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
265
266
  }), "f");
266
267
  __classPrivateFieldSet(this, _AssetsController_rpcDataSource, new RpcDataSource_1.RpcDataSource({
267
268
  messenger: this.messenger,
268
- onActiveChainsUpdated,
269
+ onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
269
270
  ...rpcConfig,
270
271
  }), "f");
271
272
  __classPrivateFieldSet(this, _AssetsController_stakedBalanceDataSource, new StakedBalanceDataSource_1.StakedBalanceDataSource({
272
273
  messenger: this.messenger,
273
- onActiveChainsUpdated,
274
+ onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
274
275
  ...stakedBalanceDataSourceConfig,
275
276
  }), "f");
276
277
  __classPrivateFieldSet(this, _AssetsController_tokenDataSource, new TokenDataSource_1.TokenDataSource({
@@ -302,53 +303,14 @@ class AssetsController extends base_controller_1.BaseController {
302
303
  }
303
304
  }
304
305
  }
305
- // ============================================================================
306
- // DATA SOURCE CHAIN MANAGEMENT
307
- // ============================================================================
308
306
  /**
309
- * Handle when a data source's supported chains change.
310
- * Used to refresh balance subscriptions and run a one-time fetch when a new chain is supported.
307
+ * Returns the callback passed to data sources for reporting active chain updates.
308
+ * Used by tests to simulate a data source reporting chain changes.
311
309
  *
312
- * - On any add/remove: re-subscribes to data sources so chain assignment stays correct.
313
- * - When chains are added: fetches balances for the new chains (for selected accounts on enabled networks).
314
- *
315
- * Controller does not store chains; sources report via this callback. previousChains is required for diff.
316
- *
317
- * @param dataSourceId - The identifier of the data source reporting the change.
318
- * @param activeChains - Currently active (supported and available) chain IDs for this source.
319
- * @param previousChains - Previous chains; used to compute added/removed.
310
+ * @returns The onActiveChainsUpdated callback.
320
311
  */
321
- handleActiveChainsUpdate(dataSourceId, activeChains, previousChains) {
322
- if (!__classPrivateFieldGet(this, _AssetsController_isEnabled, "f")) {
323
- return;
324
- }
325
- log('Data source active chains changed', {
326
- dataSourceId,
327
- chainCount: activeChains.length,
328
- chains: activeChains,
329
- });
330
- const previous = previousChains;
331
- const previousSet = new Set(previous);
332
- const addedChains = activeChains.filter((ch) => !previousSet.has(ch));
333
- const removedChains = previous.filter((ch) => !activeChains.includes(ch));
334
- if (addedChains.length > 0 || removedChains.length > 0) {
335
- // Refresh subscriptions to use updated data source availability
336
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
337
- }
338
- // If chains were added and we have selected accounts, do one-time fetch
339
- if (addedChains.length > 0 && __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length > 0) {
340
- const addedEnabledChains = addedChains.filter((chain) => __classPrivateFieldGet(this, _AssetsController_enabledChains, "f").has(chain));
341
- if (addedEnabledChains.length > 0) {
342
- log('Fetching balances for newly added chains', { addedEnabledChains });
343
- this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
344
- chainIds: addedEnabledChains,
345
- forceUpdate: true,
346
- updateMode: 'merge',
347
- }).catch((error) => {
348
- log('Failed to fetch balance for added chains', { error });
349
- });
350
- }
351
- }
312
+ getOnActiveChainsUpdated() {
313
+ return __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f");
352
314
  }
353
315
  // ============================================================================
354
316
  // PUBLIC API: QUERY METHODS
@@ -745,7 +707,7 @@ class AssetsController extends base_controller_1.BaseController {
745
707
  }
746
708
  }
747
709
  exports.AssetsController = AssetsController;
748
- _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctionality = new WeakMap(), _AssetsController_defaultUpdateInterval = new WeakMap(), _AssetsController_trackMetaMetricsEvent = 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_instances = new WeakSet(), _AssetsController_selectedAccounts_get = function _AssetsController_selectedAccounts_get() {
710
+ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctionality = new WeakMap(), _AssetsController_defaultUpdateInterval = new WeakMap(), _AssetsController_trackMetaMetricsEvent = 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(), _AssetsController_selectedAccounts_get = function _AssetsController_selectedAccounts_get() {
749
711
  return this.messenger.call('AccountTreeController:getAccountsFromSelectedAccountGroup');
750
712
  }, _AssetsController_allBalanceDataSources_get = function _AssetsController_allBalanceDataSources_get() {
751
713
  return [
@@ -818,6 +780,37 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
818
780
  }
819
781
  }, _AssetsController_registerActionHandlers = function _AssetsController_registerActionHandlers() {
820
782
  this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
783
+ }, _AssetsController_handleActiveChainsUpdate = function _AssetsController_handleActiveChainsUpdate(dataSourceId, activeChains, previousChains) {
784
+ if (!__classPrivateFieldGet(this, _AssetsController_isEnabled, "f")) {
785
+ return;
786
+ }
787
+ log('Data source active chains changed', {
788
+ dataSourceId,
789
+ chainCount: activeChains.length,
790
+ chains: activeChains,
791
+ });
792
+ const previous = previousChains;
793
+ const previousSet = new Set(previous);
794
+ const addedChains = activeChains.filter((ch) => !previousSet.has(ch));
795
+ const removedChains = previous.filter((ch) => !activeChains.includes(ch));
796
+ if (addedChains.length > 0 || removedChains.length > 0) {
797
+ // Refresh subscriptions to use updated data source availability
798
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
799
+ }
800
+ // If chains were added and we have selected accounts, do one-time fetch
801
+ if (addedChains.length > 0 && __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length > 0) {
802
+ const addedEnabledChains = addedChains.filter((chain) => __classPrivateFieldGet(this, _AssetsController_enabledChains, "f").has(chain));
803
+ if (addedEnabledChains.length > 0) {
804
+ log('Fetching balances for newly added chains', { addedEnabledChains });
805
+ this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
806
+ chainIds: addedEnabledChains,
807
+ forceUpdate: true,
808
+ updateMode: 'merge',
809
+ }).catch((error) => {
810
+ log('Failed to fetch balance for added chains', { error });
811
+ });
812
+ }
813
+ }
821
814
  }, _AssetsController_executeMiddlewares =
822
815
  // ============================================================================
823
816
  // MIDDLEWARE EXECUTION
@@ -1246,7 +1239,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1246
1239
  }),
1247
1240
  subscriptionId: subscriptionKey,
1248
1241
  isUpdate,
1249
- onAssetsUpdate: (response) => this.handleAssetsUpdate(response, sourceId),
1242
+ onAssetsUpdate: (response, request) => this.handleAssetsUpdate(response, sourceId, request),
1250
1243
  getAssetsState: () => this.state,
1251
1244
  };
1252
1245
  source.subscribe(subscribeReq).catch((error) => {