@metamask/assets-controller 5.0.1 → 6.1.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.
Files changed (78) hide show
  1. package/CHANGELOG.md +54 -1
  2. package/dist/AssetsController.cjs +172 -45
  3. package/dist/AssetsController.cjs.map +1 -1
  4. package/dist/AssetsController.d.cts +12 -4
  5. package/dist/AssetsController.d.cts.map +1 -1
  6. package/dist/AssetsController.d.mts +12 -4
  7. package/dist/AssetsController.d.mts.map +1 -1
  8. package/dist/AssetsController.mjs +173 -46
  9. package/dist/AssetsController.mjs.map +1 -1
  10. package/dist/data-sources/BackendWebsocketDataSource.cjs +48 -30
  11. package/dist/data-sources/BackendWebsocketDataSource.cjs.map +1 -1
  12. package/dist/data-sources/BackendWebsocketDataSource.d.cts +3 -1
  13. package/dist/data-sources/BackendWebsocketDataSource.d.cts.map +1 -1
  14. package/dist/data-sources/BackendWebsocketDataSource.d.mts +3 -1
  15. package/dist/data-sources/BackendWebsocketDataSource.d.mts.map +1 -1
  16. package/dist/data-sources/BackendWebsocketDataSource.mjs +48 -30
  17. package/dist/data-sources/BackendWebsocketDataSource.mjs.map +1 -1
  18. package/dist/data-sources/RpcDataSource.cjs +26 -8
  19. package/dist/data-sources/RpcDataSource.cjs.map +1 -1
  20. package/dist/data-sources/RpcDataSource.d.cts +8 -3
  21. package/dist/data-sources/RpcDataSource.d.cts.map +1 -1
  22. package/dist/data-sources/RpcDataSource.d.mts +8 -3
  23. package/dist/data-sources/RpcDataSource.d.mts.map +1 -1
  24. package/dist/data-sources/RpcDataSource.mjs +26 -8
  25. package/dist/data-sources/RpcDataSource.mjs.map +1 -1
  26. package/dist/data-sources/TokenDataSource.cjs +27 -12
  27. package/dist/data-sources/TokenDataSource.cjs.map +1 -1
  28. package/dist/data-sources/TokenDataSource.d.cts.map +1 -1
  29. package/dist/data-sources/TokenDataSource.d.mts.map +1 -1
  30. package/dist/data-sources/TokenDataSource.mjs +27 -12
  31. package/dist/data-sources/TokenDataSource.mjs.map +1 -1
  32. package/dist/data-sources/evm-rpc-services/clients/MulticallClient.cjs +8 -0
  33. package/dist/data-sources/evm-rpc-services/clients/MulticallClient.cjs.map +1 -1
  34. package/dist/data-sources/evm-rpc-services/clients/MulticallClient.d.cts.map +1 -1
  35. package/dist/data-sources/evm-rpc-services/clients/MulticallClient.d.mts.map +1 -1
  36. package/dist/data-sources/evm-rpc-services/clients/MulticallClient.mjs +8 -0
  37. package/dist/data-sources/evm-rpc-services/clients/MulticallClient.mjs.map +1 -1
  38. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.cjs +8 -6
  39. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.cjs.map +1 -1
  40. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.cts +4 -2
  41. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.cts.map +1 -1
  42. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.mts +4 -2
  43. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.mts.map +1 -1
  44. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.mjs +8 -6
  45. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.mjs.map +1 -1
  46. package/dist/utils/formatExchangeRatesForBridge.cjs +10 -8
  47. package/dist/utils/formatExchangeRatesForBridge.cjs.map +1 -1
  48. package/dist/utils/formatExchangeRatesForBridge.d.cts +5 -3
  49. package/dist/utils/formatExchangeRatesForBridge.d.cts.map +1 -1
  50. package/dist/utils/formatExchangeRatesForBridge.d.mts +5 -3
  51. package/dist/utils/formatExchangeRatesForBridge.d.mts.map +1 -1
  52. package/dist/utils/formatExchangeRatesForBridge.mjs +11 -9
  53. package/dist/utils/formatExchangeRatesForBridge.mjs.map +1 -1
  54. package/dist/utils/formatStateForTransactionPay.cjs +8 -6
  55. package/dist/utils/formatStateForTransactionPay.cjs.map +1 -1
  56. package/dist/utils/formatStateForTransactionPay.d.cts +2 -2
  57. package/dist/utils/formatStateForTransactionPay.d.cts.map +1 -1
  58. package/dist/utils/formatStateForTransactionPay.d.mts +2 -2
  59. package/dist/utils/formatStateForTransactionPay.d.mts.map +1 -1
  60. package/dist/utils/formatStateForTransactionPay.mjs +8 -6
  61. package/dist/utils/formatStateForTransactionPay.mjs.map +1 -1
  62. package/dist/utils/index.cjs +4 -1
  63. package/dist/utils/index.cjs.map +1 -1
  64. package/dist/utils/index.d.cts +1 -0
  65. package/dist/utils/index.d.cts.map +1 -1
  66. package/dist/utils/index.d.mts +1 -0
  67. package/dist/utils/index.d.mts.map +1 -1
  68. package/dist/utils/index.mjs +1 -0
  69. package/dist/utils/index.mjs.map +1 -1
  70. package/dist/utils/native-assets.cjs +63 -0
  71. package/dist/utils/native-assets.cjs.map +1 -0
  72. package/dist/utils/native-assets.d.cts +19 -0
  73. package/dist/utils/native-assets.d.cts.map +1 -0
  74. package/dist/utils/native-assets.d.mts +19 -0
  75. package/dist/utils/native-assets.d.mts.map +1 -0
  76. package/dist/utils/native-assets.mjs +58 -0
  77. package/dist/utils/native-assets.mjs.map +1 -0
  78. package/package.json +11 -10
