@metamask-previews/assets-controllers 41.0.0-preview-db2c53b → 42.0.0-preview-651fe366

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,10 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [42.0.0]
11
+
10
12
  ### Added
11
13
 
12
14
  - Add `resetState` method to `NftController`, `TokensController`, `TokenBalancesController` and `TokenRatesController` to reset the controller's state back to their default state ([#4880](https://github.com/MetaMask/core/pull/4880))
13
15
 
16
+ ### Changed
17
+
18
+ - **BREAKING**: A `platform` argument must now be passed to the `TokenDetectionController` constructor, indicating whether the platform is extension or mobile. ([#4877](https://github.com/MetaMask/core/pull/4877))
19
+ - **BREAKING**: The `TokenRatesController` now accepts `{chainId: Hex}` as its polling input to `startPolling()` instead of `{networkClientId: NetworkClientId}` ([#4887](https://github.com/MetaMask/core/pull/4887))
20
+ - When the `TokenRatesController`'s subscription to `TokensController:stateChange` is fired, token prices are now updated across all chain IDs whose tokens changed, instead of just the current chain. ([#4866](https://github.com/MetaMask/core/pull/4866))
21
+ - The `TokenDetectionController` now passes a `x-metamask-clientproduct` header when calling the account API. ([#4877](https://github.com/MetaMask/core/pull/4877))
22
+
14
23
  ## [41.0.0]
15
24
 
16
25
  ### Changed
@@ -1180,7 +1189,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1180
1189
 
1181
1190
  - Use Ethers for AssetsContractController ([#845](https://github.com/MetaMask/core/pull/845))
1182
1191
 
1183
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@41.0.0...HEAD
1192
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@42.0.0...HEAD
1193
+ [42.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@41.0.0...@metamask/assets-controllers@42.0.0
1184
1194
  [41.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@40.0.0...@metamask/assets-controllers@41.0.0
1185
1195
  [40.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@39.0.0...@metamask/assets-controllers@40.0.0
1186
1196
  [39.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@38.3.0...@metamask/assets-controllers@39.0.0
@@ -1,24 +1,29 @@
1
1
  "use strict";
2
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
+ 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");
5
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
+ };
2
7
  var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
8
  if (kind === "m") throw new TypeError("Private method is not writable");
4
9
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
10
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
11
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
12
  };
8
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
- 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");
11
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
- };
13
- var _TokenBalancesController_handle, _TokenBalancesController_interval, _TokenBalancesController_tokens, _TokenBalancesController_disabled;
13
+ var _TokenBalancesController_instances, _TokenBalancesController_queryMultipleAccounts, _TokenBalancesController_allTokens, _TokenBalancesController_allDetectedTokens, _TokenBalancesController_calculateQueryMultipleAccounts, _TokenBalancesController_onPreferencesStateChange, _TokenBalancesController_onTokensStateChange, _TokenBalancesController_getChainIds, _TokenBalancesController_getNetworkClient;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.TokenBalancesController = exports.getDefaultTokenBalancesState = void 0;
16
- const base_controller_1 = require("@metamask/base-controller");
16
+ const contracts_1 = require("@ethersproject/contracts");
17
+ const providers_1 = require("@ethersproject/providers");
17
18
  const controller_utils_1 = require("@metamask/controller-utils");
19
+ const metamask_eth_abis_1 = require("@metamask/metamask-eth-abis");
20
+ const polling_controller_1 = require("@metamask/polling-controller");
21
+ const lodash_1 = require("lodash");
22
+ const multicall_1 = require("./multicall.cjs");
18
23
  const DEFAULT_INTERVAL = 180000;
19
24
  const controllerName = 'TokenBalancesController';
20
25
  const metadata = {
21
- contractBalances: { persist: true, anonymous: false },
26
+ tokenBalances: { persist: true, anonymous: false },
22
27
  };
23
28
  /**
24
29
  * Get the default TokenBalancesController state.
@@ -27,7 +32,7 @@ const metadata = {
27
32
  */
28
33
  function getDefaultTokenBalancesState() {
29
34
  return {
30
- contractBalances: {},
35
+ tokenBalances: {},
31
36
  };
32
37
  }
33
38
  exports.getDefaultTokenBalancesState = getDefaultTokenBalancesState;
@@ -35,18 +40,17 @@ exports.getDefaultTokenBalancesState = getDefaultTokenBalancesState;
35
40
  * Controller that passively polls on a set interval token balances
36
41
  * for tokens stored in the TokensController
37
42
  */
38
- class TokenBalancesController extends base_controller_1.BaseController {
43
+ class TokenBalancesController extends (0, polling_controller_1.StaticIntervalPollingController)() {
39
44
  /**
40
45
  * Construct a Token Balances Controller.
41
46
  *
42
47
  * @param options - The controller options.
43
48
  * @param options.interval - Polling interval used to fetch new token balances.
44
- * @param options.tokens - List of tokens to track balances for.
45
- * @param options.disabled - If set to true, all tracked tokens contract balances updates are blocked.
46
49
  * @param options.state - Initial state to set on this controller.
47
50
  * @param options.messenger - The controller restricted messenger.
48
51
  */
49
- constructor({ interval = DEFAULT_INTERVAL, tokens = [], disabled = false, messenger, state = {}, }) {
52
+ constructor({ interval = DEFAULT_INTERVAL, messenger, state = {}, }) {
53
+ var _a, _b;
50
54
  super({
51
55
  name: controllerName,
52
56
  metadata,
@@ -56,79 +60,97 @@ class TokenBalancesController extends base_controller_1.BaseController {
56
60
  ...state,
57
61
  },
58
62
  });
59
- _TokenBalancesController_handle.set(this, void 0);
60
- _TokenBalancesController_interval.set(this, void 0);
61
- _TokenBalancesController_tokens.set(this, void 0);
62
- _TokenBalancesController_disabled.set(this, void 0);
63
- __classPrivateFieldSet(this, _TokenBalancesController_disabled, disabled, "f");
64
- __classPrivateFieldSet(this, _TokenBalancesController_interval, interval, "f");
65
- __classPrivateFieldSet(this, _TokenBalancesController_tokens, tokens, "f");
66
- this.messagingSystem.subscribe('TokensController:stateChange', ({ tokens: newTokens, detectedTokens }) => {
67
- __classPrivateFieldSet(this, _TokenBalancesController_tokens, [...newTokens, ...detectedTokens], "f");
68
- // TODO: Either fix this lint violation or explain why it's necessary to ignore.
69
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
70
- this.updateBalances();
63
+ _TokenBalancesController_instances.add(this);
64
+ _TokenBalancesController_queryMultipleAccounts.set(this, void 0);
65
+ _TokenBalancesController_allTokens.set(this, void 0);
66
+ _TokenBalancesController_allDetectedTokens.set(this, void 0);
67
+ // Determines whether to query all accounts, or just the selected account
68
+ _TokenBalancesController_calculateQueryMultipleAccounts.set(this, ({ isMultiAccountBalancesEnabled, useMultiAccountBalanceChecker, }) => {
69
+ return Boolean(
70
+ // Note: These settings have different names on extension vs mobile
71
+ isMultiAccountBalancesEnabled || useMultiAccountBalanceChecker);
71
72
  });
72
- // TODO: Either fix this lint violation or explain why it's necessary to ignore.
73
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
74
- this.poll();
75
- }
76
- /**
77
- * Allows controller to update tracked tokens contract balances.
78
- */
79
- enable() {
80
- __classPrivateFieldSet(this, _TokenBalancesController_disabled, false, "f");
81
- }
82
- /**
83
- * Blocks controller from updating tracked tokens contract balances.
84
- */
85
- disable() {
86
- __classPrivateFieldSet(this, _TokenBalancesController_disabled, true, "f");
87
- }
88
- /**
89
- * Starts a new polling interval.
90
- *
91
- * @param interval - Polling interval used to fetch new token balances.
92
- */
93
- async poll(interval) {
94
- if (interval) {
95
- __classPrivateFieldSet(this, _TokenBalancesController_interval, interval, "f");
96
- }
97
- if (__classPrivateFieldGet(this, _TokenBalancesController_handle, "f")) {
98
- clearTimeout(__classPrivateFieldGet(this, _TokenBalancesController_handle, "f"));
99
- }
100
- await (0, controller_utils_1.safelyExecute)(() => this.updateBalances());
101
- __classPrivateFieldSet(this, _TokenBalancesController_handle, setTimeout(() => {
102
- // TODO: Either fix this lint violation or explain why it's necessary to ignore.
103
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
104
- this.poll(__classPrivateFieldGet(this, _TokenBalancesController_interval, "f"));
105
- }, __classPrivateFieldGet(this, _TokenBalancesController_interval, "f")), "f");
73
+ // Updates the user preference for whether to query multiple accounts
74
+ _TokenBalancesController_onPreferencesStateChange.set(this, async (preferences) => {
75
+ const queryMultipleAccounts = __classPrivateFieldGet(this, _TokenBalancesController_calculateQueryMultipleAccounts, "f").call(this, preferences);
76
+ // Refresh when flipped off -> on
77
+ const refresh = queryMultipleAccounts && !__classPrivateFieldGet(this, _TokenBalancesController_queryMultipleAccounts, "f");
78
+ __classPrivateFieldSet(this, _TokenBalancesController_queryMultipleAccounts, queryMultipleAccounts, "f");
79
+ if (refresh) {
80
+ await Promise.allSettled(__classPrivateFieldGet(this, _TokenBalancesController_getChainIds, "f").call(this, __classPrivateFieldGet(this, _TokenBalancesController_allTokens, "f"), __classPrivateFieldGet(this, _TokenBalancesController_allDetectedTokens, "f")).map(async (chainId) => this._executePoll({ chainId })));
81
+ }
82
+ });
83
+ // Refreshes token balances on chains whose tokens have changed
84
+ _TokenBalancesController_onTokensStateChange.set(this, async ({ allTokens, allDetectedTokens, }) => {
85
+ const chainIds = __classPrivateFieldGet(this, _TokenBalancesController_getChainIds, "f").call(this, allTokens, allDetectedTokens);
86
+ const chainIdsToUpdate = chainIds.filter((chainId) => !(0, lodash_1.isEqual)(__classPrivateFieldGet(this, _TokenBalancesController_allTokens, "f")[chainId], allTokens[chainId]) ||
87
+ !(0, lodash_1.isEqual)(__classPrivateFieldGet(this, _TokenBalancesController_allDetectedTokens, "f")[chainId], allDetectedTokens[chainId]));
88
+ __classPrivateFieldSet(this, _TokenBalancesController_allTokens, allTokens, "f");
89
+ __classPrivateFieldSet(this, _TokenBalancesController_allDetectedTokens, allDetectedTokens, "f");
90
+ await Promise.allSettled(chainIdsToUpdate.map(async (chainId) => this._executePoll({ chainId })));
91
+ });
92
+ // Returns an array of chain ids that have tokens
93
+ _TokenBalancesController_getChainIds.set(this, (allTokens, allDetectedTokens) => [
94
+ ...new Set([
95
+ ...Object.keys(allTokens),
96
+ ...Object.keys(allDetectedTokens),
97
+ ]),
98
+ ]);
99
+ this.setIntervalLength(interval);
100
+ // Set initial preference, and subscribe to changes
101
+ __classPrivateFieldSet(this, _TokenBalancesController_queryMultipleAccounts, __classPrivateFieldGet(this, _TokenBalancesController_calculateQueryMultipleAccounts, "f").call(this, this.messagingSystem.call('PreferencesController:getState')), "f");
102
+ this.messagingSystem.subscribe('PreferencesController:stateChange',
103
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
104
+ __classPrivateFieldGet(this, _TokenBalancesController_onPreferencesStateChange, "f").bind(this));
105
+ // Set initial tokens, and subscribe to changes
106
+ (_a = this, _b = this, {
107
+ allTokens: ({ set value(_c) { __classPrivateFieldSet(_a, _TokenBalancesController_allTokens, _c, "f"); } }).value,
108
+ allDetectedTokens: ({ set value(_c) { __classPrivateFieldSet(_b, _TokenBalancesController_allDetectedTokens, _c, "f"); } }).value,
109
+ } = this.messagingSystem.call('TokensController:getState'));
110
+ this.messagingSystem.subscribe('TokensController:stateChange',
111
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
112
+ __classPrivateFieldGet(this, _TokenBalancesController_onTokensStateChange, "f").bind(this));
106
113
  }
107
114
  /**
108
- * Updates balances for all tokens.
115
+ * Polls for erc20 token balances.
116
+ * @param input - The input for the poll.
117
+ * @param input.chainId - The chain id to poll token balances on.
109
118
  */
110
- async updateBalances() {
111
- if (__classPrivateFieldGet(this, _TokenBalancesController_disabled, "f")) {
119
+ async _executePoll({ chainId }) {
120
+ const { address: selectedAccountAddress } = this.messagingSystem.call('AccountsController:getSelectedAccount');
121
+ const isSelectedAccount = (accountAddress) => (0, controller_utils_1.toChecksumHexAddress)(accountAddress) ===
122
+ (0, controller_utils_1.toChecksumHexAddress)(selectedAccountAddress);
123
+ const accountTokenPairs = [];
124
+ const addTokens = ([accountAddress, tokens]) => __classPrivateFieldGet(this, _TokenBalancesController_queryMultipleAccounts, "f") || isSelectedAccount(accountAddress)
125
+ ? tokens.forEach((t) => accountTokenPairs.push({
126
+ accountAddress: accountAddress,
127
+ tokenAddress: t.address,
128
+ }))
129
+ : undefined;
130
+ Object.entries(__classPrivateFieldGet(this, _TokenBalancesController_allTokens, "f")[chainId] ?? {}).forEach(addTokens);
131
+ Object.entries(__classPrivateFieldGet(this, _TokenBalancesController_allDetectedTokens, "f")[chainId] ?? {}).forEach(addTokens);
132
+ if (accountTokenPairs.length === 0) {
112
133
  return;
113
134
  }
114
- const selectedInternalAccount = this.messagingSystem.call('AccountsController:getSelectedAccount');
115
- const newContractBalances = {};
116
- for (const token of __classPrivateFieldGet(this, _TokenBalancesController_tokens, "f")) {
117
- const { address } = token;
118
- try {
119
- const balance = await this.messagingSystem.call('AssetsContractController:getERC20BalanceOf', address, selectedInternalAccount.address);
120
- newContractBalances[address] = (0, controller_utils_1.toHex)(balance);
121
- token.hasBalanceError = false;
122
- }
123
- catch (error) {
124
- newContractBalances[address] = (0, controller_utils_1.toHex)(0);
125
- token.hasBalanceError = true;
126
- }
127
- }
135
+ const provider = new providers_1.Web3Provider(__classPrivateFieldGet(this, _TokenBalancesController_instances, "m", _TokenBalancesController_getNetworkClient).call(this, chainId).provider);
136
+ const calls = accountTokenPairs.map(({ accountAddress, tokenAddress }) => ({
137
+ contract: new contracts_1.Contract(tokenAddress, metamask_eth_abis_1.abiERC20, provider),
138
+ functionSignature: 'balanceOf(address)',
139
+ arguments: [accountAddress],
140
+ }));
141
+ const results = await (0, multicall_1.multicallOrFallback)(calls, chainId, provider);
128
142
  this.update((state) => {
129
- state.contractBalances = newContractBalances;
143
+ var _a, _b;
144
+ for (let i = 0; i < results.length; i++) {
145
+ const { success, value } = results[i];
146
+ if (success) {
147
+ const { accountAddress, tokenAddress } = accountTokenPairs[i];
148
+ ((_b = ((_a = state.tokenBalances)[accountAddress] ?? (_a[accountAddress] = {})))[chainId] ?? (_b[chainId] = {}))[tokenAddress] = (0, controller_utils_1.toHex)(value);
149
+ }
150
+ }
130
151
  });
131
152
  }
153
+ // TODO: needed?
132
154
  /**
133
155
  * Reset the controller state to the default state.
134
156
  */
@@ -139,6 +161,14 @@ class TokenBalancesController extends base_controller_1.BaseController {
139
161
  }
140
162
  }
141
163
  exports.TokenBalancesController = TokenBalancesController;
142
- _TokenBalancesController_handle = new WeakMap(), _TokenBalancesController_interval = new WeakMap(), _TokenBalancesController_tokens = new WeakMap(), _TokenBalancesController_disabled = new WeakMap();
164
+ _TokenBalancesController_queryMultipleAccounts = new WeakMap(), _TokenBalancesController_allTokens = new WeakMap(), _TokenBalancesController_allDetectedTokens = new WeakMap(), _TokenBalancesController_calculateQueryMultipleAccounts = new WeakMap(), _TokenBalancesController_onPreferencesStateChange = new WeakMap(), _TokenBalancesController_onTokensStateChange = new WeakMap(), _TokenBalancesController_getChainIds = new WeakMap(), _TokenBalancesController_instances = new WeakSet(), _TokenBalancesController_getNetworkClient = function _TokenBalancesController_getNetworkClient(chainId) {
165
+ const { networkConfigurationsByChainId } = this.messagingSystem.call('NetworkController:getState');
166
+ const networkConfiguration = networkConfigurationsByChainId[chainId];
167
+ if (!networkConfiguration) {
168
+ throw new Error(`TokenBalancesController: No network configuration found for chainId ${chainId}`);
169
+ }
170
+ const { networkClientId } = networkConfiguration.rpcEndpoints[networkConfiguration.defaultRpcEndpointIndex];
171
+ return this.messagingSystem.call(`NetworkController:getNetworkClientById`, networkClientId);
172
+ };
143
173
  exports.default = TokenBalancesController;
144
174
  //# sourceMappingURL=TokenBalancesController.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"TokenBalancesController.cjs","sourceRoot":"","sources":["../src/TokenBalancesController.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccountsControllerGetSelectedAccountAction } from '@metamask/accounts-controller';\nimport type {\n RestrictedControllerMessenger,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport { safelyExecute, toHex } from '@metamask/controller-utils';\n\nimport type { AssetsContractControllerGetERC20BalanceOfAction } from './AssetsContractController';\nimport type { Token } from './TokenRatesController';\nimport type { TokensControllerStateChangeEvent } from './TokensController';\n\nconst DEFAULT_INTERVAL = 180000;\n\nconst controllerName = 'TokenBalancesController';\n\nconst metadata = {\n contractBalances: { persist: true, anonymous: false },\n};\n\n/**\n * Token balances controller options\n * @property interval - Polling interval used to fetch new token balances.\n * @property tokens - List of tokens to track balances for.\n * @property disabled - If set to true, all tracked tokens contract balances updates are blocked.\n */\ntype TokenBalancesControllerOptions = {\n interval?: number;\n tokens?: Token[];\n disabled?: boolean;\n messenger: TokenBalancesControllerMessenger;\n state?: Partial<TokenBalancesControllerState>;\n};\n\n/**\n * Represents a mapping of hash token contract addresses to their balances.\n */\ntype ContractBalances = Record<string, string>;\n\n/**\n * Token balances controller state\n * @property contractBalances - Hash of token contract addresses to balances\n */\nexport type TokenBalancesControllerState = {\n contractBalances: ContractBalances;\n};\n\nexport type TokenBalancesControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n TokenBalancesControllerState\n>;\n\nexport type TokenBalancesControllerActions =\n TokenBalancesControllerGetStateAction;\n\nexport type AllowedActions =\n | AccountsControllerGetSelectedAccountAction\n | AssetsContractControllerGetERC20BalanceOfAction;\n\nexport type TokenBalancesControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n TokenBalancesControllerState\n >;\n\nexport type TokenBalancesControllerEvents =\n TokenBalancesControllerStateChangeEvent;\n\nexport type AllowedEvents = TokensControllerStateChangeEvent;\n\nexport type TokenBalancesControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n TokenBalancesControllerActions | AllowedActions,\n TokenBalancesControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * Get the default TokenBalancesController state.\n *\n * @returns The default TokenBalancesController state.\n */\nexport function getDefaultTokenBalancesState(): TokenBalancesControllerState {\n return {\n contractBalances: {},\n };\n}\n\n/**\n * Controller that passively polls on a set interval token balances\n * for tokens stored in the TokensController\n */\nexport class TokenBalancesController extends BaseController<\n typeof controllerName,\n TokenBalancesControllerState,\n TokenBalancesControllerMessenger\n> {\n #handle?: ReturnType<typeof setTimeout>;\n\n #interval: number;\n\n #tokens: Token[];\n\n #disabled: boolean;\n\n /**\n * Construct a Token Balances Controller.\n *\n * @param options - The controller options.\n * @param options.interval - Polling interval used to fetch new token balances.\n * @param options.tokens - List of tokens to track balances for.\n * @param options.disabled - If set to true, all tracked tokens contract balances updates are blocked.\n * @param options.state - Initial state to set on this controller.\n * @param options.messenger - The controller restricted messenger.\n */\n constructor({\n interval = DEFAULT_INTERVAL,\n tokens = [],\n disabled = false,\n messenger,\n state = {},\n }: TokenBalancesControllerOptions) {\n super({\n name: controllerName,\n metadata,\n messenger,\n state: {\n ...getDefaultTokenBalancesState(),\n ...state,\n },\n });\n\n this.#disabled = disabled;\n this.#interval = interval;\n this.#tokens = tokens;\n\n this.messagingSystem.subscribe(\n 'TokensController:stateChange',\n ({ tokens: newTokens, detectedTokens }) => {\n this.#tokens = [...newTokens, ...detectedTokens];\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.updateBalances();\n },\n );\n\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.poll();\n }\n\n /**\n * Allows controller to update tracked tokens contract balances.\n */\n enable() {\n this.#disabled = false;\n }\n\n /**\n * Blocks controller from updating tracked tokens contract balances.\n */\n disable() {\n this.#disabled = true;\n }\n\n /**\n * Starts a new polling interval.\n *\n * @param interval - Polling interval used to fetch new token balances.\n */\n async poll(interval?: number): Promise<void> {\n if (interval) {\n this.#interval = interval;\n }\n\n if (this.#handle) {\n clearTimeout(this.#handle);\n }\n\n await safelyExecute(() => this.updateBalances());\n\n this.#handle = setTimeout(() => {\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.poll(this.#interval);\n }, this.#interval);\n }\n\n /**\n * Updates balances for all tokens.\n */\n async updateBalances() {\n if (this.#disabled) {\n return;\n }\n const selectedInternalAccount = this.messagingSystem.call(\n 'AccountsController:getSelectedAccount',\n );\n\n const newContractBalances: ContractBalances = {};\n for (const token of this.#tokens) {\n const { address } = token;\n try {\n const balance = await this.messagingSystem.call(\n 'AssetsContractController:getERC20BalanceOf',\n address,\n selectedInternalAccount.address,\n );\n newContractBalances[address] = toHex(balance);\n token.hasBalanceError = false;\n } catch (error) {\n newContractBalances[address] = toHex(0);\n token.hasBalanceError = true;\n }\n }\n\n this.update((state) => {\n state.contractBalances = newContractBalances;\n });\n }\n\n /**\n * Reset the controller state to the default state.\n */\n resetState() {\n this.update(() => {\n return getDefaultTokenBalancesState();\n });\n }\n}\n\nexport default TokenBalancesController;\n"]}
1
+ {"version":3,"file":"TokenBalancesController.cjs","sourceRoot":"","sources":["../src/TokenBalancesController.ts"],"names":[],"mappings":"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","sourcesContent":["import { Contract } from '@ethersproject/contracts';\nimport { Web3Provider } from '@ethersproject/providers';\nimport type { AccountsControllerGetSelectedAccountAction } from '@metamask/accounts-controller';\nimport type {\n RestrictedControllerMessenger,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport { toChecksumHexAddress, toHex } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport type {\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type {\n PreferencesControllerGetStateAction,\n PreferencesControllerStateChangeEvent,\n PreferencesState,\n} from '@metamask/preferences-controller';\nimport type { Hex } from '@metamask/utils';\nimport type BN from 'bn.js';\nimport { isEqual } from 'lodash';\n\nimport { multicallOrFallback } from './multicall';\nimport type { Token } from './TokenRatesController';\nimport type {\n TokensControllerGetStateAction,\n TokensControllerState,\n TokensControllerStateChangeEvent,\n} from './TokensController';\n\nconst DEFAULT_INTERVAL = 180000;\n\nconst controllerName = 'TokenBalancesController';\n\nconst metadata = {\n tokenBalances: { persist: true, anonymous: false },\n};\n\n/**\n * Token balances controller options\n * @property interval - Polling interval used to fetch new token balances.\n * @property messenger - A controller messenger.\n * @property state - Initial state for the controller.\n */\ntype TokenBalancesControllerOptions = {\n interval?: number;\n messenger: TokenBalancesControllerMessenger;\n state?: Partial<TokenBalancesControllerState>;\n};\n\n/**\n * A mapping from account address to chain id to token address to balance.\n */\ntype TokenBalances = Record<Hex, Record<Hex, Record<Hex, Hex>>>;\n\n/**\n * Token balances controller state\n * @property tokenBalances - A mapping from account address to chain id to token address to balance.\n */\nexport type TokenBalancesControllerState = {\n tokenBalances: TokenBalances;\n};\n\nexport type TokenBalancesControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n TokenBalancesControllerState\n>;\n\nexport type TokenBalancesControllerActions =\n TokenBalancesControllerGetStateAction;\n\nexport type AllowedActions =\n | NetworkControllerGetNetworkClientByIdAction\n | NetworkControllerGetStateAction\n | TokensControllerGetStateAction\n | PreferencesControllerGetStateAction\n | AccountsControllerGetSelectedAccountAction;\n\nexport type TokenBalancesControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n TokenBalancesControllerState\n >;\n\nexport type TokenBalancesControllerEvents =\n TokenBalancesControllerStateChangeEvent;\n\nexport type AllowedEvents =\n | TokensControllerStateChangeEvent\n | PreferencesControllerStateChangeEvent;\n\nexport type TokenBalancesControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n TokenBalancesControllerActions | AllowedActions,\n TokenBalancesControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * Get the default TokenBalancesController state.\n *\n * @returns The default TokenBalancesController state.\n */\nexport function getDefaultTokenBalancesState(): TokenBalancesControllerState {\n return {\n tokenBalances: {},\n };\n}\n\n/** The input to start polling for the {@link TokenBalancesController} */\nexport type TokenBalancesPollingInput = {\n chainId: Hex;\n};\n\n/**\n * Controller that passively polls on a set interval token balances\n * for tokens stored in the TokensController\n */\nexport class TokenBalancesController extends StaticIntervalPollingController<TokenBalancesPollingInput>()<\n typeof controllerName,\n TokenBalancesControllerState,\n TokenBalancesControllerMessenger\n> {\n #queryMultipleAccounts: boolean;\n\n #allTokens: TokensControllerState['allTokens'];\n\n #allDetectedTokens: TokensControllerState['allDetectedTokens'];\n\n /**\n * Construct a Token Balances Controller.\n *\n * @param options - The controller options.\n * @param options.interval - Polling interval used to fetch new token balances.\n * @param options.state - Initial state to set on this controller.\n * @param options.messenger - The controller restricted messenger.\n */\n constructor({\n interval = DEFAULT_INTERVAL,\n messenger,\n state = {},\n }: TokenBalancesControllerOptions) {\n super({\n name: controllerName,\n metadata,\n messenger,\n state: {\n ...getDefaultTokenBalancesState(),\n ...state,\n },\n });\n\n this.setIntervalLength(interval);\n\n // Set initial preference, and subscribe to changes\n this.#queryMultipleAccounts = this.#calculateQueryMultipleAccounts(\n this.messagingSystem.call('PreferencesController:getState'),\n );\n this.messagingSystem.subscribe(\n 'PreferencesController:stateChange',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#onPreferencesStateChange.bind(this),\n );\n\n // Set initial tokens, and subscribe to changes\n ({\n allTokens: this.#allTokens,\n allDetectedTokens: this.#allDetectedTokens,\n } = this.messagingSystem.call('TokensController:getState'));\n\n this.messagingSystem.subscribe(\n 'TokensController:stateChange',\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#onTokensStateChange.bind(this),\n );\n }\n\n // Determines whether to query all accounts, or just the selected account\n #calculateQueryMultipleAccounts = ({\n isMultiAccountBalancesEnabled,\n useMultiAccountBalanceChecker,\n }: PreferencesState & { useMultiAccountBalanceChecker?: boolean }) => {\n return Boolean(\n // Note: These settings have different names on extension vs mobile\n isMultiAccountBalancesEnabled || useMultiAccountBalanceChecker,\n );\n };\n\n // Updates the user preference for whether to query multiple accounts\n #onPreferencesStateChange = async (preferences: PreferencesState) => {\n const queryMultipleAccounts =\n this.#calculateQueryMultipleAccounts(preferences);\n\n // Refresh when flipped off -> on\n const refresh = queryMultipleAccounts && !this.#queryMultipleAccounts;\n this.#queryMultipleAccounts = queryMultipleAccounts;\n\n if (refresh) {\n await Promise.allSettled(\n this.#getChainIds(this.#allTokens, this.#allDetectedTokens).map(\n async (chainId) => this._executePoll({ chainId }),\n ),\n );\n }\n };\n\n // Refreshes token balances on chains whose tokens have changed\n #onTokensStateChange = async ({\n allTokens,\n allDetectedTokens,\n }: TokensControllerState) => {\n const chainIds = this.#getChainIds(allTokens, allDetectedTokens);\n const chainIdsToUpdate = chainIds.filter(\n (chainId) =>\n !isEqual(this.#allTokens[chainId], allTokens[chainId]) ||\n !isEqual(this.#allDetectedTokens[chainId], allDetectedTokens[chainId]),\n );\n\n this.#allTokens = allTokens;\n this.#allDetectedTokens = allDetectedTokens;\n\n await Promise.allSettled(\n chainIdsToUpdate.map(async (chainId) => this._executePoll({ chainId })),\n );\n };\n\n // Returns an array of chain ids that have tokens\n #getChainIds = (\n allTokens: TokensControllerState['allTokens'],\n allDetectedTokens: TokensControllerState['allDetectedTokens'],\n ) =>\n [\n ...new Set([\n ...Object.keys(allTokens),\n ...Object.keys(allDetectedTokens),\n ]),\n ] as Hex[];\n\n /**\n * Polls for erc20 token balances.\n * @param input - The input for the poll.\n * @param input.chainId - The chain id to poll token balances on.\n */\n async _executePoll({ chainId }: TokenBalancesPollingInput): Promise<void> {\n const { address: selectedAccountAddress } = this.messagingSystem.call(\n 'AccountsController:getSelectedAccount',\n );\n\n const isSelectedAccount = (accountAddress: string) =>\n toChecksumHexAddress(accountAddress) ===\n toChecksumHexAddress(selectedAccountAddress);\n\n const accountTokenPairs: { accountAddress: Hex; tokenAddress: Hex }[] = [];\n\n const addTokens = ([accountAddress, tokens]: [string, Token[]]) =>\n this.#queryMultipleAccounts || isSelectedAccount(accountAddress)\n ? tokens.forEach((t) =>\n accountTokenPairs.push({\n accountAddress: accountAddress as Hex,\n tokenAddress: t.address as Hex,\n }),\n )\n : undefined;\n\n Object.entries(this.#allTokens[chainId] ?? {}).forEach(addTokens);\n Object.entries(this.#allDetectedTokens[chainId] ?? {}).forEach(addTokens);\n\n if (accountTokenPairs.length === 0) {\n return;\n }\n\n const provider = new Web3Provider(this.#getNetworkClient(chainId).provider);\n\n const calls = accountTokenPairs.map(({ accountAddress, tokenAddress }) => ({\n contract: new Contract(tokenAddress, abiERC20, provider),\n functionSignature: 'balanceOf(address)',\n arguments: [accountAddress],\n }));\n\n const results = await multicallOrFallback(calls, chainId, provider);\n\n this.update((state) => {\n for (let i = 0; i < results.length; i++) {\n const { success, value } = results[i];\n\n if (success) {\n const { accountAddress, tokenAddress } = accountTokenPairs[i];\n ((state.tokenBalances[accountAddress] ??= {})[chainId] ??= {})[\n tokenAddress\n ] = toHex(value as BN);\n }\n }\n });\n }\n\n // TODO: needed?\n /**\n * Reset the controller state to the default state.\n */\n resetState() {\n this.update(() => {\n return getDefaultTokenBalancesState();\n });\n }\n\n // Returns the network client for a given chain id\n #getNetworkClient(chainId: Hex) {\n const { networkConfigurationsByChainId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n\n const networkConfiguration = networkConfigurationsByChainId[chainId];\n if (!networkConfiguration) {\n throw new Error(\n `TokenBalancesController: No network configuration found for chainId ${chainId}`,\n );\n }\n\n const { networkClientId } =\n networkConfiguration.rpcEndpoints[\n networkConfiguration.defaultRpcEndpointIndex\n ];\n\n return this.messagingSystem.call(\n `NetworkController:getNetworkClientById`,\n networkClientId,\n );\n }\n}\n\nexport default TokenBalancesController;\n"]}
@@ -1,40 +1,38 @@
1
1
  import type { AccountsControllerGetSelectedAccountAction } from "@metamask/accounts-controller";
2
2
  import type { RestrictedControllerMessenger, ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller";
3
- import { BaseController } from "@metamask/base-controller";
4
- import type { AssetsContractControllerGetERC20BalanceOfAction } from "./AssetsContractController.cjs";
5
- import type { Token } from "./TokenRatesController.cjs";
6
- import type { TokensControllerStateChangeEvent } from "./TokensController.cjs";
3
+ import type { NetworkControllerGetNetworkClientByIdAction, NetworkControllerGetStateAction } from "@metamask/network-controller";
4
+ import type { PreferencesControllerGetStateAction, PreferencesControllerStateChangeEvent } from "@metamask/preferences-controller";
5
+ import type { Hex } from "@metamask/utils";
6
+ import type { TokensControllerGetStateAction, TokensControllerStateChangeEvent } from "./TokensController.cjs";
7
7
  declare const controllerName = "TokenBalancesController";
8
8
  /**
9
9
  * Token balances controller options
10
10
  * @property interval - Polling interval used to fetch new token balances.
11
- * @property tokens - List of tokens to track balances for.
12
- * @property disabled - If set to true, all tracked tokens contract balances updates are blocked.
11
+ * @property messenger - A controller messenger.
12
+ * @property state - Initial state for the controller.
13
13
  */
14
14
  type TokenBalancesControllerOptions = {
15
15
  interval?: number;
16
- tokens?: Token[];
17
- disabled?: boolean;
18
16
  messenger: TokenBalancesControllerMessenger;
19
17
  state?: Partial<TokenBalancesControllerState>;
20
18
  };
21
19
  /**
22
- * Represents a mapping of hash token contract addresses to their balances.
20
+ * A mapping from account address to chain id to token address to balance.
23
21
  */
24
- type ContractBalances = Record<string, string>;
22
+ type TokenBalances = Record<Hex, Record<Hex, Record<Hex, Hex>>>;
25
23
  /**
26
24
  * Token balances controller state
27
- * @property contractBalances - Hash of token contract addresses to balances
25
+ * @property tokenBalances - A mapping from account address to chain id to token address to balance.
28
26
  */
29
27
  export type TokenBalancesControllerState = {
30
- contractBalances: ContractBalances;
28
+ tokenBalances: TokenBalances;
31
29
  };
32
30
  export type TokenBalancesControllerGetStateAction = ControllerGetStateAction<typeof controllerName, TokenBalancesControllerState>;
33
31
  export type TokenBalancesControllerActions = TokenBalancesControllerGetStateAction;
34
- export type AllowedActions = AccountsControllerGetSelectedAccountAction | AssetsContractControllerGetERC20BalanceOfAction;
32
+ export type AllowedActions = NetworkControllerGetNetworkClientByIdAction | NetworkControllerGetStateAction | TokensControllerGetStateAction | PreferencesControllerGetStateAction | AccountsControllerGetSelectedAccountAction;
35
33
  export type TokenBalancesControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, TokenBalancesControllerState>;
36
34
  export type TokenBalancesControllerEvents = TokenBalancesControllerStateChangeEvent;
37
- export type AllowedEvents = TokensControllerStateChangeEvent;
35
+ export type AllowedEvents = TokensControllerStateChangeEvent | PreferencesControllerStateChangeEvent;
38
36
  export type TokenBalancesControllerMessenger = RestrictedControllerMessenger<typeof controllerName, TokenBalancesControllerActions | AllowedActions, TokenBalancesControllerEvents | AllowedEvents, AllowedActions['type'], AllowedEvents['type']>;
39
37
  /**
40
38
  * Get the default TokenBalancesController state.
@@ -42,41 +40,46 @@ export type TokenBalancesControllerMessenger = RestrictedControllerMessenger<typ
42
40
  * @returns The default TokenBalancesController state.
43
41
  */
44
42
  export declare function getDefaultTokenBalancesState(): TokenBalancesControllerState;
43
+ /** The input to start polling for the {@link TokenBalancesController} */
44
+ export type TokenBalancesPollingInput = {
45
+ chainId: Hex;
46
+ };
47
+ declare const TokenBalancesController_base: (abstract new (...args: any[]) => {
48
+ readonly "__#787890@#intervalIds": Record<string, NodeJS.Timeout>;
49
+ "__#787890@#intervalLength": number | undefined;
50
+ setIntervalLength(intervalLength: number): void;
51
+ getIntervalLength(): number | undefined;
52
+ _startPolling(input: TokenBalancesPollingInput): void;
53
+ _stopPollingByPollingTokenSetId(key: string): void;
54
+ readonly "__#787882@#pollingTokenSets": Map<string, Set<string>>;
55
+ "__#787882@#callbacks": Map<string, Set<(input: TokenBalancesPollingInput) => void>>;
56
+ _executePoll(input: TokenBalancesPollingInput): Promise<void>;
57
+ startPolling(input: TokenBalancesPollingInput): string;
58
+ stopAllPolling(): void;
59
+ stopPollingByPollingToken(pollingToken: string): void;
60
+ onPollingComplete(input: TokenBalancesPollingInput, callback: (input: TokenBalancesPollingInput) => void): void;
61
+ }) & typeof import("@metamask/base-controller").BaseController;
45
62
  /**
46
63
  * Controller that passively polls on a set interval token balances
47
64
  * for tokens stored in the TokensController
48
65
  */
49
- export declare class TokenBalancesController extends BaseController<typeof controllerName, TokenBalancesControllerState, TokenBalancesControllerMessenger> {
66
+ export declare class TokenBalancesController extends TokenBalancesController_base<typeof controllerName, TokenBalancesControllerState, TokenBalancesControllerMessenger> {
50
67
  #private;
51
68
  /**
52
69
  * Construct a Token Balances Controller.
53
70
  *
54
71
  * @param options - The controller options.
55
72
  * @param options.interval - Polling interval used to fetch new token balances.
56
- * @param options.tokens - List of tokens to track balances for.
57
- * @param options.disabled - If set to true, all tracked tokens contract balances updates are blocked.
58
73
  * @param options.state - Initial state to set on this controller.
59
74
  * @param options.messenger - The controller restricted messenger.
60
75
  */
61
- constructor({ interval, tokens, disabled, messenger, state, }: TokenBalancesControllerOptions);
62
- /**
63
- * Allows controller to update tracked tokens contract balances.
64
- */
65
- enable(): void;
66
- /**
67
- * Blocks controller from updating tracked tokens contract balances.
68
- */
69
- disable(): void;
70
- /**
71
- * Starts a new polling interval.
72
- *
73
- * @param interval - Polling interval used to fetch new token balances.
74
- */
75
- poll(interval?: number): Promise<void>;
76
+ constructor({ interval, messenger, state, }: TokenBalancesControllerOptions);
76
77
  /**
77
- * Updates balances for all tokens.
78
+ * Polls for erc20 token balances.
79
+ * @param input - The input for the poll.
80
+ * @param input.chainId - The chain id to poll token balances on.
78
81
  */
79
- updateBalances(): Promise<void>;
82
+ _executePoll({ chainId }: TokenBalancesPollingInput): Promise<void>;
80
83
  /**
81
84
  * Reset the controller state to the default state.
82
85
  */
@@ -1 +1 @@
1
- {"version":3,"file":"TokenBalancesController.d.cts","sourceRoot":"","sources":["../src/TokenBalancesController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0CAA0C,EAAE,sCAAsC;AAChG,OAAO,KAAK,EACV,6BAA6B,EAC7B,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAG3D,OAAO,KAAK,EAAE,+CAA+C,EAAE,uCAAmC;AAClG,OAAO,KAAK,EAAE,KAAK,EAAE,mCAA+B;AACpD,OAAO,KAAK,EAAE,gCAAgC,EAAE,+BAA2B;AAI3E,QAAA,MAAM,cAAc,4BAA4B,CAAC;AAMjD;;;;;GAKG;AACH,KAAK,8BAA8B,GAAG;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,gCAAgC,CAAC;IAC5C,KAAK,CAAC,EAAE,OAAO,CAAC,4BAA4B,CAAC,CAAC;CAC/C,CAAC;AAEF;;GAEG;AACH,KAAK,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE/C;;;GAGG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC,gBAAgB,EAAE,gBAAgB,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,qCAAqC,GAAG,wBAAwB,CAC1E,OAAO,cAAc,EACrB,4BAA4B,CAC7B,CAAC;AAEF,MAAM,MAAM,8BAA8B,GACxC,qCAAqC,CAAC;AAExC,MAAM,MAAM,cAAc,GACtB,0CAA0C,GAC1C,+CAA+C,CAAC;AAEpD,MAAM,MAAM,uCAAuC,GACjD,0BAA0B,CACxB,OAAO,cAAc,EACrB,4BAA4B,CAC7B,CAAC;AAEJ,MAAM,MAAM,6BAA6B,GACvC,uCAAuC,CAAC;AAE1C,MAAM,MAAM,aAAa,GAAG,gCAAgC,CAAC;AAE7D,MAAM,MAAM,gCAAgC,GAAG,6BAA6B,CAC1E,OAAO,cAAc,EACrB,8BAA8B,GAAG,cAAc,EAC/C,6BAA6B,GAAG,aAAa,EAC7C,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,4BAA4B,IAAI,4BAA4B,CAI3E;AAED;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,cAAc,CACzD,OAAO,cAAc,EACrB,4BAA4B,EAC5B,gCAAgC,CACjC;;IASC;;;;;;;;;OASG;gBACS,EACV,QAA2B,EAC3B,MAAW,EACX,QAAgB,EAChB,SAAS,EACT,KAAU,GACX,EAAE,8BAA8B;IA8BjC;;OAEG;IACH,MAAM;IAIN;;OAEG;IACH,OAAO;IAIP;;;;OAIG;IACG,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB5C;;OAEG;IACG,cAAc;IA8BpB;;OAEG;IACH,UAAU;CAKX;AAED,eAAe,uBAAuB,CAAC"}
1
+ {"version":3,"file":"TokenBalancesController.d.cts","sourceRoot":"","sources":["../src/TokenBalancesController.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,0CAA0C,EAAE,sCAAsC;AAChG,OAAO,KAAK,EACV,6BAA6B,EAC7B,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AAGnC,OAAO,KAAK,EACV,2CAA2C,EAC3C,+BAA+B,EAChC,qCAAqC;AAEtC,OAAO,KAAK,EACV,mCAAmC,EACnC,qCAAqC,EAEtC,yCAAyC;AAC1C,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAM3C,OAAO,KAAK,EACV,8BAA8B,EAE9B,gCAAgC,EACjC,+BAA2B;AAI5B,QAAA,MAAM,cAAc,4BAA4B,CAAC;AAMjD;;;;;GAKG;AACH,KAAK,8BAA8B,GAAG;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,gCAAgC,CAAC;IAC5C,KAAK,CAAC,EAAE,OAAO,CAAC,4BAA4B,CAAC,CAAC;CAC/C,CAAC;AAEF;;GAEG;AACH,KAAK,aAAa,GAAG,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AAEhE;;;GAGG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC,aAAa,EAAE,aAAa,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,qCAAqC,GAAG,wBAAwB,CAC1E,OAAO,cAAc,EACrB,4BAA4B,CAC7B,CAAC;AAEF,MAAM,MAAM,8BAA8B,GACxC,qCAAqC,CAAC;AAExC,MAAM,MAAM,cAAc,GACtB,2CAA2C,GAC3C,+BAA+B,GAC/B,8BAA8B,GAC9B,mCAAmC,GACnC,0CAA0C,CAAC;AAE/C,MAAM,MAAM,uCAAuC,GACjD,0BAA0B,CACxB,OAAO,cAAc,EACrB,4BAA4B,CAC7B,CAAC;AAEJ,MAAM,MAAM,6BAA6B,GACvC,uCAAuC,CAAC;AAE1C,MAAM,MAAM,aAAa,GACrB,gCAAgC,GAChC,qCAAqC,CAAC;AAE1C,MAAM,MAAM,gCAAgC,GAAG,6BAA6B,CAC1E,OAAO,cAAc,EACrB,8BAA8B,GAAG,cAAc,EAC/C,6BAA6B,GAAG,aAAa,EAC7C,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,4BAA4B,IAAI,4BAA4B,CAI3E;AAED,yEAAyE;AACzE,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,EAAE,GAAG,CAAC;CACd,CAAC;;;;;;;;;;;;;;;;AAEF;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,6BAC3C,OAAO,cAAc,EACrB,4BAA4B,EAC5B,gCAAgC,CACjC;;IAOC;;;;;;;OAOG;gBACS,EACV,QAA2B,EAC3B,SAAS,EACT,KAAU,GACX,EAAE,8BAA8B;IAiGjC;;;;OAIG;IACG,YAAY,CAAC,EAAE,OAAO,EAAE,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqDzE;;OAEG;IACH,UAAU;CA6BX;AAED,eAAe,uBAAuB,CAAC"}
@@ -1,40 +1,38 @@
1
1
  import type { AccountsControllerGetSelectedAccountAction } from "@metamask/accounts-controller";
2
2
  import type { RestrictedControllerMessenger, ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller";
3
- import { BaseController } from "@metamask/base-controller";
4
- import type { AssetsContractControllerGetERC20BalanceOfAction } from "./AssetsContractController.mjs";
5
- import type { Token } from "./TokenRatesController.mjs";
6
- import type { TokensControllerStateChangeEvent } from "./TokensController.mjs";
3
+ import type { NetworkControllerGetNetworkClientByIdAction, NetworkControllerGetStateAction } from "@metamask/network-controller";
4
+ import type { PreferencesControllerGetStateAction, PreferencesControllerStateChangeEvent } from "@metamask/preferences-controller";
5
+ import type { Hex } from "@metamask/utils";
6
+ import type { TokensControllerGetStateAction, TokensControllerStateChangeEvent } from "./TokensController.mjs";
7
7
  declare const controllerName = "TokenBalancesController";
8
8
  /**
9
9
  * Token balances controller options
10
10
  * @property interval - Polling interval used to fetch new token balances.
11
- * @property tokens - List of tokens to track balances for.
12
- * @property disabled - If set to true, all tracked tokens contract balances updates are blocked.
11
+ * @property messenger - A controller messenger.
12
+ * @property state - Initial state for the controller.
13
13
  */
14
14
  type TokenBalancesControllerOptions = {
15
15
  interval?: number;
16
- tokens?: Token[];
17
- disabled?: boolean;
18
16
  messenger: TokenBalancesControllerMessenger;
19
17
  state?: Partial<TokenBalancesControllerState>;
20
18
  };
21
19
  /**
22
- * Represents a mapping of hash token contract addresses to their balances.
20
+ * A mapping from account address to chain id to token address to balance.
23
21
  */
24
- type ContractBalances = Record<string, string>;
22
+ type TokenBalances = Record<Hex, Record<Hex, Record<Hex, Hex>>>;
25
23
  /**
26
24
  * Token balances controller state
27
- * @property contractBalances - Hash of token contract addresses to balances
25
+ * @property tokenBalances - A mapping from account address to chain id to token address to balance.
28
26
  */
29
27
  export type TokenBalancesControllerState = {
30
- contractBalances: ContractBalances;
28
+ tokenBalances: TokenBalances;
31
29
  };
32
30
  export type TokenBalancesControllerGetStateAction = ControllerGetStateAction<typeof controllerName, TokenBalancesControllerState>;
33
31
  export type TokenBalancesControllerActions = TokenBalancesControllerGetStateAction;
34
- export type AllowedActions = AccountsControllerGetSelectedAccountAction | AssetsContractControllerGetERC20BalanceOfAction;
32
+ export type AllowedActions = NetworkControllerGetNetworkClientByIdAction | NetworkControllerGetStateAction | TokensControllerGetStateAction | PreferencesControllerGetStateAction | AccountsControllerGetSelectedAccountAction;
35
33
  export type TokenBalancesControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, TokenBalancesControllerState>;
36
34
  export type TokenBalancesControllerEvents = TokenBalancesControllerStateChangeEvent;
37
- export type AllowedEvents = TokensControllerStateChangeEvent;
35
+ export type AllowedEvents = TokensControllerStateChangeEvent | PreferencesControllerStateChangeEvent;
38
36
  export type TokenBalancesControllerMessenger = RestrictedControllerMessenger<typeof controllerName, TokenBalancesControllerActions | AllowedActions, TokenBalancesControllerEvents | AllowedEvents, AllowedActions['type'], AllowedEvents['type']>;
39
37
  /**
40
38
  * Get the default TokenBalancesController state.
@@ -42,41 +40,46 @@ export type TokenBalancesControllerMessenger = RestrictedControllerMessenger<typ
42
40
  * @returns The default TokenBalancesController state.
43
41
  */
44
42
  export declare function getDefaultTokenBalancesState(): TokenBalancesControllerState;
43
+ /** The input to start polling for the {@link TokenBalancesController} */
44
+ export type TokenBalancesPollingInput = {
45
+ chainId: Hex;
46
+ };
47
+ declare const TokenBalancesController_base: (abstract new (...args: any[]) => {
48
+ readonly "__#787890@#intervalIds": Record<string, NodeJS.Timeout>;
49
+ "__#787890@#intervalLength": number | undefined;
50
+ setIntervalLength(intervalLength: number): void;
51
+ getIntervalLength(): number | undefined;
52
+ _startPolling(input: TokenBalancesPollingInput): void;
53
+ _stopPollingByPollingTokenSetId(key: string): void;
54
+ readonly "__#787882@#pollingTokenSets": Map<string, Set<string>>;
55
+ "__#787882@#callbacks": Map<string, Set<(input: TokenBalancesPollingInput) => void>>;
56
+ _executePoll(input: TokenBalancesPollingInput): Promise<void>;
57
+ startPolling(input: TokenBalancesPollingInput): string;
58
+ stopAllPolling(): void;
59
+ stopPollingByPollingToken(pollingToken: string): void;
60
+ onPollingComplete(input: TokenBalancesPollingInput, callback: (input: TokenBalancesPollingInput) => void): void;
61
+ }) & typeof import("@metamask/base-controller").BaseController;
45
62
  /**
46
63
  * Controller that passively polls on a set interval token balances
47
64
  * for tokens stored in the TokensController
48
65
  */
49
- export declare class TokenBalancesController extends BaseController<typeof controllerName, TokenBalancesControllerState, TokenBalancesControllerMessenger> {
66
+ export declare class TokenBalancesController extends TokenBalancesController_base<typeof controllerName, TokenBalancesControllerState, TokenBalancesControllerMessenger> {
50
67
  #private;
51
68
  /**
52
69
  * Construct a Token Balances Controller.
53
70
  *
54
71
  * @param options - The controller options.
55
72
  * @param options.interval - Polling interval used to fetch new token balances.
56
- * @param options.tokens - List of tokens to track balances for.
57
- * @param options.disabled - If set to true, all tracked tokens contract balances updates are blocked.
58
73
  * @param options.state - Initial state to set on this controller.
59
74
  * @param options.messenger - The controller restricted messenger.
60
75
  */
61
- constructor({ interval, tokens, disabled, messenger, state, }: TokenBalancesControllerOptions);
62
- /**
63
- * Allows controller to update tracked tokens contract balances.
64
- */
65
- enable(): void;
66
- /**
67
- * Blocks controller from updating tracked tokens contract balances.
68
- */
69
- disable(): void;
70
- /**
71
- * Starts a new polling interval.
72
- *
73
- * @param interval - Polling interval used to fetch new token balances.
74
- */
75
- poll(interval?: number): Promise<void>;
76
+ constructor({ interval, messenger, state, }: TokenBalancesControllerOptions);
76
77
  /**
77
- * Updates balances for all tokens.
78
+ * Polls for erc20 token balances.
79
+ * @param input - The input for the poll.
80
+ * @param input.chainId - The chain id to poll token balances on.
78
81
  */
79
- updateBalances(): Promise<void>;
82
+ _executePoll({ chainId }: TokenBalancesPollingInput): Promise<void>;
80
83
  /**
81
84
  * Reset the controller state to the default state.
82
85
  */
@@ -1 +1 @@
1
- {"version":3,"file":"TokenBalancesController.d.mts","sourceRoot":"","sources":["../src/TokenBalancesController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0CAA0C,EAAE,sCAAsC;AAChG,OAAO,KAAK,EACV,6BAA6B,EAC7B,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAG3D,OAAO,KAAK,EAAE,+CAA+C,EAAE,uCAAmC;AAClG,OAAO,KAAK,EAAE,KAAK,EAAE,mCAA+B;AACpD,OAAO,KAAK,EAAE,gCAAgC,EAAE,+BAA2B;AAI3E,QAAA,MAAM,cAAc,4BAA4B,CAAC;AAMjD;;;;;GAKG;AACH,KAAK,8BAA8B,GAAG;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,gCAAgC,CAAC;IAC5C,KAAK,CAAC,EAAE,OAAO,CAAC,4BAA4B,CAAC,CAAC;CAC/C,CAAC;AAEF;;GAEG;AACH,KAAK,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE/C;;;GAGG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC,gBAAgB,EAAE,gBAAgB,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,qCAAqC,GAAG,wBAAwB,CAC1E,OAAO,cAAc,EACrB,4BAA4B,CAC7B,CAAC;AAEF,MAAM,MAAM,8BAA8B,GACxC,qCAAqC,CAAC;AAExC,MAAM,MAAM,cAAc,GACtB,0CAA0C,GAC1C,+CAA+C,CAAC;AAEpD,MAAM,MAAM,uCAAuC,GACjD,0BAA0B,CACxB,OAAO,cAAc,EACrB,4BAA4B,CAC7B,CAAC;AAEJ,MAAM,MAAM,6BAA6B,GACvC,uCAAuC,CAAC;AAE1C,MAAM,MAAM,aAAa,GAAG,gCAAgC,CAAC;AAE7D,MAAM,MAAM,gCAAgC,GAAG,6BAA6B,CAC1E,OAAO,cAAc,EACrB,8BAA8B,GAAG,cAAc,EAC/C,6BAA6B,GAAG,aAAa,EAC7C,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,4BAA4B,IAAI,4BAA4B,CAI3E;AAED;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,cAAc,CACzD,OAAO,cAAc,EACrB,4BAA4B,EAC5B,gCAAgC,CACjC;;IASC;;;;;;;;;OASG;gBACS,EACV,QAA2B,EAC3B,MAAW,EACX,QAAgB,EAChB,SAAS,EACT,KAAU,GACX,EAAE,8BAA8B;IA8BjC;;OAEG;IACH,MAAM;IAIN;;OAEG;IACH,OAAO;IAIP;;;;OAIG;IACG,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB5C;;OAEG;IACG,cAAc;IA8BpB;;OAEG;IACH,UAAU;CAKX;AAED,eAAe,uBAAuB,CAAC"}
1
+ {"version":3,"file":"TokenBalancesController.d.mts","sourceRoot":"","sources":["../src/TokenBalancesController.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,0CAA0C,EAAE,sCAAsC;AAChG,OAAO,KAAK,EACV,6BAA6B,EAC7B,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AAGnC,OAAO,KAAK,EACV,2CAA2C,EAC3C,+BAA+B,EAChC,qCAAqC;AAEtC,OAAO,KAAK,EACV,mCAAmC,EACnC,qCAAqC,EAEtC,yCAAyC;AAC1C,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAM3C,OAAO,KAAK,EACV,8BAA8B,EAE9B,gCAAgC,EACjC,+BAA2B;AAI5B,QAAA,MAAM,cAAc,4BAA4B,CAAC;AAMjD;;;;;GAKG;AACH,KAAK,8BAA8B,GAAG;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,gCAAgC,CAAC;IAC5C,KAAK,CAAC,EAAE,OAAO,CAAC,4BAA4B,CAAC,CAAC;CAC/C,CAAC;AAEF;;GAEG;AACH,KAAK,aAAa,GAAG,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AAEhE;;;GAGG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC,aAAa,EAAE,aAAa,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,qCAAqC,GAAG,wBAAwB,CAC1E,OAAO,cAAc,EACrB,4BAA4B,CAC7B,CAAC;AAEF,MAAM,MAAM,8BAA8B,GACxC,qCAAqC,CAAC;AAExC,MAAM,MAAM,cAAc,GACtB,2CAA2C,GAC3C,+BAA+B,GAC/B,8BAA8B,GAC9B,mCAAmC,GACnC,0CAA0C,CAAC;AAE/C,MAAM,MAAM,uCAAuC,GACjD,0BAA0B,CACxB,OAAO,cAAc,EACrB,4BAA4B,CAC7B,CAAC;AAEJ,MAAM,MAAM,6BAA6B,GACvC,uCAAuC,CAAC;AAE1C,MAAM,MAAM,aAAa,GACrB,gCAAgC,GAChC,qCAAqC,CAAC;AAE1C,MAAM,MAAM,gCAAgC,GAAG,6BAA6B,CAC1E,OAAO,cAAc,EACrB,8BAA8B,GAAG,cAAc,EAC/C,6BAA6B,GAAG,aAAa,EAC7C,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,4BAA4B,IAAI,4BAA4B,CAI3E;AAED,yEAAyE;AACzE,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,EAAE,GAAG,CAAC;CACd,CAAC;;;;;;;;;;;;;;;;AAEF;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,6BAC3C,OAAO,cAAc,EACrB,4BAA4B,EAC5B,gCAAgC,CACjC;;IAOC;;;;;;;OAOG;gBACS,EACV,QAA2B,EAC3B,SAAS,EACT,KAAU,GACX,EAAE,8BAA8B;IAiGjC;;;;OAIG;IACG,YAAY,CAAC,EAAE,OAAO,EAAE,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqDzE;;OAEG;IACH,UAAU;CA6BX;AAED,eAAe,uBAAuB,CAAC"}