@metamask/assets-controllers 55.0.0 → 56.0.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 (46) hide show
  1. package/CHANGELOG.md +37 -1
  2. package/dist/AccountTrackerController.cjs +7 -25
  3. package/dist/AccountTrackerController.cjs.map +1 -1
  4. package/dist/AccountTrackerController.d.cts +5 -10
  5. package/dist/AccountTrackerController.d.cts.map +1 -1
  6. package/dist/AccountTrackerController.d.mts +5 -10
  7. package/dist/AccountTrackerController.d.mts.map +1 -1
  8. package/dist/AccountTrackerController.mjs +7 -25
  9. package/dist/AccountTrackerController.mjs.map +1 -1
  10. package/dist/CurrencyRateController.cjs +3 -0
  11. package/dist/CurrencyRateController.cjs.map +1 -1
  12. package/dist/CurrencyRateController.d.cts +1 -1
  13. package/dist/CurrencyRateController.d.cts.map +1 -1
  14. package/dist/CurrencyRateController.d.mts +1 -1
  15. package/dist/CurrencyRateController.d.mts.map +1 -1
  16. package/dist/CurrencyRateController.mjs +3 -0
  17. package/dist/CurrencyRateController.mjs.map +1 -1
  18. package/dist/NftController.cjs +6 -4
  19. package/dist/NftController.cjs.map +1 -1
  20. package/dist/NftController.d.cts.map +1 -1
  21. package/dist/NftController.d.mts.map +1 -1
  22. package/dist/NftController.mjs +6 -4
  23. package/dist/NftController.mjs.map +1 -1
  24. package/dist/TokenListController.cjs +0 -13
  25. package/dist/TokenListController.cjs.map +1 -1
  26. package/dist/TokenListController.d.cts +0 -1
  27. package/dist/TokenListController.d.cts.map +1 -1
  28. package/dist/TokenListController.d.mts +0 -1
  29. package/dist/TokenListController.d.mts.map +1 -1
  30. package/dist/TokenListController.mjs +0 -13
  31. package/dist/TokenListController.mjs.map +1 -1
  32. package/dist/TokenRatesController.cjs +5 -1
  33. package/dist/TokenRatesController.cjs.map +1 -1
  34. package/dist/TokenRatesController.d.cts.map +1 -1
  35. package/dist/TokenRatesController.d.mts.map +1 -1
  36. package/dist/TokenRatesController.mjs +5 -1
  37. package/dist/TokenRatesController.mjs.map +1 -1
  38. package/dist/TokensController.cjs +35 -78
  39. package/dist/TokensController.cjs.map +1 -1
  40. package/dist/TokensController.d.cts +0 -6
  41. package/dist/TokensController.d.cts.map +1 -1
  42. package/dist/TokensController.d.mts +0 -6
  43. package/dist/TokensController.d.mts.map +1 -1
  44. package/dist/TokensController.mjs +36 -78
  45. package/dist/TokensController.mjs.map +1 -1
  46. package/package.json +7 -7
