@metamask-previews/assets-controller 8.3.2-preview-2b6e433 → 8.3.2-preview-cf351fcd3

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 (48) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/AssetsController.cjs +51 -26
  3. package/dist/AssetsController.cjs.map +1 -1
  4. package/dist/AssetsController.d.cts.map +1 -1
  5. package/dist/AssetsController.d.mts.map +1 -1
  6. package/dist/AssetsController.mjs +51 -26
  7. package/dist/AssetsController.mjs.map +1 -1
  8. package/dist/data-sources/AccountsApiDataSource.cjs +6 -2
  9. package/dist/data-sources/AccountsApiDataSource.cjs.map +1 -1
  10. package/dist/data-sources/AccountsApiDataSource.d.cts.map +1 -1
  11. package/dist/data-sources/AccountsApiDataSource.d.mts.map +1 -1
  12. package/dist/data-sources/AccountsApiDataSource.mjs +6 -2
  13. package/dist/data-sources/AccountsApiDataSource.mjs.map +1 -1
  14. package/dist/data-sources/BackendWebsocketDataSource.cjs +1 -1
  15. package/dist/data-sources/BackendWebsocketDataSource.cjs.map +1 -1
  16. package/dist/data-sources/BackendWebsocketDataSource.mjs +1 -1
  17. package/dist/data-sources/BackendWebsocketDataSource.mjs.map +1 -1
  18. package/dist/data-sources/PriceDataSource.cjs +1 -1
  19. package/dist/data-sources/PriceDataSource.cjs.map +1 -1
  20. package/dist/data-sources/PriceDataSource.mjs +1 -1
  21. package/dist/data-sources/PriceDataSource.mjs.map +1 -1
  22. package/dist/data-sources/RpcDataSource.cjs +2 -2
  23. package/dist/data-sources/RpcDataSource.cjs.map +1 -1
  24. package/dist/data-sources/RpcDataSource.mjs +2 -2
  25. package/dist/data-sources/RpcDataSource.mjs.map +1 -1
  26. package/dist/data-sources/SnapDataSource.cjs +10 -3
  27. package/dist/data-sources/SnapDataSource.cjs.map +1 -1
  28. package/dist/data-sources/SnapDataSource.d.cts.map +1 -1
  29. package/dist/data-sources/SnapDataSource.d.mts.map +1 -1
  30. package/dist/data-sources/SnapDataSource.mjs +10 -3
  31. package/dist/data-sources/SnapDataSource.mjs.map +1 -1
  32. package/dist/data-sources/StakedBalanceDataSource.cjs +2 -2
  33. package/dist/data-sources/StakedBalanceDataSource.cjs.map +1 -1
  34. package/dist/data-sources/StakedBalanceDataSource.mjs +2 -2
  35. package/dist/data-sources/StakedBalanceDataSource.mjs.map +1 -1
  36. package/dist/middlewares/ParallelMiddleware.cjs +11 -3
  37. package/dist/middlewares/ParallelMiddleware.cjs.map +1 -1
  38. package/dist/middlewares/ParallelMiddleware.d.cts.map +1 -1
  39. package/dist/middlewares/ParallelMiddleware.d.mts.map +1 -1
  40. package/dist/middlewares/ParallelMiddleware.mjs +11 -3
  41. package/dist/middlewares/ParallelMiddleware.mjs.map +1 -1
  42. package/dist/types.cjs.map +1 -1
  43. package/dist/types.d.cts +20 -8
  44. package/dist/types.d.cts.map +1 -1
  45. package/dist/types.d.mts +20 -8
  46. package/dist/types.d.mts.map +1 -1
  47. package/dist/types.mjs.map +1 -1
  48. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -9,9 +9,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ### Changed
11
11
 