package/CHANGELOG.md CHANGED
@@ -7,6 +7,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [6.1.0]
11
+
12
+ ### Added
13
+
14
+ - Add newly supported chains to multicall contract support in `MulticallClient` ([#8346](https://github.com/MetaMask/core/pull/8346))
15
+ - Tempo Mainnet (`4217`/`0x1079`)
16
+ - Tempo Testnet Moderato (`42431`/`0xa5bf`)
17
+ - Ink Mainnet (`57073`/`0xdef1`)
18
+ - Stable mainnet (`988`/`0x3dc`)
19
+
20
+ ### Changed
21
+
22
+ - Bump `@metamask/assets-controllers` from `^104.0.0` to `^104.3.0` ([#8509](https://github.com/MetaMask/core/pull/8509), [#8544](https://github.com/MetaMask/core/pull/8544), [#8559](https://github.com/MetaMask/core/pull/8559))
23
+ - Bump `@metamask/keyring-api` from `^21.6.0` to `^23.0.1` ([#8464](https://github.com/MetaMask/core/pull/8464))
24
+ - Bump `@metamask/keyring-internal-api` from `^10.0.0` to `^10.1.1` ([#8464](https://github.com/MetaMask/core/pull/8464))
25
+ - Bump `@metamask/keyring-snap-client` from `^8.2.0` to `^9.0.1` ([#8464](https://github.com/MetaMask/core/pull/8464))
26
+ - Bump `@metamask/transaction-controller` from `^64.2.0` to `^64.3.0` ([#8482](https://github.com/MetaMask/core/pull/8482))
27
+
28
+ ### Fixed
29
+
30
+ - Native asset detection now correctly identifies native assets across all CAIP-19 representations, not just `slip44:` namespace checks ([#8483](https://github.com/MetaMask/core/pull/8483))
31
+ - Previously, native assets represented as ERC-20 tokens were not recognized as native, causing incorrect token type classification.
32
+ - Exempt mUSD token from EVM ERC-20 minimum-occurrence spam filter so it is no longer incorrectly hidden ([#8541](https://github.com/MetaMask/core/pull/8541))
33
+
34
+ ## [6.0.0]
35
+
36
+ ### Added
37
+
38
+ - **BREAKING:** `AssetsControllerMessenger` now requires the `AccountsControllerGetSelectedAccountAction` allowed action ([#8430](https://github.com/MetaMask/core/pull/8430))
39
+ - Used as a fallback in `#getSelectedAccounts()` when `AccountTreeController` has not yet initialized.
40
+ - Consumers must register `AccountsController:getSelectedAccount` on the messenger.
41
+ - **BREAKING:** `AssetsControllerMessenger` now requires the `TransactionControllerUnapprovedTransactionAddedEvent` allowed event ([#8430](https://github.com/MetaMask/core/pull/8430))
42
+ - `AssetsController` subscribes to `TransactionController:unapprovedTransactionAdded` to refresh balances for the account initiating a transaction (e.g. for gas estimations).
43
+ - Consumers must allow `TransactionController:unapprovedTransactionAdded` on the messenger.
44
+ - Added `isOnboarded` option to `AssetsControllerOptions` and `RpcDataSourceConfig` ([#8430](https://github.com/MetaMask/core/pull/8430))
45
+ - When `isOnboarded` returns `false`, `RpcDataSource` skips `fetch` and `subscribe` calls, preventing on-chain RPC calls before onboarding is complete.
46
+ - Defaults to `() => true` so existing consumers are unaffected.
47
+
48
+ ### Changed
49
+
50
+ - Bump `@metamask/account-tree-controller` from `^7.0.0` to `^7.1.0` ([#8472](https://github.com/MetaMask/core/pull/8472))
51
+
10
52
  ## [5.0.1]
11
53
 
12
54
  ### Changed
@@ -17,6 +59,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
17
59
 
18
60
  ### Fixed
19
61
 
62
+ - `AssetsController` now re-subscribes to all data sources when `AccountTreeController` state changes after initial startup, ensuring snap accounts and their chains are included ([#8430](https://github.com/MetaMask/core/pull/8430))
63
+ - Previously, `#start()` would create subscriptions before snap accounts were available, and its idempotency guard prevented re-subscription when the full account list arrived.
64
+ - Added `#handleAccountTreeStateChange()` which forces a full re-subscription and re-fetch when the account tree updates, picking up all accounts including snaps.
65
+ - Added `AccountsController:getSelectedAccount` as a fallback in `#getSelectedAccounts()` for when the account tree is not yet initialized.
66
+ - `TokenDataSource` no longer filters out user-imported custom assets with the `MIN_TOKEN_OCCURRENCES` spam filter or Blockaid bulk scan ([#8430](https://github.com/MetaMask/core/pull/8430))
67
+ - Tokens present in `customAssets` state now bypass the EVM occurrence threshold and non-EVM Blockaid scan, ensuring manually imported assets always appear.
68
+ - `BackendWebsocketDataSource` now properly releases chains to `AccountsApiDataSource` when the websocket is disconnected or disabled ([#8430](https://github.com/MetaMask/core/pull/8430))
69
+ - Previously, `BackendWebsocketDataSource` eagerly claimed all supported chains on initialization regardless of connection state, preventing `AccountsApiDataSource` from polling.
70
+ - Chains are now only claimed when the websocket is connected. On disconnect, chains are released so the chain-claiming loop assigns them to `AccountsApiDataSource` for polling fallback. On reconnect, chains are reclaimed.
20
71
  - `AssetsController` no longer silently skips asset fetching on startup for returning users ([#8412](https://github.com/MetaMask/core/pull/8412))
21
72
  - Previously, `#start()` was called at keyring unlock before `AccountTreeController.init()` had built the account tree, causing `#selectedAccounts` to return an empty array and all subscriptions and fetches to be skipped. `selectedAccountGroupChange` does not fire when the persisted selected group is unchanged, leaving the controller idle.
22
73
  - Now subscribes to `AccountTreeController:stateChange` (the base-controller event guaranteed to fire when `init()` calls `this.update()`), so the controller re-evaluates its active state once accounts are available.
@@ -302,7 +353,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
302
353
  - Refactor `RpcDataSource` to delegate polling to `BalanceFetcher` and `TokenDetector` services ([#7709](https://github.com/MetaMask/core/pull/7709))
303
354
  - Refactor `BalanceFetcher` and `TokenDetector` to extend `StaticIntervalPollingControllerOnly` for independent polling management ([#7709](https://github.com/MetaMask/core/pull/7709))
304
355
 
305
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@5.0.1...HEAD
356
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@6.1.0...HEAD
357
+ [6.1.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@6.0.0...@metamask/assets-controller@6.1.0
358
+ [6.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@5.0.1...@metamask/assets-controller@6.0.0
306
359
  [5.0.1]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@5.0.0...@metamask/assets-controller@5.0.1
307
360
  [5.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@4.0.0...@metamask/assets-controller@5.0.0
308
361
  [4.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controller@3.3.0...@metamask/assets-controller@4.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_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_shouldHideNativeToken, _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_lastKnownAccountIds, _AssetsController_getSelectedAccounts, _AssetsController_backendWebsocketDataSource, _AssetsController_accountsApiDataSource, _AssetsController_snapDataSource, _AssetsController_rpcDataSource, _AssetsController_stakedBalanceDataSource, _AssetsController_allBalanceDataSources_get, _AssetsController_priceDataSource, _AssetsController_detectionMiddleware, _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_updateState, _AssetsController_getAssetsFromState, _AssetsController_shouldHideNativeToken, _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");
@@ -34,6 +34,8 @@ const logger_1 = require("./logger.cjs");
34
34
  const DetectionMiddleware_1 = require("./middlewares/DetectionMiddleware.cjs");
35
35
  const ParallelMiddleware_1 = require("./middlewares/ParallelMiddleware.cjs");
36
36
  const utils_2 = require("./utils/index.cjs");
37
+ const constants_1 = require("./utils/constants.cjs");
38
+ const NATIVE_ASSETS_QUERY_KEY = ['nativeAssets'];
37
39
  // ============================================================================
38
40
  // CONTROLLER CONSTANTS
39
41
  // ============================================================================
@@ -210,7 +212,7 @@ function normalizeResponse(response) {
210
212
  * - The controller does NOT manage polling - it simply receives pushed updates
211
213
  */
212
214
  class AssetsController extends base_controller_1.BaseController {
213
- constructor({ messenger, state = {}, defaultUpdateInterval = DEFAULT_POLLING_INTERVAL_MS, isEnabled = () => true, isBasicFunctionality, subscribeToBasicFunctionalityChange, queryApiClient, rpcDataSourceConfig, trace, accountsApiDataSourceConfig, priceDataSourceConfig, stakedBalanceDataSourceConfig, }) {
215
+ constructor({ messenger, state = {}, defaultUpdateInterval = DEFAULT_POLLING_INTERVAL_MS, isEnabled = () => true, isBasicFunctionality, subscribeToBasicFunctionalityChange, queryApiClient, rpcDataSourceConfig, trace, accountsApiDataSourceConfig, priceDataSourceConfig, stakedBalanceDataSourceConfig, isOnboarded, }) {
214
216
  super({
215
217
  name: CONTROLLER_NAME,
216
218
  messenger,
@@ -247,6 +249,12 @@ class AssetsController extends base_controller_1.BaseController {
247
249
  _AssetsController_activeSubscriptions.set(this, new Map());
248
250
  /** Currently enabled chains from NetworkEnablementController */
249
251
  _AssetsController_enabledChains.set(this, new Set());
252
+ /**
253
+ * Snapshot of account IDs that were active when the last subscription/fetch
254
+ * cycle ran. Used by #handleAccountTreeStateChange to skip redundant
255
+ * re-subscriptions when the account set hasn't actually changed.
256
+ */
257
+ _AssetsController_lastKnownAccountIds.set(this, new Set());
250
258
  _AssetsController_backendWebsocketDataSource.set(this, void 0);
251
259
  _AssetsController_accountsApiDataSource.set(this, void 0);
252
260
  _AssetsController_snapDataSource.set(this, void 0);
@@ -256,12 +264,15 @@ class AssetsController extends base_controller_1.BaseController {
256
264
  _AssetsController_detectionMiddleware.set(this, void 0);
257
265
  _AssetsController_tokenDataSource.set(this, void 0);
258
266
  _AssetsController_unsubscribeBasicFunctionality.set(this, null);
267
+ _AssetsController_queryApiClient.set(this, void 0);
259
268
  _AssetsController_onActiveChainsUpdated.set(this, void 0);
260
269
  __classPrivateFieldSet(this, _AssetsController_isEnabled, isEnabled(), "f");
261
270
  __classPrivateFieldSet(this, _AssetsController_isBasicFunctionality, isBasicFunctionality ?? (() => true), "f");
262
271
  __classPrivateFieldSet(this, _AssetsController_defaultUpdateInterval, defaultUpdateInterval, "f");
263
272
  __classPrivateFieldSet(this, _AssetsController_trace, trace, "f");
273
+ __classPrivateFieldSet(this, _AssetsController_queryApiClient, queryApiClient, "f");
264
274
  const rpcConfig = rpcDataSourceConfig ?? {};
275
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_initializeNativeAssetsMap).call(this, queryApiClient);
265
276
  __classPrivateFieldSet(this, _AssetsController_onActiveChainsUpdated, (dataSourceName, chains, previousChains) => {
266
277
  try {
267
278
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleActiveChainsUpdate).call(this, dataSourceName, chains, previousChains);
@@ -277,6 +288,7 @@ class AssetsController extends base_controller_1.BaseController {
277
288
  messenger: this.messenger,
278
289
  queryApiClient,
279
290
  onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
291
+ isNativeAsset: (assetId) => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_isNativeAsset).call(this, assetId),
280
292
  }), "f");
281
293
  __classPrivateFieldSet(this, _AssetsController_accountsApiDataSource, new AccountsApiDataSource_1.AccountsApiDataSource({
282
294
  queryApiClient,
@@ -290,7 +302,10 @@ class AssetsController extends base_controller_1.BaseController {
290
302
  __classPrivateFieldSet(this, _AssetsController_rpcDataSource, new RpcDataSource_1.RpcDataSource({
291
303
  messenger: this.messenger,
292
304
  onActiveChainsUpdated: __classPrivateFieldGet(this, _AssetsController_onActiveChainsUpdated, "f"),
305
+ getNativeAssetForChain: (chainId) => __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetMap).call(this)[chainId] ??
306
+ `${chainId}/erc20:${constants_1.ZERO_ADDRESS}`,
293
307
  ...rpcConfig,
308
+ isOnboarded: rpcConfig.isOnboarded ?? isOnboarded,
294
309
  }), "f");
295
310
  __classPrivateFieldSet(this, _AssetsController_stakedBalanceDataSource, new StakedBalanceDataSource_1.StakedBalanceDataSource({
296
311
  messenger: this.messenger,
@@ -300,8 +315,7 @@ class AssetsController extends base_controller_1.BaseController {
300
315
  __classPrivateFieldSet(this, _AssetsController_tokenDataSource, new TokenDataSource_1.TokenDataSource(this.messenger, {
301
316
  queryApiClient,
302
317
  getNativeAssetIds: () => {
303
- const { nativeAssetIdentifiers } = this.messenger.call('NetworkEnablementController:getState');
304
- return Object.values(nativeAssetIdentifiers);
318
+ return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForEnabledChains).call(this);
305
319
  },
306
320
  }), "f");
307
321
  __classPrivateFieldSet(this, _AssetsController_priceDataSource, new PriceDataSource_1.PriceDataSource({
@@ -489,12 +503,12 @@ class AssetsController extends base_controller_1.BaseController {
489
503
  * @returns Bridge-compatible exchange rate state derived from assetsPrice and selectedCurrency.
490
504
  */
491
505
  getExchangeRatesForBridge() {
492
- const { nativeAssetIdentifiers } = this.messenger.call('NetworkEnablementController:getState');
493
506
  const { networkConfigurationsByChainId } = this.messenger.call('NetworkController:getState');
494
507
  return (0, utils_2.formatExchangeRatesForBridge)({
508
+ assetsInfo: this.state.assetsInfo,
495
509
  assetsPrice: this.state.assetsPrice,
496
510
  selectedCurrency: this.state.selectedCurrency,
497
- nativeAssetIdentifiers,
511
+ nativeAssetIdentifiers: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetMap).call(this),
498
512
  networkConfigurationsByChainId,
499
513
  });
500
514
  }
@@ -508,8 +522,7 @@ class AssetsController extends base_controller_1.BaseController {
508
522
  * @returns Legacy-compatible state for transaction-pay-controller.
509
523
  */
510
524
  getStateForTransactionPay() {
511
- const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get);
512
- const { nativeAssetIdentifiers } = this.messenger.call('NetworkEnablementController:getState');
525
+ const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this);
513
526
  const { networkConfigurationsByChainId } = this.messenger.call('NetworkController:getState');
514
527
  return (0, utils_2.formatStateForTransactionPay)({
515
528
  assetsBalance: this.state.assetsBalance,
@@ -517,7 +530,7 @@ class AssetsController extends base_controller_1.BaseController {
517
530
  assetsPrice: this.state.assetsPrice,
518
531
  selectedCurrency: this.state.selectedCurrency,
519
532
  accounts: accounts.map((a) => ({ id: a.id, address: a.address })),
520
- nativeAssetIdentifiers,
533
+ nativeAssetIdentifiers: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetMap).call(this),
521
534
  networkConfigurationsByChainId,
522
535
  });
523
536
  }
@@ -561,7 +574,7 @@ class AssetsController extends base_controller_1.BaseController {
561
574
  if (pendingMetadata) {
562
575
  const parsed = (0, utils_1.parseCaipAssetType)(normalizedAssetId);
563
576
  let tokenType = 'erc20';
564
- if (parsed.assetNamespace === 'slip44') {
577
+ if (__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_isNativeAsset).call(this, normalizedAssetId)) {
565
578
  tokenType = 'native';
566
579
  }
567
580
  else if (parsed.assetNamespace === 'spl') {
@@ -581,7 +594,7 @@ class AssetsController extends base_controller_1.BaseController {
581
594
  }
582
595
  });
583
596
  // Fetch data for the newly added custom asset (merge to preserve other chains)
584
- const account = __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).find((a) => a.id === accountId);
597
+ const account = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((a) => a.id === accountId);
585
598
  if (account) {
586
599
  const chainId = extractChainId(normalizedAssetId);
587
600
  await this.getAssets([account], {
@@ -680,7 +693,7 @@ class AssetsController extends base_controller_1.BaseController {
680
693
  if (!__classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)) {
681
694
  return;
682
695
  }
683
- this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
696
+ this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this), {
684
697
  forceUpdate: true,
685
698
  dataTypes: ['price'],
686
699
  assetsForPriceUpdate: Object.values(this.state.assetsBalance).flatMap((balances) => Object.keys(balances)),
@@ -705,10 +718,11 @@ class AssetsController extends base_controller_1.BaseController {
705
718
  const subscriptionKey = 'ds:PriceDataSource';
706
719
  const existingSubscription = __classPrivateFieldGet(this, _AssetsController_activeSubscriptions, "f").get(subscriptionKey);
707
720
  const isUpdate = existingSubscription !== undefined;
721
+ const request = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildDataRequest).call(this, accounts, chainIds, {
722
+ dataTypes: ['price'],
723
+ });
708
724
  const subscribeReq = {
709
- request: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildDataRequest).call(this, accounts, chainIds, {
710
- dataTypes: ['price'],
711
- }),
725
+ request,
712
726
  subscriptionId: subscriptionKey,
713
727
  isUpdate,
714
728
  onAssetsUpdate: (response) => this.handleAssetsUpdate(response, 'PriceDataSource'),
@@ -836,7 +850,7 @@ class AssetsController extends base_controller_1.BaseController {
836
850
  }
837
851
  }
838
852
  exports.AssetsController = AssetsController;
839
- _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 = {
853
+ _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_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_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 = {
840
854
  controller: 'AssetsController',
841
855
  }) {
842
856
  if (!__classPrivateFieldGet(this, _AssetsController_trace, "f")) {
@@ -882,8 +896,16 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
882
896
  price_entries: Object.keys(assetsPrice).length,
883
897
  custom_asset_entries: customAssetEntries,
884
898
  });
885
- }, _AssetsController_selectedAccounts_get = function _AssetsController_selectedAccounts_get() {
886
- return this.messenger.call('AccountTreeController:getAccountsFromSelectedAccountGroup');
899
+ }, _AssetsController_getSelectedAccounts = function _AssetsController_getSelectedAccounts() {
900
+ const accounts = this.messenger.call('AccountTreeController:getAccountsFromSelectedAccountGroup');
901
+ if (accounts.length > 0) {
902
+ return accounts;
903
+ }
904
+ const selectedAccount = this.messenger.call('AccountsController:getSelectedAccount');
905
+ if (selectedAccount) {
906
+ return [selectedAccount];
907
+ }
908
+ return [];
887
909
  }, _AssetsController_allBalanceDataSources_get = function _AssetsController_allBalanceDataSources_get() {
888
910
  return [
889
911
  __classPrivateFieldGet(this, _AssetsController_backendWebsocketDataSource, "f"),
@@ -891,6 +913,25 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
891
913
  __classPrivateFieldGet(this, _AssetsController_snapDataSource, "f"),
892
914
  __classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f"),
893
915
  ];
916
+ }, _AssetsController_initializeNativeAssetsMap = function _AssetsController_initializeNativeAssetsMap(queryApiClient) {
917
+ queryApiClient.queryClient
918
+ .fetchQuery({
919
+ queryKey: NATIVE_ASSETS_QUERY_KEY,
920
+ queryFn: utils_2.buildNativeAssetsFromApi,
921
+ staleTime: Infinity,
922
+ gcTime: Infinity,
923
+ })
924
+ .catch((error) => {
925
+ // Failure to populate native asset cache is non-fatal;
926
+ // #isNativeAsset falls back to the seed data from buildNativeAssetsFromConstant.
927
+ log('Failed to populate native asset cache, falling back to seed data', error);
928
+ });
929
+ // Seed the cache synchronously so that synchronous consumers (e.g.
930
+ // #isNativeAsset, #resolveNativeAssetIds) have data available immediately.
931
+ // When fetchQuery resolves (currently instant, future: API), it overwrites
932
+ // this with potentially fresher data.
933
+ const initialNativeAssetMap = (0, utils_2.buildNativeAssetsFromConstant)();
934
+ queryApiClient.setCachedData(NATIVE_ASSETS_QUERY_KEY, initialNativeAssetMap);
894
935
  }, _AssetsController_initializeState = function _AssetsController_initializeState() {
895
936
  const { enabledNetworkMap } = this.messenger.call('NetworkEnablementController:getState');
896
937
  __classPrivateFieldSet(this, _AssetsController_enabledChains, __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_extractEnabledChains).call(this, enabledNetworkMap), "f");
@@ -936,7 +977,7 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
936
977
  // when init() calls this.update(). #start() is idempotent so
937
978
  // repeated fires are safe.
938
979
  this.messenger.subscribe('AccountTreeController:stateChange', () => {
939
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateActive).call(this);
980
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_handleAccountTreeStateChange).call(this);
940
981
  });
941
982
  // Subscribe to network enablement changes (only enabledNetworkMap)
942
983
  this.messenger.subscribe('NetworkEnablementController:stateChange', ({ enabledNetworkMap }) => {
@@ -955,6 +996,33 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
955
996
  __classPrivateFieldSet(this, _AssetsController_keyringUnlocked, false, "f");
956
997
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_updateActive).call(this);
957
998
  });
999
+ // Subscribe to unapproved transactions - TXs that need confirmation
1000
+ // Ensures that balances for the account making transaction are updated (e.g. for gas estimations)
1001
+ this.messenger.subscribe('TransactionController:unapprovedTransactionAdded', (transactionMeta) => {
1002
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_onUnapprovedTransactionAdded).call(this, transactionMeta);
1003
+ });
1004
+ }, _AssetsController_onUnapprovedTransactionAdded = function _AssetsController_onUnapprovedTransactionAdded(transactionMeta) {
1005
+ const hexChainId = transactionMeta.chainId;
1006
+ if (!hexChainId) {
1007
+ return;
1008
+ }
1009
+ const caipChainId = `eip155:${parseInt(hexChainId, 16)}`;
1010
+ const fromAddress = transactionMeta.txParams.from?.toLowerCase();
1011
+ if (!fromAddress) {
1012
+ return;
1013
+ }
1014
+ const matchedAccount = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((account) => account.address.toLowerCase() === fromAddress);
1015
+ if (!matchedAccount) {
1016
+ return;
1017
+ }
1018
+ this.getAssets([matchedAccount], {
1019
+ chainIds: [caipChainId],
1020
+ forceUpdate: true,
1021
+ }).catch((error) => {
1022
+ log('Failed to refresh assets after unapproved transaction added', {
1023
+ error,
1024
+ });
1025
+ });
958
1026
  }, _AssetsController_updateActive = function _AssetsController_updateActive() {
959
1027
  const shouldRun = __classPrivateFieldGet(this, _AssetsController_uiOpen, "f") && __classPrivateFieldGet(this, _AssetsController_keyringUnlocked, "f");
960
1028
  if (shouldRun) {
@@ -963,6 +1031,36 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
963
1031
  else {
964
1032
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_stop).call(this);
965
1033
  }
1034
+ }, _AssetsController_handleAccountTreeStateChange = function _AssetsController_handleAccountTreeStateChange() {
1035
+ const shouldRun = __classPrivateFieldGet(this, _AssetsController_uiOpen, "f") && __classPrivateFieldGet(this, _AssetsController_keyringUnlocked, "f");
1036
+ if (!shouldRun) {
1037
+ return;
1038
+ }
1039
+ if (__classPrivateFieldGet(this, _AssetsController_activeSubscriptions, "f").size > 0) {
1040
+ const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this);
1041
+ const currentIds = new Set(accounts.map((a) => a.id));
1042
+ const accountsChanged = currentIds.size !== __classPrivateFieldGet(this, _AssetsController_lastKnownAccountIds, "f").size ||
1043
+ [...currentIds].some((id) => !__classPrivateFieldGet(this, _AssetsController_lastKnownAccountIds, "f").has(id));
1044
+ if (!accountsChanged) {
1045
+ return;
1046
+ }
1047
+ log('Account tree changed with new accounts, re-subscribing', {
1048
+ previousCount: __classPrivateFieldGet(this, _AssetsController_lastKnownAccountIds, "f").size,
1049
+ currentCount: currentIds.size,
1050
+ });
1051
+ __classPrivateFieldSet(this, _AssetsController_lastKnownAccountIds, currentIds, "f");
1052
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
1053
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
1054
+ this.getAssets(accounts, {
1055
+ chainIds: [...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f")],
1056
+ forceUpdate: true,
1057
+ }).catch((error) => {
1058
+ log('Failed to fetch assets after tree change', error);
1059
+ });
1060
+ }
1061
+ else {
1062
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_start).call(this);
1063
+ }
966
1064
  }, _AssetsController_registerActionHandlers = function _AssetsController_registerActionHandlers() {
967
1065
  this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
968
1066
  }, _AssetsController_handleActiveChainsUpdate = function _AssetsController_handleActiveChainsUpdate(dataSourceId, activeChains, previousChains) {
@@ -983,11 +1081,11 @@ _AssetsController_isEnabled = new WeakMap(), _AssetsController_isBasicFunctional
983
1081
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
984
1082
  }
985
1083
  // If chains were added and we have selected accounts, do one-time fetch
986
- if (addedChains.length > 0 && __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length > 0) {
1084
+ if (addedChains.length > 0 && __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).length > 0) {
987
1085
  const addedEnabledChains = addedChains.filter((chain) => __classPrivateFieldGet(this, _AssetsController_enabledChains, "f").has(chain));
988
1086
  if (addedEnabledChains.length > 0) {
989
1087
  log('Fetching balances for newly added chains', { addedEnabledChains });
990
- this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
1088
+ this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this), {
991
1089
  chainIds: addedEnabledChains,
992
1090
  forceUpdate: true,
993
1091
  updateMode: 'merge',
@@ -1071,11 +1169,28 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1071
1169
  });
1072
1170
  }
1073
1171
  return { response: result.response, durationByDataSource };
1172
+ }, _AssetsController_getNativeAssetMap = function _AssetsController_getNativeAssetMap() {
1173
+ return (__classPrivateFieldGet(this, _AssetsController_queryApiClient, "f").getCachedData(NATIVE_ASSETS_QUERY_KEY) ?? {});
1174
+ }, _AssetsController_isNativeAsset = function _AssetsController_isNativeAsset(assetId) {
1175
+ const parsed = (0, utils_1.parseCaipAssetType)(assetId);
1176
+ if (parsed.assetNamespace === 'slip44') {
1177
+ return true;
1178
+ }
1179
+ const lower = assetId.toLowerCase();
1180
+ const isInNativeAssetMap = Object.values(__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetMap).call(this)).some((id) => id.toLowerCase() === lower);
1181
+ if (isInNativeAssetMap) {
1182
+ return true;
1183
+ }
1184
+ if (parsed.assetNamespace === 'erc20' &&
1185
+ parsed.assetReference === constants_1.ZERO_ADDRESS) {
1186
+ return true;
1187
+ }
1188
+ return false;
1074
1189
  }, _AssetsController_resolveNativeAssetIds = function _AssetsController_resolveNativeAssetIds(chains) {
1075
- const { nativeAssetIdentifiers } = this.messenger.call('NetworkEnablementController:getState');
1190
+ const nativeAssetMap = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetMap).call(this);
1076
1191
  const ids = [];
1077
1192
  for (const chainId of chains) {
1078
- const nativeId = nativeAssetIdentifiers?.[chainId];
1193
+ const nativeId = nativeAssetMap[chainId];
1079
1194
  if (nativeId) {
1080
1195
  ids.push(nativeId);
1081
1196
  }
@@ -1086,7 +1201,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1086
1201
  }, _AssetsController_getNativeAssetIdsForAccount = function _AssetsController_getNativeAssetIdsForAccount(account) {
1087
1202
  return __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_resolveNativeAssetIds).call(this, __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getEnabledChainsForAccount).call(this, account));
1088
1203
  }, _AssetsController_ensureNativeBalancesDefaultZero = function _AssetsController_ensureNativeBalancesDefaultZero() {
1089
- const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get);
1204
+ const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this);
1090
1205
  if (accounts.length === 0) {
1091
1206
  return;
1092
1207
  }
@@ -1175,7 +1290,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1175
1290
  return next;
1176
1291
  })();
1177
1292
  // Ensure native tokens have an entry (0 if missing) for chains this account supports
1178
- const account = __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).find((a) => a.id === accountId);
1293
+ const account = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).find((a) => a.id === accountId);
1179
1294
  const nativeAssetIdsForAccount = account
1180
1295
  ? __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForAccount).call(this, account)
1181
1296
  : __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getNativeAssetIdsForEnabledChains).call(this);
@@ -1293,7 +1408,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1293
1408
  }
1294
1409
  const assetChainId = extractChainId(typedAssetId);
1295
1410
  // Skip native tokens on Tempo networks
1296
- if (__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_shouldHideNativeToken).call(this, assetChainId, typedAssetId, metadata)) {
1411
+ if (__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_shouldHideNativeToken).call(this, assetChainId, metadata)) {
1297
1412
  continue;
1298
1413
  }
1299
1414
  if (!chainIdSet.has(assetChainId)) {
@@ -1329,14 +1444,12 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1329
1444
  }
1330
1445
  }
1331
1446
  return result;
1332
- }, _AssetsController_shouldHideNativeToken = function _AssetsController_shouldHideNativeToken(chainId, assetId, metadata) {
1447
+ }, _AssetsController_shouldHideNativeToken = function _AssetsController_shouldHideNativeToken(chainId, metadata) {
1333
1448
  // Check if it's a chain that should skip native tokens
1334
1449
  if (!controller_utils_1.CHAIN_IDS_WITH_NO_NATIVE_TOKEN.includes(chainId)) {
1335
1450
  return false;
1336
1451
  }
1337
- // Check if it's a native token (either by metadata type or assetId format)
1338
- const isNative = metadata.type === 'native' || assetId.includes('/slip44:');
1339
- return isNative;
1452
+ return metadata.type === 'native';
1340
1453
  }, _AssetsController_tokenStandardToAssetType = function _AssetsController_tokenStandardToAssetType(tokenStandard) {
1341
1454
  switch (tokenStandard) {
1342
1455
  case 'native':
@@ -1353,7 +1466,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1353
1466
  return 'fungible';
1354
1467
  }
1355
1468
  }, _AssetsController_start = function _AssetsController_start() {
1356
- const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get);
1469
+ const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this);
1357
1470
  const chainIds = [...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f")];
1358
1471
  if (accounts.length === 0 || chainIds.length === 0) {
1359
1472
  return;
@@ -1365,6 +1478,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1365
1478
  selectedAccountCount: accounts.length,
1366
1479
  enabledChainCount: chainIds.length,
1367
1480
  });
1481
+ __classPrivateFieldSet(this, _AssetsController_lastKnownAccountIds, new Set(accounts.map((a) => a.id)), "f");
1368
1482
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
1369
1483
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_ensureNativeBalancesDefaultZero).call(this);
1370
1484
  this.getAssets(accounts, {
@@ -1380,6 +1494,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1380
1494
  });
1381
1495
  __classPrivateFieldSet(this, _AssetsController_firstInitFetchReported, false, "f");
1382
1496
  __classPrivateFieldSet(this, _AssetsController_stateSizeReported, false, "f");
1497
+ __classPrivateFieldSet(this, _AssetsController_lastKnownAccountIds, new Set(), "f");
1383
1498
  // Stop price subscription first (uses direct messenger call)
1384
1499
  this.unsubscribeAssetsPrice();
1385
1500
  // Stop balance subscriptions by properly notifying data sources via messenger
@@ -1402,23 +1517,21 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1402
1517
  }
1403
1518
  __classPrivateFieldGet(this, _AssetsController_activeSubscriptions, "f").clear();
1404
1519
  }, _AssetsController_subscribeAssets = function _AssetsController_subscribeAssets() {
1405
- if (__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length === 0 || __classPrivateFieldGet(this, _AssetsController_enabledChains, "f").size === 0) {
1520
+ const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this);
1521
+ const enabledChains = [...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f")];
1522
+ if (accounts.length === 0 || enabledChains.length === 0) {
1406
1523
  return;
1407
1524
  }
1408
1525
  // Subscribe to balance updates (batched by data source)
1409
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssetsBalance).call(this, __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), [
1410
- ...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f"),
1411
- ]);
1526
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssetsBalance).call(this, accounts, enabledChains);
1412
1527
  // Subscribe to staked balance updates (separate from regular balance chain-claiming)
1413
- __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeStakedBalance).call(this, __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), [
1414
- ...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f"),
1415
- ]);
1528
+ __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeStakedBalance).call(this, accounts, enabledChains);
1416
1529
  // Subscribe to price updates for all assets held by selected accounts
1417
- this.subscribeAssetsPrice(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), [...__classPrivateFieldGet(this, _AssetsController_enabledChains, "f")]);
1530
+ this.subscribeAssetsPrice(accounts, enabledChains);
1418
1531
  }, _AssetsController_subscribeAssetsBalance = function _AssetsController_subscribeAssetsBalance(accounts, chainIds) {
1419
1532
  const chainToAccounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_buildChainToAccountsMap).call(this, accounts, new Set(chainIds));
1420
1533
  const remainingChains = new Set(chainToAccounts.keys());
1421
- // When basic functionality is on (getter true), use all balance data sources; when off (getter false), RPC only.
1534
+ // When basic functionality is on, use all balance data sources; when off, RPC only.
1422
1535
  const balanceDataSources = __classPrivateFieldGet(this, _AssetsController_isBasicFunctionality, "f").call(this)
1423
1536
  ? __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_allBalanceDataSources_get)
1424
1537
  : [__classPrivateFieldGet(this, _AssetsController_rpcDataSource, "f")];
@@ -1521,16 +1634,19 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1521
1634
  }
1522
1635
  }, _AssetsController_buildDataRequest = function _AssetsController_buildDataRequest(accounts, chainIds, partial = {}) {
1523
1636
  const chainIdSet = new Set(chainIds);
1637
+ // Force update will pass in additional chains for wildcard account scope
1638
+ // Enables updates for chains that are not selected (e.g. for unapproved transactions)
1639
+ const forceUpdateChains = partial.forceUpdate ? chainIds : undefined;
1524
1640
  const accountsWithSupportedChains = accounts.map((account) => ({
1525
1641
  account,
1526
- supportedChains: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getEnabledChainsForAccount).call(this, account).filter((chain) => chainIdSet.has(chain)),
1642
+ supportedChains: __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getEnabledChainsForAccount).call(this, account, forceUpdateChains).filter((chain) => chainIdSet.has(chain)),
1527
1643
  }));
1528
1644
  return {
1529
1645
  accountsWithSupportedChains,
1530
1646
  chainIds,
1531
1647
  ...partial,
1532
1648
  };
1533
- }, _AssetsController_getEnabledChainsForAccount = function _AssetsController_getEnabledChainsForAccount(account) {
1649
+ }, _AssetsController_getEnabledChainsForAccount = function _AssetsController_getEnabledChainsForAccount(account, additionalChains) {
1534
1650
  // Account scopes are CAIP-2 chain IDs like "eip155:1", "solana:mainnet", "bip122:..."
1535
1651
  const scopes = account.scopes ?? [];
1536
1652
  const result = [];
@@ -1543,6 +1659,7 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1543
1659
  const { namespace, reference } = (0, utils_1.parseCaipChainId)(scopeStr);
1544
1660
  // Wildcard scope (e.g., "eip155:0" means all enabled chains in that namespace)
1545
1661
  if (reference === '0') {
1662
+ // Add enabled chains
1546
1663
  for (const chain of __classPrivateFieldGet(this, _AssetsController_enabledChains, "f")) {
1547
1664
  if ((0, utils_1.isCaipChainId)(chain)) {
1548
1665
  const chainParsed = (0, utils_1.parseCaipChainId)(chain);
@@ -1551,6 +1668,15 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1551
1668
  }
1552
1669
  }
1553
1670
  }
1671
+ // Add additional chains
1672
+ for (const chain of additionalChains ?? []) {
1673
+ if ((0, utils_1.isCaipChainId)(chain)) {
1674
+ const chainParsed = (0, utils_1.parseCaipChainId)(chain);
1675
+ if (chainParsed.namespace === namespace) {
1676
+ result.push(chain);
1677
+ }
1678
+ }
1679
+ }
1554
1680
  }
1555
1681
  else if (namespace === 'eip155' && (0, utils_1.isStrictHexString)(reference)) {
1556
1682
  // Normalize hex to decimal for EIP155
@@ -1566,11 +1692,12 @@ async function _AssetsController_executeMiddlewares(sources, request, initialRes
1566
1692
  // EVENT HANDLERS
1567
1693
  // ============================================================================
1568
1694
  async function _AssetsController_handleAccountGroupChanged() {
1569
- const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get);
1695
+ const accounts = __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this);
1570
1696
  log('Account group changed', {
1571
1697
  accountCount: accounts.length,
1572
1698
  accountIds: accounts.map((a) => a.id),
1573
1699
  });
1700
+ __classPrivateFieldSet(this, _AssetsController_lastKnownAccountIds, new Set(accounts.map((a) => a.id)), "f");
1574
1701
  // Subscribe and fetch for the new account group
1575
1702
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
1576
1703
  if (accounts.length > 0) {
@@ -1609,8 +1736,8 @@ async function _AssetsController_handleAccountGroupChanged() {
1609
1736
  // Refresh subscriptions for new chain set
1610
1737
  __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_subscribeAssets).call(this);
1611
1738
  // Do one-time fetch for newly enabled chains; merge so we keep existing chain balances
1612
- if (addedChains.length > 0 && __classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get).length > 0) {
1613
- await this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "a", _AssetsController_selectedAccounts_get), {
1739
+ if (addedChains.length > 0 && __classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this).length > 0) {
1740
+ await this.getAssets(__classPrivateFieldGet(this, _AssetsController_instances, "m", _AssetsController_getSelectedAccounts).call(this), {
1614
1741
  chainIds: addedChains,
1615
1742
  forceUpdate: true,
1616
1743
  updateMode: 'merge',