package/CHANGELOG.md CHANGED
@@ -7,6 +7,40 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [56.0.0]
11
+
12
+ ### Changed
13
+
14
+ - Update `TokensController`, `TokenListController`, and `AccountTrackerController` to use per-chain state variants ([#5310](https://github.com/MetaMask/core/pull/5310))
15
+ - Bump `@metamask/keyring-api` to `^17.4.0` ([#5565](https://github.com/MetaMask/core/pull/5565))
16
+ - Bump `@metamask/controller-utils` to `^11.7.0` ([#5583](https://github.com/MetaMask/core/pull/5583))
17
+ - Via this upgrade, `updateExchangeRates` now supports the MegaETH testnet
18
+
19
+ ### Removed
20
+
21
+ - **BREAKING:** Remove deprecated state fields scoped to the current chain ([#5310](https://github.com/MetaMask/core/pull/5310))
22
+ - This change removes the following state fields from the following controllers:
23
+ - `TokensControllerState`
24
+ - `detectedTokens` (replaced by `detectedTokensByChainId`)
25
+ - `ignoredTokens` (replaced by `ignoredTokensByChainId`)
26
+ - `tokens` (replaced by `tokensByChainId`)
27
+ - `TokenListControllerState`
28
+ - `tokenList` (replaced by `tokensChainsCache`)
29
+ - `AccountTrackerControllerState`
30
+ - `accounts` (replaced by `accountsByChainId`)
31
+ - This will require a migration in the clients to remove them from state in order to prevent unnecessary Sentry errors when updating controller state.
32
+
33
+ ### Fixed
34
+
35
+ - Update token rate request key to handle when new tokens are detected inside the `TokenRatesController` ([#5531](https://github.com/MetaMask/core/pull/5311)))
36
+ - Update `CurrencyRateController` to prevent undefined or empty currencies from being queried ([#5458](https://github.com/MetaMask/core/pull/5458)))
37
+
38
+ ## [55.0.1]
39
+
40
+ ### Added
41
+
42
+ - Add an optional chainId argument to `addNftContract` function in NftController ([#5508](https://github.com/MetaMask/core/pull/5508))
43
+
10
44
  ## [55.0.0]
11
45
 
12
46
  ### Changed
@@ -1486,7 +1520,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1486
1520
 
1487
1521
  - Use Ethers for AssetsContractController ([#845](https://github.com/MetaMask/core/pull/845))
1488
1522
 
1489
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@55.0.0...HEAD
1523
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@56.0.0...HEAD
1524
+ [56.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@55.0.1...@metamask/assets-controllers@56.0.0
1525
+ [55.0.1]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@55.0.0...@metamask/assets-controllers@55.0.1
1490
1526
  [55.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@54.0.0...@metamask/assets-controllers@55.0.0
1491
1527
  [54.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@53.1.1...@metamask/assets-controllers@54.0.0
1492
1528
  [53.1.1]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@53.1.0...@metamask/assets-controllers@53.1.1
@@ -13,7 +13,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
13
13
  var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
15
  };
16
- var _AccountTrackerController_instances, _AccountTrackerController_refreshMutex, _AccountTrackerController_includeStakedAssets, _AccountTrackerController_getStakedBalanceForChain, _AccountTrackerController_getCurrentChainId, _AccountTrackerController_getCorrectNetworkClient, _AccountTrackerController_getBalanceFromChain;
16
+ var _AccountTrackerController_instances, _AccountTrackerController_refreshMutex, _AccountTrackerController_includeStakedAssets, _AccountTrackerController_getStakedBalanceForChain, _AccountTrackerController_getCorrectNetworkClient, _AccountTrackerController_getBalanceFromChain;
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.AccountTrackerController = void 0;
19
19
  const controller_utils_1 = require("@metamask/controller-utils");
@@ -27,10 +27,6 @@ const lodash_1 = require("lodash");
27
27
  */
28
28
  const controllerName = 'AccountTrackerController';
29
29
  const accountTrackerMetadata = {
30
- accounts: {
31
- persist: true,
32
- anonymous: false,
33
- },
34
30
  accountsByChainId: {
35
31
  persist: true,
36
32
  anonymous: false,
@@ -57,7 +53,6 @@ class AccountTrackerController extends (0, polling_controller_1.StaticIntervalPo
57
53
  name: controllerName,
58
54
  messenger,
59
55
  state: {
60
- accounts: {},
61
56
  accountsByChainId: {
62
57
  [chainId]: {},
63
58
  },
@@ -78,9 +73,10 @@ class AccountTrackerController extends (0, polling_controller_1.StaticIntervalPo
78
73
  () => this.refresh());
79
74
  }
80
75
  syncAccounts(newChainId) {
81
- const accounts = { ...this.state.accounts };
82
76
  const accountsByChainId = (0, lodash_1.cloneDeep)(this.state.accountsByChainId);
83
- const existing = Object.keys(accounts);
77
+ const { selectedNetworkClientId } = this.messagingSystem.call('NetworkController:getState');
78
+ const { configuration: { chainId: currentChainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', selectedNetworkClientId);
79
+ const existing = Object.keys(accountsByChainId?.[currentChainId] ?? {});
84
80
  if (!accountsByChainId[newChainId]) {
85
81
  accountsByChainId[newChainId] = {};
86
82
  existing.forEach((address) => {
@@ -94,9 +90,6 @@ class AccountTrackerController extends (0, polling_controller_1.StaticIntervalPo
94
90
  .map((internalAccount) => (0, controller_utils_1.toChecksumHexAddress)(internalAccount.address)));
95
91
  const newAddresses = addresses.filter((address) => !existing.includes(address));
96
92
  const oldAddresses = existing.filter((address) => !addresses.includes(address));
97
- newAddresses.forEach((address) => {
98
- accounts[address] = { balance: '0x0' };
99
- });
100
93
  Object.keys(accountsByChainId).forEach((chainId) => {
101
94
  newAddresses.forEach((address) => {
102
95
  accountsByChainId[chainId][address] = {
@@ -104,16 +97,12 @@ class AccountTrackerController extends (0, polling_controller_1.StaticIntervalPo
104
97
  };
105
98
  });
106
99
  });
107
- oldAddresses.forEach((address) => {
108
- delete accounts[address];
109
- });
110
100
  Object.keys(accountsByChainId).forEach((chainId) => {
111
101
  oldAddresses.forEach((address) => {
112
102
  delete accountsByChainId[chainId][address];
113
103
  });
114
104
  });
115
105
  this.update((state) => {
116
- state.accounts = accounts;
117
106
  state.accountsByChainId = accountsByChainId;
118
107
  });
119
108
  }
@@ -141,10 +130,10 @@ class AccountTrackerController extends (0, polling_controller_1.StaticIntervalPo
141
130
  try {
142
131
  const { chainId, ethQuery } = __classPrivateFieldGet(this, _AccountTrackerController_instances, "m", _AccountTrackerController_getCorrectNetworkClient).call(this, networkClientId);
143
132
  this.syncAccounts(chainId);
144
- const { accounts, accountsByChainId } = this.state;
133
+ const { accountsByChainId } = this.state;
145
134
  const { isMultiAccountBalancesEnabled } = this.messagingSystem.call('PreferencesController:getState');
146
135
  const accountsToUpdate = isMultiAccountBalancesEnabled
147
- ? Object.keys(accounts)
136
+ ? Object.keys(accountsByChainId[chainId])
148
137
  : [(0, controller_utils_1.toChecksumHexAddress)(selectedAccount.address)];
149
138
  const accountsForChain = { ...accountsByChainId[chainId] };
150
139
  for (const address of accountsToUpdate) {
@@ -165,9 +154,6 @@ class AccountTrackerController extends (0, polling_controller_1.StaticIntervalPo
165
154
  }
166
155
  }
167
156
  this.update((state) => {
168
- if (chainId === __classPrivateFieldGet(this, _AccountTrackerController_instances, "m", _AccountTrackerController_getCurrentChainId).call(this)) {
169
- state.accounts = accountsForChain;
170
- }
171
157
  state.accountsByChainId[chainId] = accountsForChain;
172
158
  });
173
159
  }
@@ -212,11 +198,7 @@ class AccountTrackerController extends (0, polling_controller_1.StaticIntervalPo
212
198
  }
213
199
  }
214
200
  exports.AccountTrackerController = AccountTrackerController;
215
- _AccountTrackerController_refreshMutex = new WeakMap(), _AccountTrackerController_includeStakedAssets = new WeakMap(), _AccountTrackerController_getStakedBalanceForChain = new WeakMap(), _AccountTrackerController_instances = new WeakSet(), _AccountTrackerController_getCurrentChainId = function _AccountTrackerController_getCurrentChainId() {
216
- const { selectedNetworkClientId } = this.messagingSystem.call('NetworkController:getState');
217
- const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', selectedNetworkClientId);
218
- return chainId;
219
- }, _AccountTrackerController_getCorrectNetworkClient = function _AccountTrackerController_getCorrectNetworkClient(networkClientId) {
201
+ _AccountTrackerController_refreshMutex = new WeakMap(), _AccountTrackerController_includeStakedAssets = new WeakMap(), _AccountTrackerController_getStakedBalanceForChain = new WeakMap(), _AccountTrackerController_instances = new WeakSet(), _AccountTrackerController_getCorrectNetworkClient = function _AccountTrackerController_getCorrectNetworkClient(networkClientId) {
220
202
  const selectedNetworkClientId = networkClientId ??
221
203
  this.messagingSystem.call('NetworkController:getState')
222
204
  .selectedNetworkClientId;
@@ -1 +1 @@
1
- {"version":3,"file":"AccountTrackerController.cjs","sourceRoot":"","sources":["../src/AccountTrackerController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerSelectedEvmAccountChangeEvent,\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerListAccountsAction,\n AccountsControllerSelectedAccountChangeEvent,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n RestrictedMessenger,\n} from '@metamask/base-controller';\nimport {\n query,\n safelyExecuteWithTimeout,\n toChecksumHexAddress,\n} from '@metamask/controller-utils';\nimport EthQuery from '@metamask/eth-query';\nimport type {\n NetworkClientId,\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { PreferencesControllerGetStateAction } from '@metamask/preferences-controller';\nimport { type Hex, assert } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport { cloneDeep } from 'lodash';\n\nimport type {\n AssetsContractController,\n StakedBalance,\n} from './AssetsContractController';\n\n/**\n * The name of the {@link AccountTrackerController}.\n */\nconst controllerName = 'AccountTrackerController';\n\n/**\n * @type AccountInformation\n *\n * Account information object\n * @property balance - Hex string of an account balance in wei\n * @property stakedBalance - Hex string of an account staked balance in wei\n */\nexport type AccountInformation = {\n balance: string;\n stakedBalance?: string;\n};\n\n/**\n * @type AccountTrackerControllerState\n *\n * Account tracker controller state\n * @property accounts - Map of addresses to account information\n */\nexport type AccountTrackerControllerState = {\n accounts: { [address: string]: AccountInformation };\n accountsByChainId: Record<string, { [address: string]: AccountInformation }>;\n};\n\nconst accountTrackerMetadata = {\n accounts: {\n persist: true,\n anonymous: false,\n },\n accountsByChainId: {\n persist: true,\n anonymous: false,\n },\n};\n\n/**\n * The action that can be performed to get the state of the {@link AccountTrackerController}.\n */\nexport type AccountTrackerControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AccountTrackerControllerState\n>;\n\n/**\n * The actions that can be performed using the {@link AccountTrackerController}.\n */\nexport type AccountTrackerControllerActions =\n AccountTrackerControllerGetStateAction;\n\n/**\n * The messenger of the {@link AccountTrackerController} for communication.\n */\nexport type AllowedActions =\n | AccountsControllerListAccountsAction\n | PreferencesControllerGetStateAction\n | AccountsControllerGetSelectedAccountAction\n | NetworkControllerGetStateAction\n | NetworkControllerGetNetworkClientByIdAction;\n\n/**\n * The event that {@link AccountTrackerController} can emit.\n */\nexport type AccountTrackerControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n AccountTrackerControllerState\n >;\n\n/**\n * The events that {@link AccountTrackerController} can emit.\n */\nexport type AccountTrackerControllerEvents =\n AccountTrackerControllerStateChangeEvent;\n\n/**\n * The external events available to the {@link AccountTrackerController}.\n */\nexport type AllowedEvents =\n | AccountsControllerSelectedEvmAccountChangeEvent\n | AccountsControllerSelectedAccountChangeEvent;\n\n/**\n * The messenger of the {@link AccountTrackerController}.\n */\nexport type AccountTrackerControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n AccountTrackerControllerActions | AllowedActions,\n AccountTrackerControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/** The input to start polling for the {@link AccountTrackerController} */\ntype AccountTrackerPollingInput = {\n networkClientId: NetworkClientId;\n};\n\n/**\n * Controller that tracks the network balances for all user accounts.\n */\nexport class AccountTrackerController extends StaticIntervalPollingController<AccountTrackerPollingInput>()<\n typeof controllerName,\n AccountTrackerControllerState,\n AccountTrackerControllerMessenger\n> {\n readonly #refreshMutex = new Mutex();\n\n readonly #includeStakedAssets: boolean;\n\n readonly #getStakedBalanceForChain: AssetsContractController['getStakedBalanceForChain'];\n\n /**\n * Creates an AccountTracker instance.\n *\n * @param options - The controller options.\n * @param options.interval - Polling interval used to fetch new account balances.\n * @param options.state - Initial state to set on this controller.\n * @param options.messenger - The controller messaging system.\n * @param options.getStakedBalanceForChain - The function to get the staked native asset balance for a chain.\n * @param options.includeStakedAssets - Whether to include staked assets in the account balances.\n */\n constructor({\n interval = 10000,\n state,\n messenger,\n getStakedBalanceForChain,\n includeStakedAssets = false,\n }: {\n interval?: number;\n state?: Partial<AccountTrackerControllerState>;\n messenger: AccountTrackerControllerMessenger;\n getStakedBalanceForChain: AssetsContractController['getStakedBalanceForChain'];\n includeStakedAssets?: boolean;\n }) {\n const { selectedNetworkClientId } = messenger.call(\n 'NetworkController:getState',\n );\n const {\n configuration: { chainId },\n } = messenger.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n super({\n name: controllerName,\n messenger,\n state: {\n accounts: {},\n accountsByChainId: {\n [chainId]: {},\n },\n ...state,\n },\n metadata: accountTrackerMetadata,\n });\n this.#getStakedBalanceForChain = getStakedBalanceForChain;\n\n this.#includeStakedAssets = includeStakedAssets;\n\n this.setIntervalLength(interval);\n\n this.messagingSystem.subscribe(\n 'AccountsController:selectedEvmAccountChange',\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n () => this.refresh(),\n );\n }\n\n /**\n * Gets the current chain ID.\n * @returns The current chain ID.\n */\n #getCurrentChainId(): Hex {\n const { selectedNetworkClientId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const {\n configuration: { chainId },\n } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n return chainId;\n }\n\n private syncAccounts(newChainId: string) {\n const accounts = { ...this.state.accounts };\n const accountsByChainId = cloneDeep(this.state.accountsByChainId);\n\n const existing = Object.keys(accounts);\n if (!accountsByChainId[newChainId]) {\n accountsByChainId[newChainId] = {};\n existing.forEach((address) => {\n accountsByChainId[newChainId][address] = { balance: '0x0' };\n });\n }\n\n // Note: The address from the preferences controller are checksummed\n // The addresses from the accounts controller are lowercased\n const addresses = Object.values(\n this.messagingSystem\n .call('AccountsController:listAccounts')\n .map((internalAccount) =>\n toChecksumHexAddress(internalAccount.address),\n ),\n );\n const newAddresses = addresses.filter(\n (address) => !existing.includes(address),\n );\n const oldAddresses = existing.filter(\n (address) => !addresses.includes(address),\n );\n newAddresses.forEach((address) => {\n accounts[address] = { balance: '0x0' };\n });\n Object.keys(accountsByChainId).forEach((chainId) => {\n newAddresses.forEach((address) => {\n accountsByChainId[chainId][address] = {\n balance: '0x0',\n };\n });\n });\n\n oldAddresses.forEach((address) => {\n delete accounts[address];\n });\n Object.keys(accountsByChainId).forEach((chainId) => {\n oldAddresses.forEach((address) => {\n delete accountsByChainId[chainId][address];\n });\n });\n\n this.update((state) => {\n state.accounts = accounts;\n state.accountsByChainId = accountsByChainId;\n });\n }\n\n /**\n * Resolves a networkClientId to a network client config\n * or globally selected network config if not provided\n *\n * @param networkClientId - Optional networkClientId to fetch a network client with\n * @returns network client config\n */\n #getCorrectNetworkClient(networkClientId?: NetworkClientId): {\n chainId: string;\n ethQuery?: EthQuery;\n } {\n const selectedNetworkClientId =\n networkClientId ??\n this.messagingSystem.call('NetworkController:getState')\n .selectedNetworkClientId;\n const {\n configuration: { chainId },\n provider,\n } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n\n return {\n chainId,\n ethQuery: new EthQuery(provider),\n };\n }\n\n /**\n * Refreshes the balances of the accounts using the networkClientId\n *\n * @param input - The input for the poll.\n * @param input.networkClientId - The network client ID used to get balances.\n */\n async _executePoll({\n networkClientId,\n }: AccountTrackerPollingInput): Promise<void> {\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.refresh(networkClientId);\n }\n\n /**\n * Refreshes the balances of the accounts depending on the multi-account setting.\n * If multi-account is disabled, only updates the selected account balance.\n * If multi-account is enabled, updates balances for all accounts.\n *\n * @param networkClientId - Optional networkClientId to fetch a network client with\n */\n async refresh(networkClientId?: NetworkClientId) {\n const selectedAccount = this.messagingSystem.call(\n 'AccountsController:getSelectedAccount',\n );\n const releaseLock = await this.#refreshMutex.acquire();\n try {\n const { chainId, ethQuery } =\n this.#getCorrectNetworkClient(networkClientId);\n this.syncAccounts(chainId);\n const { accounts, accountsByChainId } = this.state;\n const { isMultiAccountBalancesEnabled } = this.messagingSystem.call(\n 'PreferencesController:getState',\n );\n\n const accountsToUpdate = isMultiAccountBalancesEnabled\n ? Object.keys(accounts)\n : [toChecksumHexAddress(selectedAccount.address)];\n\n const accountsForChain = { ...accountsByChainId[chainId] };\n for (const address of accountsToUpdate) {\n const balance = await this.#getBalanceFromChain(address, ethQuery);\n if (balance) {\n accountsForChain[address] = {\n balance,\n };\n }\n if (this.#includeStakedAssets) {\n const stakedBalance = await this.#getStakedBalanceForChain(\n address,\n networkClientId,\n );\n if (stakedBalance) {\n accountsForChain[address] = {\n ...accountsForChain[address],\n stakedBalance,\n };\n }\n }\n }\n\n this.update((state) => {\n if (chainId === this.#getCurrentChainId()) {\n state.accounts = accountsForChain;\n }\n state.accountsByChainId[chainId] = accountsForChain;\n });\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Fetches the balance of a given address from the blockchain.\n *\n * @param address - The account address to fetch the balance for.\n * @param ethQuery - The EthQuery instance to query getBalnce with.\n * @returns A promise that resolves to the balance in a hex string format.\n */\n async #getBalanceFromChain(\n address: string,\n ethQuery?: EthQuery,\n ): Promise<string | undefined> {\n return await safelyExecuteWithTimeout(async () => {\n assert(ethQuery, 'Provider not set.');\n return await query(ethQuery, 'getBalance', [address]);\n });\n }\n\n /**\n * Sync accounts balances with some additional addresses.\n *\n * @param addresses - the additional addresses, may be hardware wallet addresses.\n * @param networkClientId - Optional networkClientId to fetch a network client with.\n * @returns accounts - addresses with synced balance\n */\n async syncBalanceWithAddresses(\n addresses: string[],\n networkClientId?: NetworkClientId,\n ): Promise<\n Record<string, { balance: string; stakedBalance?: StakedBalance }>\n > {\n const { ethQuery } = this.#getCorrectNetworkClient(networkClientId);\n\n return await Promise.all(\n addresses.map(\n (address): Promise<[string, string, StakedBalance] | undefined> => {\n return safelyExecuteWithTimeout(async () => {\n assert(ethQuery, 'Provider not set.');\n const balance = await query(ethQuery, 'getBalance', [address]);\n\n let stakedBalance: StakedBalance;\n if (this.#includeStakedAssets) {\n stakedBalance = await this.#getStakedBalanceForChain(\n address,\n networkClientId,\n );\n }\n return [address, balance, stakedBalance];\n });\n },\n ),\n ).then((value) => {\n return value.reduce((obj, item) => {\n if (!item) {\n return obj;\n }\n\n const [address, balance, stakedBalance] = item;\n return {\n ...obj,\n [address]: {\n balance,\n stakedBalance,\n },\n };\n }, {});\n });\n }\n}\n\nexport default AccountTrackerController;\n"]}
1
+ {"version":3,"file":"AccountTrackerController.cjs","sourceRoot":"","sources":["../src/AccountTrackerController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerSelectedEvmAccountChangeEvent,\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerListAccountsAction,\n AccountsControllerSelectedAccountChangeEvent,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n RestrictedMessenger,\n} from '@metamask/base-controller';\nimport {\n query,\n safelyExecuteWithTimeout,\n toChecksumHexAddress,\n} from '@metamask/controller-utils';\nimport EthQuery from '@metamask/eth-query';\nimport type {\n NetworkClientId,\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { PreferencesControllerGetStateAction } from '@metamask/preferences-controller';\nimport { assert } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport { cloneDeep } from 'lodash';\n\nimport type {\n AssetsContractController,\n StakedBalance,\n} from './AssetsContractController';\n\n/**\n * The name of the {@link AccountTrackerController}.\n */\nconst controllerName = 'AccountTrackerController';\n\n/**\n * @type AccountInformation\n *\n * Account information object\n * @property balance - Hex string of an account balance in wei\n * @property stakedBalance - Hex string of an account staked balance in wei\n */\nexport type AccountInformation = {\n balance: string;\n stakedBalance?: string;\n};\n\n/**\n * @type AccountTrackerControllerState\n *\n * Account tracker controller state\n * @property accountsByChainId - Map of addresses to account information by chain\n */\nexport type AccountTrackerControllerState = {\n accountsByChainId: Record<string, { [address: string]: AccountInformation }>;\n};\n\nconst accountTrackerMetadata = {\n accountsByChainId: {\n persist: true,\n anonymous: false,\n },\n};\n\n/**\n * The action that can be performed to get the state of the {@link AccountTrackerController}.\n */\nexport type AccountTrackerControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AccountTrackerControllerState\n>;\n\n/**\n * The actions that can be performed using the {@link AccountTrackerController}.\n */\nexport type AccountTrackerControllerActions =\n AccountTrackerControllerGetStateAction;\n\n/**\n * The messenger of the {@link AccountTrackerController} for communication.\n */\nexport type AllowedActions =\n | AccountsControllerListAccountsAction\n | PreferencesControllerGetStateAction\n | AccountsControllerGetSelectedAccountAction\n | NetworkControllerGetStateAction\n | NetworkControllerGetNetworkClientByIdAction;\n\n/**\n * The event that {@link AccountTrackerController} can emit.\n */\nexport type AccountTrackerControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n AccountTrackerControllerState\n >;\n\n/**\n * The events that {@link AccountTrackerController} can emit.\n */\nexport type AccountTrackerControllerEvents =\n AccountTrackerControllerStateChangeEvent;\n\n/**\n * The external events available to the {@link AccountTrackerController}.\n */\nexport type AllowedEvents =\n | AccountsControllerSelectedEvmAccountChangeEvent\n | AccountsControllerSelectedAccountChangeEvent;\n\n/**\n * The messenger of the {@link AccountTrackerController}.\n */\nexport type AccountTrackerControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n AccountTrackerControllerActions | AllowedActions,\n AccountTrackerControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/** The input to start polling for the {@link AccountTrackerController} */\ntype AccountTrackerPollingInput = {\n networkClientId: NetworkClientId;\n};\n\n/**\n * Controller that tracks the network balances for all user accounts.\n */\nexport class AccountTrackerController extends StaticIntervalPollingController<AccountTrackerPollingInput>()<\n typeof controllerName,\n AccountTrackerControllerState,\n AccountTrackerControllerMessenger\n> {\n readonly #refreshMutex = new Mutex();\n\n readonly #includeStakedAssets: boolean;\n\n readonly #getStakedBalanceForChain: AssetsContractController['getStakedBalanceForChain'];\n\n /**\n * Creates an AccountTracker instance.\n *\n * @param options - The controller options.\n * @param options.interval - Polling interval used to fetch new account balances.\n * @param options.state - Initial state to set on this controller.\n * @param options.messenger - The controller messaging system.\n * @param options.getStakedBalanceForChain - The function to get the staked native asset balance for a chain.\n * @param options.includeStakedAssets - Whether to include staked assets in the account balances.\n */\n constructor({\n interval = 10000,\n state,\n messenger,\n getStakedBalanceForChain,\n includeStakedAssets = false,\n }: {\n interval?: number;\n state?: Partial<AccountTrackerControllerState>;\n messenger: AccountTrackerControllerMessenger;\n getStakedBalanceForChain: AssetsContractController['getStakedBalanceForChain'];\n includeStakedAssets?: boolean;\n }) {\n const { selectedNetworkClientId } = messenger.call(\n 'NetworkController:getState',\n );\n const {\n configuration: { chainId },\n } = messenger.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n super({\n name: controllerName,\n messenger,\n state: {\n accountsByChainId: {\n [chainId]: {},\n },\n ...state,\n },\n metadata: accountTrackerMetadata,\n });\n this.#getStakedBalanceForChain = getStakedBalanceForChain;\n\n this.#includeStakedAssets = includeStakedAssets;\n\n this.setIntervalLength(interval);\n\n this.messagingSystem.subscribe(\n 'AccountsController:selectedEvmAccountChange',\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n () => this.refresh(),\n );\n }\n\n private syncAccounts(newChainId: string) {\n const accountsByChainId = cloneDeep(this.state.accountsByChainId);\n const { selectedNetworkClientId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const {\n configuration: { chainId: currentChainId },\n } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n\n const existing = Object.keys(accountsByChainId?.[currentChainId] ?? {});\n\n if (!accountsByChainId[newChainId]) {\n accountsByChainId[newChainId] = {};\n existing.forEach((address) => {\n accountsByChainId[newChainId][address] = { balance: '0x0' };\n });\n }\n\n // Note: The address from the preferences controller are checksummed\n // The addresses from the accounts controller are lowercased\n const addresses = Object.values(\n this.messagingSystem\n .call('AccountsController:listAccounts')\n .map((internalAccount) =>\n toChecksumHexAddress(internalAccount.address),\n ),\n );\n const newAddresses = addresses.filter(\n (address) => !existing.includes(address),\n );\n const oldAddresses = existing.filter(\n (address) => !addresses.includes(address),\n );\n Object.keys(accountsByChainId).forEach((chainId) => {\n newAddresses.forEach((address) => {\n accountsByChainId[chainId][address] = {\n balance: '0x0',\n };\n });\n });\n\n Object.keys(accountsByChainId).forEach((chainId) => {\n oldAddresses.forEach((address) => {\n delete accountsByChainId[chainId][address];\n });\n });\n\n this.update((state) => {\n state.accountsByChainId = accountsByChainId;\n });\n }\n\n /**\n * Resolves a networkClientId to a network client config\n * or globally selected network config if not provided\n *\n * @param networkClientId - Optional networkClientId to fetch a network client with\n * @returns network client config\n */\n #getCorrectNetworkClient(networkClientId?: NetworkClientId): {\n chainId: string;\n ethQuery?: EthQuery;\n } {\n const selectedNetworkClientId =\n networkClientId ??\n this.messagingSystem.call('NetworkController:getState')\n .selectedNetworkClientId;\n const {\n configuration: { chainId },\n provider,\n } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n\n return {\n chainId,\n ethQuery: new EthQuery(provider),\n };\n }\n\n /**\n * Refreshes the balances of the accounts using the networkClientId\n *\n * @param input - The input for the poll.\n * @param input.networkClientId - The network client ID used to get balances.\n */\n async _executePoll({\n networkClientId,\n }: AccountTrackerPollingInput): Promise<void> {\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.refresh(networkClientId);\n }\n\n /**\n * Refreshes the balances of the accounts depending on the multi-account setting.\n * If multi-account is disabled, only updates the selected account balance.\n * If multi-account is enabled, updates balances for all accounts.\n *\n * @param networkClientId - Optional networkClientId to fetch a network client with\n */\n async refresh(networkClientId?: NetworkClientId) {\n const selectedAccount = this.messagingSystem.call(\n 'AccountsController:getSelectedAccount',\n );\n const releaseLock = await this.#refreshMutex.acquire();\n try {\n const { chainId, ethQuery } =\n this.#getCorrectNetworkClient(networkClientId);\n this.syncAccounts(chainId);\n const { accountsByChainId } = this.state;\n const { isMultiAccountBalancesEnabled } = this.messagingSystem.call(\n 'PreferencesController:getState',\n );\n\n const accountsToUpdate = isMultiAccountBalancesEnabled\n ? Object.keys(accountsByChainId[chainId])\n : [toChecksumHexAddress(selectedAccount.address)];\n\n const accountsForChain = { ...accountsByChainId[chainId] };\n for (const address of accountsToUpdate) {\n const balance = await this.#getBalanceFromChain(address, ethQuery);\n if (balance) {\n accountsForChain[address] = {\n balance,\n };\n }\n if (this.#includeStakedAssets) {\n const stakedBalance = await this.#getStakedBalanceForChain(\n address,\n networkClientId,\n );\n if (stakedBalance) {\n accountsForChain[address] = {\n ...accountsForChain[address],\n stakedBalance,\n };\n }\n }\n }\n\n this.update((state) => {\n state.accountsByChainId[chainId] = accountsForChain;\n });\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Fetches the balance of a given address from the blockchain.\n *\n * @param address - The account address to fetch the balance for.\n * @param ethQuery - The EthQuery instance to query getBalnce with.\n * @returns A promise that resolves to the balance in a hex string format.\n */\n async #getBalanceFromChain(\n address: string,\n ethQuery?: EthQuery,\n ): Promise<string | undefined> {\n return await safelyExecuteWithTimeout(async () => {\n assert(ethQuery, 'Provider not set.');\n return await query(ethQuery, 'getBalance', [address]);\n });\n }\n\n /**\n * Sync accounts balances with some additional addresses.\n *\n * @param addresses - the additional addresses, may be hardware wallet addresses.\n * @param networkClientId - Optional networkClientId to fetch a network client with.\n * @returns accounts - addresses with synced balance\n */\n async syncBalanceWithAddresses(\n addresses: string[],\n networkClientId?: NetworkClientId,\n ): Promise<\n Record<string, { balance: string; stakedBalance?: StakedBalance }>\n > {\n const { ethQuery } = this.#getCorrectNetworkClient(networkClientId);\n\n return await Promise.all(\n addresses.map(\n (address): Promise<[string, string, StakedBalance] | undefined> => {\n return safelyExecuteWithTimeout(async () => {\n assert(ethQuery, 'Provider not set.');\n const balance = await query(ethQuery, 'getBalance', [address]);\n\n let stakedBalance: StakedBalance;\n if (this.#includeStakedAssets) {\n stakedBalance = await this.#getStakedBalanceForChain(\n address,\n networkClientId,\n );\n }\n return [address, balance, stakedBalance];\n });\n },\n ),\n ).then((value) => {\n return value.reduce((obj, item) => {\n if (!item) {\n return obj;\n }\n\n const [address, balance, stakedBalance] = item;\n return {\n ...obj,\n [address]: {\n balance,\n stakedBalance,\n },\n };\n }, {});\n });\n }\n}\n\nexport default AccountTrackerController;\n"]}
@@ -22,12 +22,9 @@ export type AccountInformation = {
22
22
  * @type AccountTrackerControllerState
23
23
  *
24
24
  * Account tracker controller state
25
- * @property accounts - Map of addresses to account information
25
+ * @property accountsByChainId - Map of addresses to account information by chain
26
26
  */
27
27
  export type AccountTrackerControllerState = {
28
- accounts: {
29
- [address: string]: AccountInformation;
30
- };
31
28
  accountsByChainId: Record<string, {
32
29
  [address: string]: AccountInformation;
33
30
  }>;
@@ -69,12 +66,7 @@ declare const AccountTrackerController_base: (abstract new (...args: any[]) => {
69
66
  "__#14@#intervalLength": number | undefined;
70
67
  setIntervalLength(intervalLength: number): void;
71
68
  getIntervalLength(): number | undefined;
72
- _startPolling(input: AccountTrackerPollingInput): void; /**
73
- * @type AccountTrackerControllerState
74
- *
75
- * Account tracker controller state
76
- * @property accounts - Map of addresses to account information
77
- */
69
+ _startPolling(input: AccountTrackerPollingInput): void;
78
70
  _stopPollingByPollingTokenSetId(key: string): void;
79
71
  readonly "__#3@#pollingTokenSets": Map<string, Set<string>>;
80
72
  "__#3@#callbacks": Map<string, Set<(input: AccountTrackerPollingInput) => void>>;
@@ -82,6 +74,9 @@ declare const AccountTrackerController_base: (abstract new (...args: any[]) => {
82
74
  startPolling(input: AccountTrackerPollingInput): string;
83
75
  stopAllPolling(): void;
84
76
  stopPollingByPollingToken(pollingToken: string): void;
77
+ /**
78
+ * The action that can be performed to get the state of the {@link AccountTrackerController}.
79
+ */
85
80
  onPollingComplete(input: AccountTrackerPollingInput, callback: (input: AccountTrackerPollingInput) => void): void;
86
81
  }) & typeof import("@metamask/base-controller").BaseController;
87
82
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"AccountTrackerController.d.cts","sourceRoot":"","sources":["../src/AccountTrackerController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AccountTrackerController.d.cts","sourceRoot":"","sources":["../src/AccountTrackerController.ts"],"names":[],"mappings":"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"}
@@ -22,12 +22,9 @@ export type AccountInformation = {
22
22
  * @type AccountTrackerControllerState
23
23
  *
24
24
  * Account tracker controller state
25
- * @property accounts - Map of addresses to account information
25
+ * @property accountsByChainId - Map of addresses to account information by chain
26
26
  */
27
27
  export type AccountTrackerControllerState = {
28
- accounts: {
29
- [address: string]: AccountInformation;
30
- };
31
28
  accountsByChainId: Record<string, {
32
29
  [address: string]: AccountInformation;
33
30
  }>;
@@ -69,12 +66,7 @@ declare const AccountTrackerController_base: (abstract new (...args: any[]) => {
69
66
  "__#14@#intervalLength": number | undefined;
70
67
  setIntervalLength(intervalLength: number): void;
71
68
  getIntervalLength(): number | undefined;
72
- _startPolling(input: AccountTrackerPollingInput): void; /**
73
- * @type AccountTrackerControllerState
74
- *
75
- * Account tracker controller state
76
- * @property accounts - Map of addresses to account information
77
- */
69
+ _startPolling(input: AccountTrackerPollingInput): void;
78
70
  _stopPollingByPollingTokenSetId(key: string): void;
79
71
  readonly "__#3@#pollingTokenSets": Map<string, Set<string>>;
80
72
  "__#3@#callbacks": Map<string, Set<(input: AccountTrackerPollingInput) => void>>;
@@ -82,6 +74,9 @@ declare const AccountTrackerController_base: (abstract new (...args: any[]) => {
82
74
  startPolling(input: AccountTrackerPollingInput): string;
83
75
  stopAllPolling(): void;
84
76
  stopPollingByPollingToken(pollingToken: string): void;
77
+ /**
78
+ * The action that can be performed to get the state of the {@link AccountTrackerController}.
79
+ */
85
80
  onPollingComplete(input: AccountTrackerPollingInput, callback: (input: AccountTrackerPollingInput) => void): void;
86
81
  }) & typeof import("@metamask/base-controller").BaseController;
87
82
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"AccountTrackerController.d.mts","sourceRoot":"","sources":["../src/AccountTrackerController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AccountTrackerController.d.mts","sourceRoot":"","sources":["../src/AccountTrackerController.ts"],"names":[],"mappings":"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"}
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _AccountTrackerController_instances, _AccountTrackerController_refreshMutex, _AccountTrackerController_includeStakedAssets, _AccountTrackerController_getStakedBalanceForChain, _AccountTrackerController_getCurrentChainId, _AccountTrackerController_getCorrectNetworkClient, _AccountTrackerController_getBalanceFromChain;
12
+ var _AccountTrackerController_instances, _AccountTrackerController_refreshMutex, _AccountTrackerController_includeStakedAssets, _AccountTrackerController_getStakedBalanceForChain, _AccountTrackerController_getCorrectNetworkClient, _AccountTrackerController_getBalanceFromChain;
13
13
  function $importDefault(module) {
14
14
  if (module?.__esModule) {
15
15
  return module.default;
@@ -29,10 +29,6 @@ const { cloneDeep } = $lodash;
29
29
  */
30
30
  const controllerName = 'AccountTrackerController';
31
31
  const accountTrackerMetadata = {
32
- accounts: {
33
- persist: true,
34
- anonymous: false,
35
- },
36
32
  accountsByChainId: {
37
33
  persist: true,
38
34
  anonymous: false,
@@ -59,7 +55,6 @@ export class AccountTrackerController extends StaticIntervalPollingController()
59
55
  name: controllerName,
60
56
  messenger,
61
57
  state: {
62
- accounts: {},
63
58
  accountsByChainId: {
64
59
  [chainId]: {},
65
60
  },
@@ -80,9 +75,10 @@ export class AccountTrackerController extends StaticIntervalPollingController()
80
75
  () => this.refresh());
81
76
  }
82
77
  syncAccounts(newChainId) {
83
- const accounts = { ...this.state.accounts };
84
78
  const accountsByChainId = cloneDeep(this.state.accountsByChainId);
85
- const existing = Object.keys(accounts);
79
+ const { selectedNetworkClientId } = this.messagingSystem.call('NetworkController:getState');
80
+ const { configuration: { chainId: currentChainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', selectedNetworkClientId);
81
+ const existing = Object.keys(accountsByChainId?.[currentChainId] ?? {});
86
82
  if (!accountsByChainId[newChainId]) {
87
83
  accountsByChainId[newChainId] = {};
88
84
  existing.forEach((address) => {
@@ -96,9 +92,6 @@ export class AccountTrackerController extends StaticIntervalPollingController()
96
92
  .map((internalAccount) => toChecksumHexAddress(internalAccount.address)));
97
93
  const newAddresses = addresses.filter((address) => !existing.includes(address));
98
94
  const oldAddresses = existing.filter((address) => !addresses.includes(address));
99
- newAddresses.forEach((address) => {
100
- accounts[address] = { balance: '0x0' };
101
- });
102
95
  Object.keys(accountsByChainId).forEach((chainId) => {
103
96
  newAddresses.forEach((address) => {
104
97
  accountsByChainId[chainId][address] = {
@@ -106,16 +99,12 @@ export class AccountTrackerController extends StaticIntervalPollingController()
106
99
  };
107
100
  });
108
101
  });
109
- oldAddresses.forEach((address) => {
110
- delete accounts[address];
111
- });
112
102
  Object.keys(accountsByChainId).forEach((chainId) => {
113
103
  oldAddresses.forEach((address) => {
114
104
  delete accountsByChainId[chainId][address];
115
105
  });
116
106
  });
117
107
  this.update((state) => {
118
- state.accounts = accounts;
119
108
  state.accountsByChainId = accountsByChainId;
120
109
  });
121
110
  }
@@ -143,10 +132,10 @@ export class AccountTrackerController extends StaticIntervalPollingController()
143
132
  try {
144
133
  const { chainId, ethQuery } = __classPrivateFieldGet(this, _AccountTrackerController_instances, "m", _AccountTrackerController_getCorrectNetworkClient).call(this, networkClientId);
145
134
  this.syncAccounts(chainId);
146
- const { accounts, accountsByChainId } = this.state;
135
+ const { accountsByChainId } = this.state;
147
136
  const { isMultiAccountBalancesEnabled } = this.messagingSystem.call('PreferencesController:getState');
148
137
  const accountsToUpdate = isMultiAccountBalancesEnabled
149
- ? Object.keys(accounts)
138
+ ? Object.keys(accountsByChainId[chainId])
150
139
  : [toChecksumHexAddress(selectedAccount.address)];
151
140
  const accountsForChain = { ...accountsByChainId[chainId] };
152
141
  for (const address of accountsToUpdate) {
@@ -167,9 +156,6 @@ export class AccountTrackerController extends StaticIntervalPollingController()
167
156
  }
168
157
  }
169
158
  this.update((state) => {
170
- if (chainId === __classPrivateFieldGet(this, _AccountTrackerController_instances, "m", _AccountTrackerController_getCurrentChainId).call(this)) {
171
- state.accounts = accountsForChain;
172
- }
173
159
  state.accountsByChainId[chainId] = accountsForChain;
174
160
  });
175
161
  }
@@ -213,11 +199,7 @@ export class AccountTrackerController extends StaticIntervalPollingController()
213
199
  });
214
200
  }
215
201
  }
216
- _AccountTrackerController_refreshMutex = new WeakMap(), _AccountTrackerController_includeStakedAssets = new WeakMap(), _AccountTrackerController_getStakedBalanceForChain = new WeakMap(), _AccountTrackerController_instances = new WeakSet(), _AccountTrackerController_getCurrentChainId = function _AccountTrackerController_getCurrentChainId() {
217
- const { selectedNetworkClientId } = this.messagingSystem.call('NetworkController:getState');
218
- const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', selectedNetworkClientId);
219
- return chainId;
220
- }, _AccountTrackerController_getCorrectNetworkClient = function _AccountTrackerController_getCorrectNetworkClient(networkClientId) {
202
+ _AccountTrackerController_refreshMutex = new WeakMap(), _AccountTrackerController_includeStakedAssets = new WeakMap(), _AccountTrackerController_getStakedBalanceForChain = new WeakMap(), _AccountTrackerController_instances = new WeakSet(), _AccountTrackerController_getCorrectNetworkClient = function _AccountTrackerController_getCorrectNetworkClient(networkClientId) {
221
203
  const selectedNetworkClientId = networkClientId ??
222
204
  this.messagingSystem.call('NetworkController:getState')
223
205
  .selectedNetworkClientId;
@@ -1 +1 @@
1
- {"version":3,"file":"AccountTrackerController.mjs","sourceRoot":"","sources":["../src/AccountTrackerController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerSelectedEvmAccountChangeEvent,\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerListAccountsAction,\n AccountsControllerSelectedAccountChangeEvent,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n RestrictedMessenger,\n} from '@metamask/base-controller';\nimport {\n query,\n safelyExecuteWithTimeout,\n toChecksumHexAddress,\n} from '@metamask/controller-utils';\nimport EthQuery from '@metamask/eth-query';\nimport type {\n NetworkClientId,\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { PreferencesControllerGetStateAction } from '@metamask/preferences-controller';\nimport { type Hex, assert } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport { cloneDeep } from 'lodash';\n\nimport type {\n AssetsContractController,\n StakedBalance,\n} from './AssetsContractController';\n\n/**\n * The name of the {@link AccountTrackerController}.\n */\nconst controllerName = 'AccountTrackerController';\n\n/**\n * @type AccountInformation\n *\n * Account information object\n * @property balance - Hex string of an account balance in wei\n * @property stakedBalance - Hex string of an account staked balance in wei\n */\nexport type AccountInformation = {\n balance: string;\n stakedBalance?: string;\n};\n\n/**\n * @type AccountTrackerControllerState\n *\n * Account tracker controller state\n * @property accounts - Map of addresses to account information\n */\nexport type AccountTrackerControllerState = {\n accounts: { [address: string]: AccountInformation };\n accountsByChainId: Record<string, { [address: string]: AccountInformation }>;\n};\n\nconst accountTrackerMetadata = {\n accounts: {\n persist: true,\n anonymous: false,\n },\n accountsByChainId: {\n persist: true,\n anonymous: false,\n },\n};\n\n/**\n * The action that can be performed to get the state of the {@link AccountTrackerController}.\n */\nexport type AccountTrackerControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AccountTrackerControllerState\n>;\n\n/**\n * The actions that can be performed using the {@link AccountTrackerController}.\n */\nexport type AccountTrackerControllerActions =\n AccountTrackerControllerGetStateAction;\n\n/**\n * The messenger of the {@link AccountTrackerController} for communication.\n */\nexport type AllowedActions =\n | AccountsControllerListAccountsAction\n | PreferencesControllerGetStateAction\n | AccountsControllerGetSelectedAccountAction\n | NetworkControllerGetStateAction\n | NetworkControllerGetNetworkClientByIdAction;\n\n/**\n * The event that {@link AccountTrackerController} can emit.\n */\nexport type AccountTrackerControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n AccountTrackerControllerState\n >;\n\n/**\n * The events that {@link AccountTrackerController} can emit.\n */\nexport type AccountTrackerControllerEvents =\n AccountTrackerControllerStateChangeEvent;\n\n/**\n * The external events available to the {@link AccountTrackerController}.\n */\nexport type AllowedEvents =\n | AccountsControllerSelectedEvmAccountChangeEvent\n | AccountsControllerSelectedAccountChangeEvent;\n\n/**\n * The messenger of the {@link AccountTrackerController}.\n */\nexport type AccountTrackerControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n AccountTrackerControllerActions | AllowedActions,\n AccountTrackerControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/** The input to start polling for the {@link AccountTrackerController} */\ntype AccountTrackerPollingInput = {\n networkClientId: NetworkClientId;\n};\n\n/**\n * Controller that tracks the network balances for all user accounts.\n */\nexport class AccountTrackerController extends StaticIntervalPollingController<AccountTrackerPollingInput>()<\n typeof controllerName,\n AccountTrackerControllerState,\n AccountTrackerControllerMessenger\n> {\n readonly #refreshMutex = new Mutex();\n\n readonly #includeStakedAssets: boolean;\n\n readonly #getStakedBalanceForChain: AssetsContractController['getStakedBalanceForChain'];\n\n /**\n * Creates an AccountTracker instance.\n *\n * @param options - The controller options.\n * @param options.interval - Polling interval used to fetch new account balances.\n * @param options.state - Initial state to set on this controller.\n * @param options.messenger - The controller messaging system.\n * @param options.getStakedBalanceForChain - The function to get the staked native asset balance for a chain.\n * @param options.includeStakedAssets - Whether to include staked assets in the account balances.\n */\n constructor({\n interval = 10000,\n state,\n messenger,\n getStakedBalanceForChain,\n includeStakedAssets = false,\n }: {\n interval?: number;\n state?: Partial<AccountTrackerControllerState>;\n messenger: AccountTrackerControllerMessenger;\n getStakedBalanceForChain: AssetsContractController['getStakedBalanceForChain'];\n includeStakedAssets?: boolean;\n }) {\n const { selectedNetworkClientId } = messenger.call(\n 'NetworkController:getState',\n );\n const {\n configuration: { chainId },\n } = messenger.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n super({\n name: controllerName,\n messenger,\n state: {\n accounts: {},\n accountsByChainId: {\n [chainId]: {},\n },\n ...state,\n },\n metadata: accountTrackerMetadata,\n });\n this.#getStakedBalanceForChain = getStakedBalanceForChain;\n\n this.#includeStakedAssets = includeStakedAssets;\n\n this.setIntervalLength(interval);\n\n this.messagingSystem.subscribe(\n 'AccountsController:selectedEvmAccountChange',\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n () => this.refresh(),\n );\n }\n\n /**\n * Gets the current chain ID.\n * @returns The current chain ID.\n */\n #getCurrentChainId(): Hex {\n const { selectedNetworkClientId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const {\n configuration: { chainId },\n } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n return chainId;\n }\n\n private syncAccounts(newChainId: string) {\n const accounts = { ...this.state.accounts };\n const accountsByChainId = cloneDeep(this.state.accountsByChainId);\n\n const existing = Object.keys(accounts);\n if (!accountsByChainId[newChainId]) {\n accountsByChainId[newChainId] = {};\n existing.forEach((address) => {\n accountsByChainId[newChainId][address] = { balance: '0x0' };\n });\n }\n\n // Note: The address from the preferences controller are checksummed\n // The addresses from the accounts controller are lowercased\n const addresses = Object.values(\n this.messagingSystem\n .call('AccountsController:listAccounts')\n .map((internalAccount) =>\n toChecksumHexAddress(internalAccount.address),\n ),\n );\n const newAddresses = addresses.filter(\n (address) => !existing.includes(address),\n );\n const oldAddresses = existing.filter(\n (address) => !addresses.includes(address),\n );\n newAddresses.forEach((address) => {\n accounts[address] = { balance: '0x0' };\n });\n Object.keys(accountsByChainId).forEach((chainId) => {\n newAddresses.forEach((address) => {\n accountsByChainId[chainId][address] = {\n balance: '0x0',\n };\n });\n });\n\n oldAddresses.forEach((address) => {\n delete accounts[address];\n });\n Object.keys(accountsByChainId).forEach((chainId) => {\n oldAddresses.forEach((address) => {\n delete accountsByChainId[chainId][address];\n });\n });\n\n this.update((state) => {\n state.accounts = accounts;\n state.accountsByChainId = accountsByChainId;\n });\n }\n\n /**\n * Resolves a networkClientId to a network client config\n * or globally selected network config if not provided\n *\n * @param networkClientId - Optional networkClientId to fetch a network client with\n * @returns network client config\n */\n #getCorrectNetworkClient(networkClientId?: NetworkClientId): {\n chainId: string;\n ethQuery?: EthQuery;\n } {\n const selectedNetworkClientId =\n networkClientId ??\n this.messagingSystem.call('NetworkController:getState')\n .selectedNetworkClientId;\n const {\n configuration: { chainId },\n provider,\n } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n\n return {\n chainId,\n ethQuery: new EthQuery(provider),\n };\n }\n\n /**\n * Refreshes the balances of the accounts using the networkClientId\n *\n * @param input - The input for the poll.\n * @param input.networkClientId - The network client ID used to get balances.\n */\n async _executePoll({\n networkClientId,\n }: AccountTrackerPollingInput): Promise<void> {\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.refresh(networkClientId);\n }\n\n /**\n * Refreshes the balances of the accounts depending on the multi-account setting.\n * If multi-account is disabled, only updates the selected account balance.\n * If multi-account is enabled, updates balances for all accounts.\n *\n * @param networkClientId - Optional networkClientId to fetch a network client with\n */\n async refresh(networkClientId?: NetworkClientId) {\n const selectedAccount = this.messagingSystem.call(\n 'AccountsController:getSelectedAccount',\n );\n const releaseLock = await this.#refreshMutex.acquire();\n try {\n const { chainId, ethQuery } =\n this.#getCorrectNetworkClient(networkClientId);\n this.syncAccounts(chainId);\n const { accounts, accountsByChainId } = this.state;\n const { isMultiAccountBalancesEnabled } = this.messagingSystem.call(\n 'PreferencesController:getState',\n );\n\n const accountsToUpdate = isMultiAccountBalancesEnabled\n ? Object.keys(accounts)\n : [toChecksumHexAddress(selectedAccount.address)];\n\n const accountsForChain = { ...accountsByChainId[chainId] };\n for (const address of accountsToUpdate) {\n const balance = await this.#getBalanceFromChain(address, ethQuery);\n if (balance) {\n accountsForChain[address] = {\n balance,\n };\n }\n if (this.#includeStakedAssets) {\n const stakedBalance = await this.#getStakedBalanceForChain(\n address,\n networkClientId,\n );\n if (stakedBalance) {\n accountsForChain[address] = {\n ...accountsForChain[address],\n stakedBalance,\n };\n }\n }\n }\n\n this.update((state) => {\n if (chainId === this.#getCurrentChainId()) {\n state.accounts = accountsForChain;\n }\n state.accountsByChainId[chainId] = accountsForChain;\n });\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Fetches the balance of a given address from the blockchain.\n *\n * @param address - The account address to fetch the balance for.\n * @param ethQuery - The EthQuery instance to query getBalnce with.\n * @returns A promise that resolves to the balance in a hex string format.\n */\n async #getBalanceFromChain(\n address: string,\n ethQuery?: EthQuery,\n ): Promise<string | undefined> {\n return await safelyExecuteWithTimeout(async () => {\n assert(ethQuery, 'Provider not set.');\n return await query(ethQuery, 'getBalance', [address]);\n });\n }\n\n /**\n * Sync accounts balances with some additional addresses.\n *\n * @param addresses - the additional addresses, may be hardware wallet addresses.\n * @param networkClientId - Optional networkClientId to fetch a network client with.\n * @returns accounts - addresses with synced balance\n */\n async syncBalanceWithAddresses(\n addresses: string[],\n networkClientId?: NetworkClientId,\n ): Promise<\n Record<string, { balance: string; stakedBalance?: StakedBalance }>\n > {\n const { ethQuery } = this.#getCorrectNetworkClient(networkClientId);\n\n return await Promise.all(\n addresses.map(\n (address): Promise<[string, string, StakedBalance] | undefined> => {\n return safelyExecuteWithTimeout(async () => {\n assert(ethQuery, 'Provider not set.');\n const balance = await query(ethQuery, 'getBalance', [address]);\n\n let stakedBalance: StakedBalance;\n if (this.#includeStakedAssets) {\n stakedBalance = await this.#getStakedBalanceForChain(\n address,\n networkClientId,\n );\n }\n return [address, balance, stakedBalance];\n });\n },\n ),\n ).then((value) => {\n return value.reduce((obj, item) => {\n if (!item) {\n return obj;\n }\n\n const [address, balance, stakedBalance] = item;\n return {\n ...obj,\n [address]: {\n balance,\n stakedBalance,\n },\n };\n }, {});\n });\n }\n}\n\nexport default AccountTrackerController;\n"]}
1
+ {"version":3,"file":"AccountTrackerController.mjs","sourceRoot":"","sources":["../src/AccountTrackerController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerSelectedEvmAccountChangeEvent,\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerListAccountsAction,\n AccountsControllerSelectedAccountChangeEvent,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n RestrictedMessenger,\n} from '@metamask/base-controller';\nimport {\n query,\n safelyExecuteWithTimeout,\n toChecksumHexAddress,\n} from '@metamask/controller-utils';\nimport EthQuery from '@metamask/eth-query';\nimport type {\n NetworkClientId,\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { PreferencesControllerGetStateAction } from '@metamask/preferences-controller';\nimport { assert } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport { cloneDeep } from 'lodash';\n\nimport type {\n AssetsContractController,\n StakedBalance,\n} from './AssetsContractController';\n\n/**\n * The name of the {@link AccountTrackerController}.\n */\nconst controllerName = 'AccountTrackerController';\n\n/**\n * @type AccountInformation\n *\n * Account information object\n * @property balance - Hex string of an account balance in wei\n * @property stakedBalance - Hex string of an account staked balance in wei\n */\nexport type AccountInformation = {\n balance: string;\n stakedBalance?: string;\n};\n\n/**\n * @type AccountTrackerControllerState\n *\n * Account tracker controller state\n * @property accountsByChainId - Map of addresses to account information by chain\n */\nexport type AccountTrackerControllerState = {\n accountsByChainId: Record<string, { [address: string]: AccountInformation }>;\n};\n\nconst accountTrackerMetadata = {\n accountsByChainId: {\n persist: true,\n anonymous: false,\n },\n};\n\n/**\n * The action that can be performed to get the state of the {@link AccountTrackerController}.\n */\nexport type AccountTrackerControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AccountTrackerControllerState\n>;\n\n/**\n * The actions that can be performed using the {@link AccountTrackerController}.\n */\nexport type AccountTrackerControllerActions =\n AccountTrackerControllerGetStateAction;\n\n/**\n * The messenger of the {@link AccountTrackerController} for communication.\n */\nexport type AllowedActions =\n | AccountsControllerListAccountsAction\n | PreferencesControllerGetStateAction\n | AccountsControllerGetSelectedAccountAction\n | NetworkControllerGetStateAction\n | NetworkControllerGetNetworkClientByIdAction;\n\n/**\n * The event that {@link AccountTrackerController} can emit.\n */\nexport type AccountTrackerControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n AccountTrackerControllerState\n >;\n\n/**\n * The events that {@link AccountTrackerController} can emit.\n */\nexport type AccountTrackerControllerEvents =\n AccountTrackerControllerStateChangeEvent;\n\n/**\n * The external events available to the {@link AccountTrackerController}.\n */\nexport type AllowedEvents =\n | AccountsControllerSelectedEvmAccountChangeEvent\n | AccountsControllerSelectedAccountChangeEvent;\n\n/**\n * The messenger of the {@link AccountTrackerController}.\n */\nexport type AccountTrackerControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n AccountTrackerControllerActions | AllowedActions,\n AccountTrackerControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/** The input to start polling for the {@link AccountTrackerController} */\ntype AccountTrackerPollingInput = {\n networkClientId: NetworkClientId;\n};\n\n/**\n * Controller that tracks the network balances for all user accounts.\n */\nexport class AccountTrackerController extends StaticIntervalPollingController<AccountTrackerPollingInput>()<\n typeof controllerName,\n AccountTrackerControllerState,\n AccountTrackerControllerMessenger\n> {\n readonly #refreshMutex = new Mutex();\n\n readonly #includeStakedAssets: boolean;\n\n readonly #getStakedBalanceForChain: AssetsContractController['getStakedBalanceForChain'];\n\n /**\n * Creates an AccountTracker instance.\n *\n * @param options - The controller options.\n * @param options.interval - Polling interval used to fetch new account balances.\n * @param options.state - Initial state to set on this controller.\n * @param options.messenger - The controller messaging system.\n * @param options.getStakedBalanceForChain - The function to get the staked native asset balance for a chain.\n * @param options.includeStakedAssets - Whether to include staked assets in the account balances.\n */\n constructor({\n interval = 10000,\n state,\n messenger,\n getStakedBalanceForChain,\n includeStakedAssets = false,\n }: {\n interval?: number;\n state?: Partial<AccountTrackerControllerState>;\n messenger: AccountTrackerControllerMessenger;\n getStakedBalanceForChain: AssetsContractController['getStakedBalanceForChain'];\n includeStakedAssets?: boolean;\n }) {\n const { selectedNetworkClientId } = messenger.call(\n 'NetworkController:getState',\n );\n const {\n configuration: { chainId },\n } = messenger.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n super({\n name: controllerName,\n messenger,\n state: {\n accountsByChainId: {\n [chainId]: {},\n },\n ...state,\n },\n metadata: accountTrackerMetadata,\n });\n this.#getStakedBalanceForChain = getStakedBalanceForChain;\n\n this.#includeStakedAssets = includeStakedAssets;\n\n this.setIntervalLength(interval);\n\n this.messagingSystem.subscribe(\n 'AccountsController:selectedEvmAccountChange',\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n () => this.refresh(),\n );\n }\n\n private syncAccounts(newChainId: string) {\n const accountsByChainId = cloneDeep(this.state.accountsByChainId);\n const { selectedNetworkClientId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const {\n configuration: { chainId: currentChainId },\n } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n\n const existing = Object.keys(accountsByChainId?.[currentChainId] ?? {});\n\n if (!accountsByChainId[newChainId]) {\n accountsByChainId[newChainId] = {};\n existing.forEach((address) => {\n accountsByChainId[newChainId][address] = { balance: '0x0' };\n });\n }\n\n // Note: The address from the preferences controller are checksummed\n // The addresses from the accounts controller are lowercased\n const addresses = Object.values(\n this.messagingSystem\n .call('AccountsController:listAccounts')\n .map((internalAccount) =>\n toChecksumHexAddress(internalAccount.address),\n ),\n );\n const newAddresses = addresses.filter(\n (address) => !existing.includes(address),\n );\n const oldAddresses = existing.filter(\n (address) => !addresses.includes(address),\n );\n Object.keys(accountsByChainId).forEach((chainId) => {\n newAddresses.forEach((address) => {\n accountsByChainId[chainId][address] = {\n balance: '0x0',\n };\n });\n });\n\n Object.keys(accountsByChainId).forEach((chainId) => {\n oldAddresses.forEach((address) => {\n delete accountsByChainId[chainId][address];\n });\n });\n\n this.update((state) => {\n state.accountsByChainId = accountsByChainId;\n });\n }\n\n /**\n * Resolves a networkClientId to a network client config\n * or globally selected network config if not provided\n *\n * @param networkClientId - Optional networkClientId to fetch a network client with\n * @returns network client config\n */\n #getCorrectNetworkClient(networkClientId?: NetworkClientId): {\n chainId: string;\n ethQuery?: EthQuery;\n } {\n const selectedNetworkClientId =\n networkClientId ??\n this.messagingSystem.call('NetworkController:getState')\n .selectedNetworkClientId;\n const {\n configuration: { chainId },\n provider,\n } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n\n return {\n chainId,\n ethQuery: new EthQuery(provider),\n };\n }\n\n /**\n * Refreshes the balances of the accounts using the networkClientId\n *\n * @param input - The input for the poll.\n * @param input.networkClientId - The network client ID used to get balances.\n */\n async _executePoll({\n networkClientId,\n }: AccountTrackerPollingInput): Promise<void> {\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.refresh(networkClientId);\n }\n\n /**\n * Refreshes the balances of the accounts depending on the multi-account setting.\n * If multi-account is disabled, only updates the selected account balance.\n * If multi-account is enabled, updates balances for all accounts.\n *\n * @param networkClientId - Optional networkClientId to fetch a network client with\n */\n async refresh(networkClientId?: NetworkClientId) {\n const selectedAccount = this.messagingSystem.call(\n 'AccountsController:getSelectedAccount',\n );\n const releaseLock = await this.#refreshMutex.acquire();\n try {\n const { chainId, ethQuery } =\n this.#getCorrectNetworkClient(networkClientId);\n this.syncAccounts(chainId);\n const { accountsByChainId } = this.state;\n const { isMultiAccountBalancesEnabled } = this.messagingSystem.call(\n 'PreferencesController:getState',\n );\n\n const accountsToUpdate = isMultiAccountBalancesEnabled\n ? Object.keys(accountsByChainId[chainId])\n : [toChecksumHexAddress(selectedAccount.address)];\n\n const accountsForChain = { ...accountsByChainId[chainId] };\n for (const address of accountsToUpdate) {\n const balance = await this.#getBalanceFromChain(address, ethQuery);\n if (balance) {\n accountsForChain[address] = {\n balance,\n };\n }\n if (this.#includeStakedAssets) {\n const stakedBalance = await this.#getStakedBalanceForChain(\n address,\n networkClientId,\n );\n if (stakedBalance) {\n accountsForChain[address] = {\n ...accountsForChain[address],\n stakedBalance,\n };\n }\n }\n }\n\n this.update((state) => {\n state.accountsByChainId[chainId] = accountsForChain;\n });\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Fetches the balance of a given address from the blockchain.\n *\n * @param address - The account address to fetch the balance for.\n * @param ethQuery - The EthQuery instance to query getBalnce with.\n * @returns A promise that resolves to the balance in a hex string format.\n */\n async #getBalanceFromChain(\n address: string,\n ethQuery?: EthQuery,\n ): Promise<string | undefined> {\n return await safelyExecuteWithTimeout(async () => {\n assert(ethQuery, 'Provider not set.');\n return await query(ethQuery, 'getBalance', [address]);\n });\n }\n\n /**\n * Sync accounts balances with some additional addresses.\n *\n * @param addresses - the additional addresses, may be hardware wallet addresses.\n * @param networkClientId - Optional networkClientId to fetch a network client with.\n * @returns accounts - addresses with synced balance\n */\n async syncBalanceWithAddresses(\n addresses: string[],\n networkClientId?: NetworkClientId,\n ): Promise<\n Record<string, { balance: string; stakedBalance?: StakedBalance }>\n > {\n const { ethQuery } = this.#getCorrectNetworkClient(networkClientId);\n\n return await Promise.all(\n addresses.map(\n (address): Promise<[string, string, StakedBalance] | undefined> => {\n return safelyExecuteWithTimeout(async () => {\n assert(ethQuery, 'Provider not set.');\n const balance = await query(ethQuery, 'getBalance', [address]);\n\n let stakedBalance: StakedBalance;\n if (this.#includeStakedAssets) {\n stakedBalance = await this.#getStakedBalanceForChain(\n address,\n networkClientId,\n );\n }\n return [address, balance, stakedBalance];\n });\n },\n ),\n ).then((value) => {\n return value.reduce((obj, item) => {\n if (!item) {\n return obj;\n }\n\n const [address, balance, stakedBalance] = item;\n return {\n ...obj,\n [address]: {\n balance,\n stakedBalance,\n },\n };\n }, {});\n });\n }\n}\n\nexport default AccountTrackerController;\n"]}
@@ -83,6 +83,9 @@ class CurrencyRateController extends (0, polling_controller_1.StaticIntervalPoll
83
83
  // Map each native currency to the symbol we want to fetch for it.
84
84
  const testnetSymbols = Object.values(controller_utils_1.TESTNET_TICKER_SYMBOLS);
85
85
  const nativeCurrenciesToFetch = nativeCurrencies.reduce((acc, nativeCurrency) => {
86
+ if (!nativeCurrency) {
87
+ return acc;
88
+ }
86
89
  acc[nativeCurrency] = testnetSymbols.includes(nativeCurrency)
87
90
  ? controller_utils_1.FALL_BACK_VS_CURRENCY
88
91
  : nativeCurrency;