12
+ - **BREAKING:** `DataResponse.updateMode` (`AssetsUpdateMode`) changed from `'merge' | 'full'` to `{ type: 'merge' } | { type: 'full'; fullReplaceChainIds: ChainId[] }`. `'full'` now replaces balances only for listed chains. Update all `updateMode` reads/writes to the object form ([#9062](https://github.com/MetaMask/core/pull/9062))
13
+ - `mergeDataResponses` preserves `'full'` updates by unioning `fullReplaceChainIds` during merges.
12
14
  - Bump `@metamask/network-enablement-controller` from `^5.2.0` to `^5.3.0` ([#9003](https://github.com/MetaMask/core/pull/9003))
13
15
  - Bump `@metamask/transaction-controller` from `^66.0.1` to `^67.0.0` ([#9021](https://github.com/MetaMask/core/pull/9021))
14
16
 
17
+ ### Fixed
18
+
19
+ - `AssetsController` no longer wipes balances on chains a `'full'` update doesn't cover, fixing tokens disappearing on unlock and network switch. Previously a `'full'` response (e.g. from `AccountsApiDataSource` subscription polls) replaced an account's entire balance map across all chains, clearing tokens on chains the source doesn't serve (custom/RPC-only chains) or that came back `unprocessed`. `'full'` replacement is now scoped to `fullReplaceChainIds`, and user custom assets are always preserved ([#9062](https://github.com/MetaMask/core/pull/9062))
20
+ - `AccountsApiDataSource` now sets `fullReplaceChainIds` to processed chains (excluding `unprocessedNetworks`) so `'full'` updates never clear balances on unfetched chains
21
+
15
22
  ## [8.3.2]
16
23
 
17
24
  ### Changed
@@ -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, _AssetsController_emitStateSizeTrace, _AssetsController_uiOpen, _AssetsController_keyringUnlocked, _AssetsController_controllerMutex, _AssetsController_activeSubscriptions, _AssetsController_enabledChains, _AssetsController_lastKnownAccountIds, _AssetsController_getSelectedAccounts, _AssetsController_backendWebsocketDataSource, _AssetsController_accountsApiDataSource, _AssetsController_snapDataSource, _AssetsController_rpcDataSource, _AssetsController_stakedBalanceDataSource, _AssetsController_allBalanceDataSources_get, _AssetsController_priceDataSource, _AssetsController_detectionMiddleware, _AssetsController_customAssetGraduationMiddleware, _AssetsController_rpcFallbackMiddleware, _AssetsController_tokenDataSource, _AssetsController_unsubscribeBasicFunctionality, _AssetsController_queryApiClient, _AssetsController_onActiveChainsUpdated, _AssetsController_initializeNativeAssetsMap, _AssetsController_initializeState, _AssetsController_extractEnabledChains, _AssetsController_normalizeChainReference, _AssetsController_subscribeToEvents, _AssetsController_onUnapprovedTransactionAdded, _AssetsController_updateActive, _AssetsController_handleAccountTreeStateChange, _AssetsController_registerActionHandlers, _AssetsController_handleActiveChainsUpdate, _AssetsController_executeMiddlewares, _AssetsController_getNativeAssetMap, _AssetsController_isNativeAsset, _AssetsController_resolveNativeAssetIds, _AssetsController_getNativeAssetIdsForEnabledChains, _AssetsController_getNativeAssetIdsForAccount, _AssetsController_ensureNativeBalancesDefaultZero, _AssetsController_ensureDefaultTrackedAssetsSeeded, _AssetsController_updateState, _AssetsController_getAssetsFromState, _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_refreshAssetsAfterNetworkChange;
16
+ var _AssetsController_instances, _AssetsController_isEnabled, _AssetsController_isBasicFunctionality, _AssetsController_defaultUpdateInterval, _AssetsController_trace, _AssetsController_captureException, _AssetsController_firstInitFetchReported, _AssetsController_stateSizeReported, _AssetsController_emitTrace, _AssetsController_emitStateSizeTrace, _AssetsController_uiOpen, _AssetsController_keyringUnlocked, _AssetsController_controllerMutex, _AssetsController_activeSubscriptions, _AssetsController_enabledChains, _AssetsController_lastKnownAccountIds, _AssetsController_getSelectedAccounts, _AssetsController_backendWebsocketDataSource, _AssetsController_accountsApiDataSource, _AssetsController_snapDataSource, _AssetsController_rpcDataSource, _AssetsController_stakedBalanceDataSource, _AssetsController_allBalanceDataSources_get, _AssetsController_priceDataSource, _AssetsController_detectionMiddleware, _AssetsController_customAssetGraduationMiddleware, _AssetsController_rpcFallbackMiddleware, _AssetsController_tokenDataSource, _AssetsController_unsubscribeBasicFunctionality, _AssetsController_queryApiClient, _AssetsController_onActiveChainsUpdated, _AssetsController_initializeNativeAssetsMap, _AssetsController_initializeState, _AssetsController_extractEnabledChains, _AssetsController_normalizeChainReference, _AssetsController_subscribeToEvents, _AssetsController_onUnapprovedTransactionAdded, _AssetsController_updateActive, _AssetsController_handleAccountTreeStateChange, _AssetsController_registerActionHandlers, _AssetsController_handleActiveChainsUpdate, _AssetsController_executeMiddlewares, _AssetsController_getNativeAssetMap, _AssetsController_isNativeAsset, _AssetsController_resolveNativeAssetIds, _AssetsController_getNativeAssetIdsForEnabledChains, _AssetsController_getNativeAssetIdsForAccount, _AssetsController_ensureNativeBalancesDefaultZero, _AssetsController_ensureDefaultTrackedAssetsSeeded, _AssetsController_buildFullBalances, _AssetsController_updateState, _AssetsController_getAssetsFromState, _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_refreshAssetsAfterNetworkChange;
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");
@@ -441,7 +441,7 @@ class AssetsController extends base_controller_1.BaseController {
441
441
  // The fast pipeline only contains a subset of data sources (AccountsApi +
442
442
  // StakedBalance), so it must always merge to avoid wiping Snap/RPC
443
443
  // balances that the background pipeline hasn't yet replaced.
444
- await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, { ...response, updateMode: 'merge' });
444
+ await __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, { ...response, updateMode: { type: 'merge' } });
445
445
  // Background pipeline: snap and RPC run in parallel after the fast path
446
446
  // commits to state. Their balances are merged together before detection.
447
447
  // Token + price enrichment matches the pre-split behavior: only when basic
@@ -461,7 +461,7 @@ class AssetsController extends base_controller_1.BaseController {
461
461
  ]
462
462
  : []),
463
463
  ], request)
464
- .then(({ response: slowResponse }) => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, { ...slowResponse, updateMode: 'merge' }))
464
+ .then(({ response: slowResponse }) => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateState).call(this, { ...slowResponse, updateMode: { type: 'merge' } }))
465
465
  .catch((error) => log('Background pipeline failed', { error }));
466
466
  const durationMs = performance.now() - startTime;
467
467
  // Emit trace for every full fetch (Assets Health dashboard)
@@ -647,7 +647,7 @@ class AssetsController extends base_controller_1.BaseController {
647
647
  dataTypes: ['balance', 'metadata', 'price'],
648
648
  assetTypes: ['fungible'],
649
649
  forceUpdate: true,
650
- updateMode: 'merge',
650
+ updateMode: { type: 'merge' },
651
651
  });
652
652
  }
653
653
  // Re-evaluate subscriptions so the supplemental RPC poll picks up the
@@ -1166,7 +1166,7 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
1166
1166
  this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this), {
1167
1167
  chainIds: addedEnabledChains,
1168
1168
  forceUpdate: true,
1169
- updateMode: 'merge',
1169
+ updateMode: { type: 'merge' },
1170
1170
  }).catch((error) => {
1171
1171
  log('Failed to fetch balance for added chains', { error });
1172
1172
  });
@@ -1361,9 +1361,31 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1361
1361
  }
1362
1362
  }
1363
1363
  });
1364
+ }, _AssetsController_buildFullBalances = function _AssetsController_buildFullBalances({ previousBalances, accountBalances, customAssetIds, fullReplaceChains, }) {
1365
+ const next = { ...previousBalances };
1366
+ const customAssetIdSet = new Set(customAssetIds);
1367
+ // Drop stale balance entries on the authoritative chains so the response is the
1368
+ // source of truth there — but never drop user custom assets.
1369
+ for (const assetId of Object.keys(next)) {
1370
+ if (customAssetIdSet.has(assetId)) {
1371
+ continue;
1372
+ }
1373
+ if (fullReplaceChains.has(extractChainId(assetId))) {
1374
+ delete next[assetId];
1375
+ }
1376
+ }
1377
+ // Apply the response (authoritative on its replaced chains).
1378
+ Object.assign(next, accountBalances);
1379
+ // Custom assets must survive a full refresh even when the source omits them.
1380
+ for (const customId of customAssetIds) {
1381
+ next[customId] ?? (next[customId] = previousBalances[customId] ?? { amount: '0' });
1382
+ }
1383
+ return next;
1364
1384
  }, _AssetsController_updateState = async function _AssetsController_updateState(response) {
1365
1385
  const normalizedResponse = normalizeResponse(response);
1366
- const mode = normalizedResponse.updateMode ?? 'merge';
1386
+ const mode = normalizedResponse.updateMode ?? {
1387
+ type: 'merge',
1388
+ };
1367
1389
  const releaseLock = await __classPrivateFieldGet(this, _AssetsController_controllerMutex, "f").acquire();
1368
1390
  try {
1369
1391
  const previousState = this.state;
@@ -1409,33 +1431,36 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1409
1431
  for (const [accountId, accountBalances] of Object.entries(normalizedResponse.assetsBalance)) {
1410
1432
  const previousBalances = previousState.assetsBalance[accountId] ?? {};
1411
1433
  const customAssetIds = state.customAssets[accountId] ?? [];
1412
- // Full: response is authoritative; preserve custom assets not in response.
1434
+ /*
1435
+
1436
+ const updateMode: AssetsUpdateMode = normalizedResponse.updateMode ?? {
1437
+ type: 'merge',
1438
+ };
1439
+ const fullReplaceChains: Set<ChainId> | null =
1440
+ updateMode.type === 'full'
1441
+ ? new Set(updateMode.fullReplaceChainIds)
1442
+ : null;
1443
+
1444
+ */
1445
+ // Full: response is authoritative, but only for the chains it declares
1446
+ // balances on every other chain are preserved.
1413
1447
  // Merge: response overlays previous balances.
1414
- // Callers that fetch partial data (e.g. newly added chains) must set updateMode: 'merge'.
1415
- const effective = mode === 'merge'
1448
+ // Callers that fetch partial data (e.g. newly added chains) must use { type: 'merge' }.
1449
+ const effective = mode.type === 'merge'
1416
1450
  ? { ...previousBalances, ...accountBalances }
1417
- : (() => {
1418
- const next = {
1419
- ...accountBalances,
1420
- };
1421
- for (const customId of customAssetIds) {
1422
- if (!(customId in next)) {
1423
- const prev = previousBalances[customId];
1424
- next[customId] =
1425
- prev ?? { amount: '0' };
1426
- }
1427
- }
1428
- return next;
1429
- })();
1451
+ : __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildFullBalances).call(this, {
1452
+ previousBalances,
1453
+ accountBalances,
1454
+ customAssetIds,
1455
+ fullReplaceChains: new Set(mode.fullReplaceChainIds),
1456
+ });
1430
1457
  // Ensure native tokens have an entry (0 if missing) for chains this account supports
1431
1458
  const account = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((a) => a.id === accountId);
1432
1459
  const nativeAssetIdsForAccount = account
1433
1460
  ? __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForAccount).call(this, account)
1434
1461
  : __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForEnabledChains).call(this);
1435
1462
  for (const nativeAssetId of nativeAssetIdsForAccount) {
1436
- if (!(nativeAssetId in effective)) {
1437
- effective[nativeAssetId] = { amount: '0' };
1438
- }
1463
+ effective[nativeAssetId] ?? (effective[nativeAssetId] = { amount: '0' });
1439
1464
  }
1440
1465
  for (const [assetId, balance] of Object.entries(effective)) {
1441
1466
  const previousBalance = previousBalances[assetId];
@@ -1941,7 +1966,7 @@ async function _AssetsController_handleAccountGroupChanged() {
1941
1966
  await this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this), {
1942
1967
  chainIds: addedChains,
1943
1968
  forceUpdate: true,
1944
- updateMode: 'merge',
1969
+ updateMode: { type: 'merge' },
1945
1970
  });
1946
1971
  }
1947
1972
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);