@metamask-previews/assets-controllers 11.0.1-preview.d32a7cc

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 (80) hide show
  1. package/CHANGELOG.md +235 -0
  2. package/LICENSE +20 -0
  3. package/README.md +30 -0
  4. package/dist/AccountTrackerController.d.ts +106 -0
  5. package/dist/AccountTrackerController.d.ts.map +1 -0
  6. package/dist/AccountTrackerController.js +163 -0
  7. package/dist/AccountTrackerController.js.map +1 -0
  8. package/dist/AssetsContractController.d.ts +188 -0
  9. package/dist/AssetsContractController.d.ts.map +1 -0
  10. package/dist/AssetsContractController.js +330 -0
  11. package/dist/AssetsContractController.js.map +1 -0
  12. package/dist/CurrencyRateController.d.ts +101 -0
  13. package/dist/CurrencyRateController.d.ts.map +1 -0
  14. package/dist/CurrencyRateController.js +219 -0
  15. package/dist/CurrencyRateController.js.map +1 -0
  16. package/dist/NftController.d.ts +464 -0
  17. package/dist/NftController.d.ts.map +1 -0
  18. package/dist/NftController.js +924 -0
  19. package/dist/NftController.js.map +1 -0
  20. package/dist/NftDetectionController.d.ts +182 -0
  21. package/dist/NftDetectionController.d.ts.map +1 -0
  22. package/dist/NftDetectionController.js +188 -0
  23. package/dist/NftDetectionController.js.map +1 -0
  24. package/dist/Standards/ERC20Standard.d.ts +50 -0
  25. package/dist/Standards/ERC20Standard.d.ts.map +1 -0
  26. package/dist/Standards/ERC20Standard.js +144 -0
  27. package/dist/Standards/ERC20Standard.js.map +1 -0
  28. package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.d.ts +79 -0
  29. package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.d.ts.map +1 -0
  30. package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.js +148 -0
  31. package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.js.map +1 -0
  32. package/dist/Standards/NftStandards/ERC721/ERC721Standard.d.ts +89 -0
  33. package/dist/Standards/NftStandards/ERC721/ERC721Standard.d.ts.map +1 -0
  34. package/dist/Standards/NftStandards/ERC721/ERC721Standard.js +182 -0
  35. package/dist/Standards/NftStandards/ERC721/ERC721Standard.js.map +1 -0
  36. package/dist/Standards/standards-types.d.ts +15 -0
  37. package/dist/Standards/standards-types.d.ts.map +1 -0
  38. package/dist/Standards/standards-types.js +3 -0
  39. package/dist/Standards/standards-types.js.map +1 -0
  40. package/dist/TokenBalancesController.d.ts +71 -0
  41. package/dist/TokenBalancesController.d.ts.map +1 -0
  42. package/dist/TokenBalancesController.js +94 -0
  43. package/dist/TokenBalancesController.js.map +1 -0
  44. package/dist/TokenDetectionController.d.ts +87 -0
  45. package/dist/TokenDetectionController.d.ts.map +1 -0
  46. package/dist/TokenDetectionController.js +189 -0
  47. package/dist/TokenDetectionController.js.map +1 -0
  48. package/dist/TokenListController.d.ts +117 -0
  49. package/dist/TokenListController.d.ts.map +1 -0
  50. package/dist/TokenListController.js +248 -0
  51. package/dist/TokenListController.js.map +1 -0
  52. package/dist/TokenRatesController.d.ts +172 -0
  53. package/dist/TokenRatesController.d.ts.map +1 -0
  54. package/dist/TokenRatesController.js +327 -0
  55. package/dist/TokenRatesController.js.map +1 -0
  56. package/dist/TokensController.d.ts +250 -0
  57. package/dist/TokensController.d.ts.map +1 -0
  58. package/dist/TokensController.js +550 -0
  59. package/dist/TokensController.js.map +1 -0
  60. package/dist/assetsUtil.d.ts +109 -0
  61. package/dist/assetsUtil.d.ts.map +1 -0
  62. package/dist/assetsUtil.js +227 -0
  63. package/dist/assetsUtil.js.map +1 -0
  64. package/dist/constants.d.ts +6 -0
  65. package/dist/constants.d.ts.map +1 -0
  66. package/dist/constants.js +10 -0
  67. package/dist/constants.js.map +1 -0
  68. package/dist/crypto-compare.d.ts +13 -0
  69. package/dist/crypto-compare.d.ts.map +1 -0
  70. package/dist/crypto-compare.js +67 -0
  71. package/dist/crypto-compare.js.map +1 -0
  72. package/dist/index.d.ts +12 -0
  73. package/dist/index.d.ts.map +1 -0
  74. package/dist/index.js +32 -0
  75. package/dist/index.js.map +1 -0
  76. package/dist/token-service.d.ts +31 -0
  77. package/dist/token-service.d.ts.map +1 -0
  78. package/dist/token-service.js +134 -0
  79. package/dist/token-service.js.map +1 -0
  80. package/package.json +82 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,235 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [11.0.1]
10
+ ### Changed
11
+ - Replace `eth-query` ^2.1.2 with `@metamask/eth-query` ^3.0.1 ([#1546](https://github.com/MetaMask/core/pull/1546))
12
+
13
+ ## [11.0.0]
14
+ ### Added
15
+ - Add a `stop` method to stop polling
16
+
17
+ ### Changed
18
+ - **BREAKING**: New required constructor parameters for the `TokenRatesController` ([#1497](https://github.com/MetaMask/core/pull/1497), [#1511](https://github.com/MetaMask/core/pull/1511))
19
+ - The new required parameters are `ticker`, `onSelectedAddress`, and `onPreferencesStateChange`
20
+ - **BREAKING**: Remove `onCurrencyRateStateChange` constructor parameter from `TokenRatesController` ([#1496](https://github.com/MetaMask/core/pull/1496))
21
+ - **BREAKING**: Disable `TokenRatesController` automatic polling ([#1501](https://github.com/MetaMask/core/pull/1501))
22
+ - Polling must be started explicitly by calling the `start` method
23
+ - The token rates are not updated upon state changes when polling is disabled.
24
+ - **BREAKING**: Replace the `poll` method with `start` ([#1501](https://github.com/MetaMask/core/pull/1501))
25
+ - The `start` method does not offer a way to change the interval. That must be done by calling `.configure` instead
26
+ - **BREAKING**: Remove `TokenRatecontroller` setter for `chainId` and `tokens` properties ([#1505](https://github.com/MetaMask/core/pull/1505))
27
+ - Bump @metamask/abi-utils from 1.2.0 to 2.0.1 ([#1525](https://github.com/MetaMask/core/pull/1525))
28
+ - Update `@metamask/utils` to `^6.2.0` ([#1514](https://github.com/MetaMask/core/pull/1514))
29
+ - Remove unnecessary `babel-runtime` dependency ([#1504](https://github.com/MetaMask/core/pull/1504))
30
+
31
+ ### Fixed
32
+ - Fix bug where token rates were incorrect after first update if initialized with a non-Ethereum selected network ([#1497](https://github.com/MetaMask/core/pull/1497))
33
+ - Fix bug where token rates would be invalid if event handlers were triggered in the wrong order ([#1496](https://github.com/MetaMask/core/pull/1496), [#1511](https://github.com/MetaMask/core/pull/1511))
34
+ - Prevent redundant token rate updates ([#1512](https://github.com/MetaMask/core/pull/1512))
35
+
36
+ ## [10.0.0]
37
+ ### Added
38
+ - The method `getERC20TokenName` has been added to `AssetsContractController` ([#1127](https://github.com/MetaMask/core/pull/1127))
39
+ - This method gets the token name from the token contract
40
+
41
+ ### Changed
42
+ - **BREAKING:** The tokens controller now requires `onTokenListStateChange` and `getERC20TokenName` as constructor parameters ([#1127](https://github.com/MetaMask/core/pull/1127))
43
+ - The `getERC20TokenName` method is used to get the token name for tokens added via `wallet_watchAsset`
44
+ - The `onTokenListStateChange` method is used to trigger a name update when the token list changes. On each change, token names are copied from the token list if they're missing from token controller state.
45
+ - **BREAKING:** The signature of the tokens controller method `addToken` has changed
46
+ - The fourth and fifth positional parameters (`image` and `interactingAddress`) have been replaced by an `options` object
47
+ - The new options parameter includes the `image` and `interactingAddress` properties, and a new `name` property
48
+ - The token detection controller now sets the token name when new tokens are detected ([#1127](https://github.com/MetaMask/core/pull/1127))
49
+ - The `Token` type now includes an optional `name` field ([#1127](https://github.com/MetaMask/core/pull/1127))
50
+
51
+ ## [9.2.0]
52
+ ### Added
53
+ - Add validation that the nft standard matches the type argument of a `wallet_watchAsset` request when type is 'ERC721' or 'ERC1155' ([#1455](https://github.com/MetaMask/core/pull/1455))
54
+
55
+ ## [9.1.0]
56
+ ### Added
57
+ - Add a fifth argument, `source`, to NftController's `addNft` method ([#1417](https://github.com/MetaMask/core/pull/1417))
58
+ - This argument can be used to specify whether the NFT was detected, added manually, or suggested by a dapp
59
+
60
+ ### Fixed
61
+ - Fix `watchNft` in NftController to ensure that if the network changes before the user accepts the request, the NFT is added to the chain ID and address before the request was initiated ([#1417](https://github.com/MetaMask/core/pull/1417))
62
+
63
+ ## [9.0.0]
64
+ ### Added
65
+ - **BREAKING**: Add required options `getSelectedAddress` and `getMultiAccountBalancesEnabled` to AccountTrackerController constructor and make use of them when refreshing account balances ([#1146](https://github.com/MetaMask/core/pull/1146))
66
+ - Previously, the controller would refresh all account balances, but these options can be used to only refresh the currently selected account
67
+ - **BREAKING:** Add logic to support validating and adding ERC721 and ERC1155 tokens to NFTController state via `wallet_watchAsset` API. ([#1173](https://github.com/MetaMask/core/pull/1173), [#1406](https://github.com/MetaMask/core/pull/1406))
68
+ - The `NFTController` now has a new `watchNFT` method that can be called to send a message to the `ApprovalController` and prompt the user to add an NFT to their wallet state.
69
+ - The `NFTController` now requires an instance of a ControllerMessenger to be passed to its constructor. This is messenger is used to pass the `watchNFT` message to the `ApprovalController`.
70
+
71
+ ### Changed
72
+ - Add dependency on `@ethersproject/address` ([#1173](https://github.com/MetaMask/core.git/pull/1173))
73
+ - Replace `eth-rpc-errors` with `@metamask/rpc-errors` ([#1173](https://github.com/MetaMask/core.git/pull/1173))
74
+
75
+ ## [8.0.0]
76
+ ### Added
77
+ - Support NFT detection on Ethereum Mainnet custom RPC endpoints ([#1360](https://github.com/MetaMask/core/pull/1360))
78
+ - Enable token detection for the Aurora network ([#1327](https://github.com/MetaMask/core/pull/1327))
79
+
80
+ ### Changed
81
+ - **BREAKING:** Bump to Node 16 ([#1262](https://github.com/MetaMask/core/pull/1262))
82
+ - **BREAKING:** Change format of chain ID in state to 0x-prefixed hex string ([#1367](https://github.com/MetaMask/core/pull/1367))
83
+ - The functions `isTokenDetectionSupportedForNetwork` and `formatIconUrlWithProxy` now expect a chain ID as type `Hex` rather than as a decimal `string`
84
+ - The assets contract controller now expects the `chainId` configuration entry and constructor parameter as type `Hex` rather than decimal `string`
85
+ - The NFT controller now expects the `chainId` configuration entry and constructor parameter as type `Hex` rather than decimal `string`
86
+ - The NFT controller methods `addNft`, `checkAndUpdateSingleNftOwnershipStatus`, `findNftByAddressAndTokenId`, `updateNft`, and `resetNftTransactionStatusByTransactionId` now expect the chain ID to be type `Hex` rather than a decimal `string`
87
+ - The NFT controller state properties `allNftContracts` and `allNfts` are now keyed by address and `Hex` chain ID, rather than by address and decimal `string` chain ID
88
+ - This requires a state migration
89
+ - The NFT detection controller now expects the `chainId` configuration entry and constructor parameter as type `Hex` rather than decimal `string`
90
+ - The token detection controller now expects the `chainId` configuration entry as type `Hex` rather than decimal `string`
91
+ - The token list controller now expects the `chainId` constructor parameter as type `Hex` rather than decimal `string`
92
+ - The token list controller state property `tokensChainsCache` is now keyed by `Hex` chain ID rather than by decimal `string` chain ID.
93
+ - This requires a state migration
94
+ - The token rates controller now expects the `chainId` configuration entry and constructor parameter as type `Hex` rather than decimal `string`
95
+ - The token rates controller `chainId` setter now expects the chain ID as `Hex` rather than as a decimal string
96
+ - The tokens controller now expects the `chainId` configuration entry and constructor parameter as type `Hex` rather than decimal `string`
97
+ - The tokens controller `addDetectedTokens` method now accepts the `chainId` property of the `detectionDetails` parameter to be of type `Hex` rather than decimal `string`.
98
+ - The tokens controller state properties `allTokens`, `allIgnoredTokens`, and `allDetectedTokens` are now keyed by chain ID in `Hex` format rather than decimal `string`.
99
+ - This requires a state migration
100
+ - **BREAKING**: Use approval controller for suggested assets ([#1261](https://github.com/MetaMask/core/pull/1261), [#1268](https://github.com/MetaMask/core/pull/1268))
101
+ - The actions `ApprovalController:acceptRequest` and `ApprovalController:rejectRequest` are no longer required by the token controller messenger.
102
+ - The `suggestedAssets` state has been removed, which means that suggested assets are no longer persisted in state
103
+ - The return type for `watchAsset` has changed. It now returns a Promise that settles after the request has been confirmed or rejected.
104
+ - **BREAKING:** Initialize controllers with the current network ([#1361](https://github.com/MetaMask/core/pull/1361))
105
+ - The following controllers now have a new `chainId` required constructor parameter:
106
+ * `AssetsContractController`
107
+ * `NftController`
108
+ * `NftDetectionController`
109
+ * `TokenRatesController`
110
+ * `TokensController`
111
+ - **BREAKING:** The token list controller messenger requires the `NetworkController:stateChange` event instead of the `NetworkController:providerConfigChange` event ([#1329](https://github.com/MetaMask/core/pull/1329))
112
+ - **BREAKING:** The token list controller `onNetworkStateChange` option now has a more restrictive type ([#1329](https://github.com/MetaMask/core/pull/1329))
113
+ - The event handler parameter type has been changed from `NetworkState | ProviderConfig` to `NetworkState`
114
+ - **BREAKING:** Update the account tracker controller `provider` type ([#1266](https://github.com/MetaMask/core/pull/1266))
115
+ - The `provider` setter and the `provider` config entry now use our `Provider` type from `eth-query` rather than `any`
116
+ - **BREAKING:** Update`@metamask/preferences-controller` dependency and add it as a peer dependency ([#1393](https://github.com/MetaMask/core/pull/1393))
117
+ - **BREAKING:** Update `@metamask/approval-controller` and `@metamask/network-controller` dependencies and peer dependencies
118
+ - Bump @metamask/abi-utils from 1.1.0 to 1.2.0 ([#1287](https://github.com/MetaMask/core/pull/1287))
119
+ - Bump @metamask/utils from 5.0.1 to 5.0.2 ([#1271](https://github.com/MetaMask/core/pull/1271))
120
+
121
+ ### Removed
122
+ - **BREAKING:** Remove the `networkType` configuration option from the NFT detection controller, NFT controller, and tokens controller ([#1360](https://github.com/MetaMask/core/pull/1360), [#1359](https://github.com/MetaMask/core/pull/1359))
123
+ - **BREAKING:** Remove the `SuggestedAssetMeta` and `SuggestedAssetMetaBase` types from the token controller ([#1268](https://github.com/MetaMask/core/pull/1268))
124
+ - **BREAKING:** Remove the `acceptWatchAsset` and `rejectWatchAsset` methods from the token controller ([#1268](https://github.com/MetaMask/core/pull/1268))
125
+ - Suggested assets can be accepted or rejected using the approval controller instead
126
+
127
+ ## [7.0.0]
128
+ ### Changed
129
+ - **BREAKING**: peerDeps: @metamask/network-controller@6.0.0->8.0.0 ([#1196](https://github.com/MetaMask/core/pull/1196))
130
+
131
+ ## [6.0.0]
132
+ ### Changed
133
+ - **BREAKING:** Create approval requests using `@metamask/approval-controller` ([#1166](https://github.com/MetaMask/core/pull/1166))
134
+
135
+ ## [5.1.0]
136
+ ### Added
137
+ - Support watching assets on a specific account ([#1124](https://github.com/MetaMask/core/pull/1124))
138
+
139
+ ## [5.0.1]
140
+ ### Changed
141
+ - Update `@metamask/contract-metadata` from 2.1.0 to 2.3.1 ([#1141](https://github.com/MetaMask/core/pull/1141))
142
+
143
+ ## [5.0.0]
144
+ ### Removed
145
+ - **BREAKING:** Remove `isomorphic-fetch` ([#1106](https://github.com/MetaMask/controllers/pull/1106))
146
+ - Consumers must now import `isomorphic-fetch` or another polyfill themselves if they are running in an environment without `fetch`
147
+
148
+ ## [4.0.1]
149
+ ### Fixed
150
+ - Update Nft Controller to add the NFT back to its own group if we are re-importing it ([#1082](https://github.com/MetaMask/core/pull/1082))
151
+
152
+ ## [4.0.0]
153
+ ### Added
154
+ - Add Sepolia support to the currency rate controller ([#1041](https://github.com/MetaMask/controllers/pull/1041))
155
+ - The currency rate controller will now treat Sepolia as a testnet, and return the Mainnet exchange rate when asked for the Sepolia exchange rate.
156
+
157
+ ### Changed
158
+ - **BREAKING:** Update `@metamask/network-controller` peer dependency to v3 ([#1041](https://github.com/MetaMask/controllers/pull/1041))
159
+ - **BREAKING:** Migrate from `metaswap` to `metafi` subdomain for OpenSea proxy and token icons API ([#1060](https://github.com/MetaMask/core/pull/1060))
160
+ - Rename this repository to `core` ([#1031](https://github.com/MetaMask/controllers/pull/1031))
161
+ - Update ERC20Standard to use `@metamask/abi-utils` instead of `@ethersproject/abi` ([#985](https://github.com/MetaMask/controllers/pull/985))
162
+ - Update `@metamask/controller-utils` package ([#1041](https://github.com/MetaMask/controllers/pull/1041))
163
+
164
+ ## Removed
165
+ - **BREAKING**: Drop support for Ropsten, Rinkeby, and Kovan ([#1041](https://github.com/MetaMask/controllers/pull/1041))
166
+ - The currency rate controller no longer has special handling of these three networks. It used to return the Mainnet exchange rate for these three networks, but now it includes no special handling for them.
167
+ - The NFT controller no longer supports the Rinkeby OpenSea test API.
168
+
169
+ ## [3.0.1]
170
+ ### Changed
171
+ - Export `isTokenDetectionSupportedForNetwork` function ([#1034](https://github.com/MetaMask/controllers/pull/1034))
172
+ - Update `@metamask/contract-metadata` from 1.35.0 to 2.1.0 ([#1013](https://github.com/MetaMask/controllers/pull/1013))
173
+
174
+ ### Fixed
175
+ - Fix token controller state updates ([#1015](https://github.com/MetaMask/controllers/pull/1015))
176
+ - Attempts to empty the list of "added", "ignored", or "detected" tokens were not saved in state correctly, resulting in that operation being undone after switching account or network.
177
+
178
+ ## [3.0.0]
179
+ ### Changed
180
+ - **BREAKING:** A new private property, controlled by the `start` and `stop` methods, is added to the CurrencyRateController: `enabled`. When this is false, no network requests will be made from the controller. Previously, setNativeCurrency or setCurrentCurrency would trigger a network request. That is now prevented if `enabled` is false. ([#1002](https://github.com/MetaMask/core/pull/1002))
181
+
182
+ ### Fixed
183
+ - The TokenRatesController no longer overwrites the `disabled` config property passed to the constructor, allowing the controller to be instantiated with `config.disabled` set to either true or false. ([#1002](https://github.com/MetaMask/core/pull/1002))
184
+ - This package will now warn if a required package is not present ([#1003](https://github.com/MetaMask/core/pull/1003))
185
+
186
+ ## [2.0.0]
187
+ ### Changed
188
+ - **BREAKING:** Update `onNetworkStateChange`, a constructor option for several controllers, to take an object with a `providerConfig` property instead of `provider` ([#995](https://github.com/MetaMask/core/pull/995))
189
+ - This affects:
190
+ - AssetsContractController
191
+ - NftController
192
+ - NftDetectionController
193
+ - TokenDetectionController
194
+ - TokenListController
195
+ - TokenRatesController
196
+ - TokenController
197
+ - **BREAKING:** [TokenDetectionController] Update `getNetworkState` constructor option to take an object with `providerConfig` property rather than `providerConfig` ([#995](https://github.com/MetaMask/core/pull/995))
198
+ - Relax dependencies on `@metamask/base-controller`, `@metamask/controller-utils`, `@metamask/network-controller`, and `@metamask/preferences-controller` (use `^` instead of `~`) ([#998](https://github.com/MetaMask/core/pull/998))
199
+
200
+ ## [1.0.1]
201
+ ### Fixed
202
+ - Fix race condition where some token detections can get mistakenly added to the wrong account ([#956](https://github.com/MetaMask/core/pull/956))
203
+
204
+ ## [1.0.0]
205
+ ### Added
206
+ - Initial release
207
+ - As a result of converting our shared controllers repo into a monorepo ([#831](https://github.com/MetaMask/core/pull/831)), we've created this package from select parts of [`@metamask/controllers` v33.0.0](https://github.com/MetaMask/core/tree/v33.0.0), namely:
208
+ - Everything in `src/assets`
209
+ - Asset-related functions from `src/util.ts` and accompanying tests
210
+
211
+ All changes listed after this point were applied to this package following the monorepo conversion.
212
+
213
+ ### Changed
214
+ - Use Ethers for AssetsContractController ([#845](https://github.com/MetaMask/core/pull/845))
215
+
216
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@11.0.1...HEAD
217
+ [11.0.1]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@11.0.0...@metamask/assets-controllers@11.0.1
218
+ [11.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@10.0.0...@metamask/assets-controllers@11.0.0
219
+ [10.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@9.2.0...@metamask/assets-controllers@10.0.0
220
+ [9.2.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@9.1.0...@metamask/assets-controllers@9.2.0
221
+ [9.1.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@9.0.0...@metamask/assets-controllers@9.1.0
222
+ [9.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@8.0.0...@metamask/assets-controllers@9.0.0
223
+ [8.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@7.0.0...@metamask/assets-controllers@8.0.0
224
+ [7.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@6.0.0...@metamask/assets-controllers@7.0.0
225
+ [6.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@5.1.0...@metamask/assets-controllers@6.0.0
226
+ [5.1.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@5.0.1...@metamask/assets-controllers@5.1.0
227
+ [5.0.1]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@5.0.0...@metamask/assets-controllers@5.0.1
228
+ [5.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@4.0.1...@metamask/assets-controllers@5.0.0
229
+ [4.0.1]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@4.0.0...@metamask/assets-controllers@4.0.1
230
+ [4.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@3.0.1...@metamask/assets-controllers@4.0.0
231
+ [3.0.1]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@3.0.0...@metamask/assets-controllers@3.0.1
232
+ [3.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@2.0.0...@metamask/assets-controllers@3.0.0
233
+ [2.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@1.0.1...@metamask/assets-controllers@2.0.0
234
+ [1.0.1]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@1.0.0...@metamask/assets-controllers@1.0.1
235
+ [1.0.0]: https://github.com/MetaMask/core/releases/tag/@metamask/assets-controllers@1.0.0
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 MetaMask
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
package/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # `@metamask/assets-controllers`
2
+
3
+ Controllers which manage interactions involving ERC-20, ERC-721, and ERC-1155 tokens (including NFTs).
4
+
5
+ ## Installation
6
+
7
+ `yarn add @metamask/assets-controllers`
8
+
9
+ or
10
+
11
+ `npm install @metamask/assets-controllers`
12
+
13
+ ## Controllers
14
+
15
+ This package features the following controllers:
16
+
17
+ - [**AccountTrackerController**](src/AccountTrackerController.ts) keeps a updated list of the accounts in the currently selected keychain which is updated automatically on a schedule or on demand.
18
+ - [**AssetsContractController**](src/AssetsContractController.ts) provides a set of convenience methods that use contracts to retrieve information about tokens, read token balances, and transfer tokens.
19
+ - [**CollectibleDetectionController**](src/CollectibleDetectionController.ts) keeps a periodically updated list of ERC-721 tokens assigned to the currently selected address.
20
+ - [**CollectiblesController**](src/CollectiblesController.ts) tracks ERC-721 and ERC-1155 tokens assigned to the currently selected address, using OpenSea to retrieve token information.
21
+ - [**CurrencyRateController**](src/CurrencyRateController.ts) keeps a periodically updated value of the exchange rate from the currently selected "native" currency to another (handling testnet tokens specially).
22
+ - [**TokenBalancesController**](src/TokenBalancesController.ts) keeps a periodically updated set of balances for the current set of ERC-20 tokens.
23
+ - [**TokenDetectionController**](src/TokenDetectionController.ts) keeps a periodically updated list of ERC-20 tokens assigned to the currently selected address.
24
+ - [**TokenListController**](src/TokenListController.ts) uses the MetaSwap API to keep a periodically updated list of known ERC-20 tokens along with their metadata.
25
+ - [**TokenRatesController**](src/TokenRatesController.ts) keeps a periodically updated list of exchange rates for known ERC-20 tokens relative to the currently selected native currency.
26
+ - [**TokensController**](src/TokensController.ts) stores the ERC-20 and ERC-721 tokens, along with their metadata, that are listed in the wallet under the currently selected address on the currently selected chain.
27
+
28
+ ## Contributing
29
+
30
+ This package is part of a monorepo. Instructions for contributing can be found in the [monorepo README](https://github.com/MetaMask/core#readme).
@@ -0,0 +1,106 @@
1
+ import type { BaseConfig, BaseState } from '@metamask/base-controller';
2
+ import { BaseController } from '@metamask/base-controller';
3
+ import type { Provider } from '@metamask/eth-query';
4
+ import type { PreferencesState } from '@metamask/preferences-controller';
5
+ /**
6
+ * @type AccountInformation
7
+ *
8
+ * Account information object
9
+ * @property balance - Hex string of an account balancec in wei
10
+ */
11
+ export interface AccountInformation {
12
+ balance: string;
13
+ }
14
+ /**
15
+ * @type AccountTrackerConfig
16
+ *
17
+ * Account tracker controller configuration
18
+ * @property provider - Provider used to create a new underlying EthQuery instance
19
+ */
20
+ export interface AccountTrackerConfig extends BaseConfig {
21
+ interval: number;
22
+ provider?: Provider;
23
+ }
24
+ /**
25
+ * @type AccountTrackerState
26
+ *
27
+ * Account tracker controller state
28
+ * @property accounts - Map of addresses to account information
29
+ */
30
+ export interface AccountTrackerState extends BaseState {
31
+ accounts: {
32
+ [address: string]: AccountInformation;
33
+ };
34
+ }
35
+ /**
36
+ * Controller that tracks the network balances for all user accounts.
37
+ */
38
+ export declare class AccountTrackerController extends BaseController<AccountTrackerConfig, AccountTrackerState> {
39
+ private ethQuery?;
40
+ private readonly mutex;
41
+ private handle?;
42
+ private syncAccounts;
43
+ /**
44
+ * Name of this controller used during composition
45
+ */
46
+ name: string;
47
+ private readonly getIdentities;
48
+ private readonly getSelectedAddress;
49
+ private readonly getMultiAccountBalancesEnabled;
50
+ /**
51
+ * Creates an AccountTracker instance.
52
+ *
53
+ * @param options - The controller options.
54
+ * @param options.onPreferencesStateChange - Allows subscribing to preference controller state changes.
55
+ * @param options.getIdentities - Gets the identities from the Preferences store.
56
+ * @param options.getSelectedAddress - Gets the selected address from the Preferences store.
57
+ * @param options.getMultiAccountBalancesEnabled - Gets the multi account balances enabled flag from the Preferences store.
58
+ * @param config - Initial options used to configure this controller.
59
+ * @param state - Initial state to set on this controller.
60
+ */
61
+ constructor({ onPreferencesStateChange, getIdentities, getSelectedAddress, getMultiAccountBalancesEnabled, }: {
62
+ onPreferencesStateChange: (listener: (preferencesState: PreferencesState) => void) => void;
63
+ getIdentities: () => PreferencesState['identities'];
64
+ getSelectedAddress: () => PreferencesState['selectedAddress'];
65
+ getMultiAccountBalancesEnabled: () => PreferencesState['isMultiAccountBalancesEnabled'];
66
+ }, config?: Partial<AccountTrackerConfig>, state?: Partial<AccountTrackerState>);
67
+ /**
68
+ * Sets a new provider.
69
+ *
70
+ * TODO: Replace this wth a method.
71
+ *
72
+ * @param provider - Provider used to create a new underlying EthQuery instance.
73
+ */
74
+ set provider(provider: Provider);
75
+ get provider(): Provider;
76
+ /**
77
+ * Starts a new polling interval.
78
+ *
79
+ * @param interval - Polling interval trigger a 'refresh'.
80
+ */
81
+ poll(interval?: number): Promise<void>;
82
+ /**
83
+ * Refreshes the balances of the accounts depending on the multi-account setting.
84
+ * If multi-account is disabled, only updates the selected account balance.
85
+ * If multi-account is enabled, updates balances for all accounts.
86
+ */
87
+ refresh: () => Promise<void>;
88
+ /**
89
+ * Fetches the balance of a given address from the blockchain.
90
+ *
91
+ * @param address - The account address to fetch the balance for.
92
+ * @returns A promise that resolves to the balance in a hex string format.
93
+ */
94
+ private getBalanceFromChain;
95
+ /**
96
+ * Sync accounts balances with some additional addresses.
97
+ *
98
+ * @param addresses - the additional addresses, may be hardware wallet addresses.
99
+ * @returns accounts - addresses with synced balance
100
+ */
101
+ syncBalanceWithAddresses(addresses: string[]): Promise<Record<string, {
102
+ balance: string;
103
+ }>>;
104
+ }
105
+ export default AccountTrackerController;
106
+ //# sourceMappingURL=AccountTrackerController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AccountTrackerController.d.ts","sourceRoot":"","sources":["../src/AccountTrackerController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAO3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAIzE;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAqB,SAAQ,UAAU;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAoB,SAAQ,SAAS;IACpD,QAAQ,EAAE;QAAE,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,CAAA;KAAE,CAAC;CACrD;AAED;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,cAAc,CAC1D,oBAAoB,EACpB,mBAAmB,CACpB;IACC,OAAO,CAAC,QAAQ,CAAC,CAAW;IAE5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IAErC,OAAO,CAAC,MAAM,CAAC,CAAgC;IAE/C,OAAO,CAAC,YAAY;IAoBpB;;OAEG;IACM,IAAI,SAA8B;IAE3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAuC;IAErE,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA4C;IAE/E,OAAO,CAAC,QAAQ,CAAC,8BAA8B,CAA0D;IAEzG;;;;;;;;;;OAUG;gBAED,EACE,wBAAwB,EACxB,aAAa,EACb,kBAAkB,EAClB,8BAA8B,GAC/B,EAAE;QACD,wBAAwB,EAAE,CACxB,QAAQ,EAAE,CAAC,gBAAgB,EAAE,gBAAgB,KAAK,IAAI,KACnD,IAAI,CAAC;QACV,aAAa,EAAE,MAAM,gBAAgB,CAAC,YAAY,CAAC,CAAC;QACpD,kBAAkB,EAAE,MAAM,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;QAC9D,8BAA8B,EAAE,MAAM,gBAAgB,CAAC,+BAA+B,CAAC,CAAC;KACzF,EACD,MAAM,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,EACtC,KAAK,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC;IAiBtC;;;;;;OAMG;IACH,IAAI,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAE9B;IAED,IAAI,QAAQ,IAJW,QAAQ,CAM9B;IAED;;;;OAIG;IACG,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW5C;;;;OAIG;IACH,OAAO,sBAgBL;IAEF;;;;;OAKG;YACW,mBAAmB;IASjC;;;;;OAKG;IACG,wBAAwB,CAC5B,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAyBhD;AAED,eAAe,wBAAwB,CAAC"}
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.AccountTrackerController = void 0;
16
+ const base_controller_1 = require("@metamask/base-controller");
17
+ const controller_utils_1 = require("@metamask/controller-utils");
18
+ const eth_query_1 = __importDefault(require("@metamask/eth-query"));
19
+ const utils_1 = require("@metamask/utils");
20
+ const async_mutex_1 = require("async-mutex");
21
+ /**
22
+ * Controller that tracks the network balances for all user accounts.
23
+ */
24
+ class AccountTrackerController extends base_controller_1.BaseController {
25
+ /**
26
+ * Creates an AccountTracker instance.
27
+ *
28
+ * @param options - The controller options.
29
+ * @param options.onPreferencesStateChange - Allows subscribing to preference controller state changes.
30
+ * @param options.getIdentities - Gets the identities from the Preferences store.
31
+ * @param options.getSelectedAddress - Gets the selected address from the Preferences store.
32
+ * @param options.getMultiAccountBalancesEnabled - Gets the multi account balances enabled flag from the Preferences store.
33
+ * @param config - Initial options used to configure this controller.
34
+ * @param state - Initial state to set on this controller.
35
+ */
36
+ constructor({ onPreferencesStateChange, getIdentities, getSelectedAddress, getMultiAccountBalancesEnabled, }, config, state) {
37
+ super(config, state);
38
+ this.mutex = new async_mutex_1.Mutex();
39
+ /**
40
+ * Name of this controller used during composition
41
+ */
42
+ this.name = 'AccountTrackerController';
43
+ /**
44
+ * Refreshes the balances of the accounts depending on the multi-account setting.
45
+ * If multi-account is disabled, only updates the selected account balance.
46
+ * If multi-account is enabled, updates balances for all accounts.
47
+ */
48
+ this.refresh = () => __awaiter(this, void 0, void 0, function* () {
49
+ this.syncAccounts();
50
+ const accounts = Object.assign({}, this.state.accounts);
51
+ const isMultiAccountBalancesEnabled = this.getMultiAccountBalancesEnabled();
52
+ const accountsToUpdate = isMultiAccountBalancesEnabled
53
+ ? Object.keys(accounts)
54
+ : [this.getSelectedAddress()];
55
+ for (const address of accountsToUpdate) {
56
+ accounts[address] = {
57
+ balance: (0, controller_utils_1.BNToHex)(yield this.getBalanceFromChain(address)),
58
+ };
59
+ }
60
+ this.update({ accounts });
61
+ });
62
+ this.defaultConfig = {
63
+ interval: 10000,
64
+ };
65
+ this.defaultState = { accounts: {} };
66
+ this.initialize();
67
+ this.getIdentities = getIdentities;
68
+ this.getSelectedAddress = getSelectedAddress;
69
+ this.getMultiAccountBalancesEnabled = getMultiAccountBalancesEnabled;
70
+ onPreferencesStateChange(() => {
71
+ this.refresh();
72
+ });
73
+ this.poll();
74
+ }
75
+ syncAccounts() {
76
+ const { accounts } = this.state;
77
+ const addresses = Object.keys(this.getIdentities());
78
+ const existing = Object.keys(accounts);
79
+ const newAddresses = addresses.filter((address) => !existing.includes(address));
80
+ const oldAddresses = existing.filter((address) => !addresses.includes(address));
81
+ newAddresses.forEach((address) => {
82
+ accounts[address] = { balance: '0x0' };
83
+ });
84
+ oldAddresses.forEach((address) => {
85
+ delete accounts[address];
86
+ });
87
+ this.update({ accounts: Object.assign({}, accounts) });
88
+ }
89
+ /**
90
+ * Sets a new provider.
91
+ *
92
+ * TODO: Replace this wth a method.
93
+ *
94
+ * @param provider - Provider used to create a new underlying EthQuery instance.
95
+ */
96
+ set provider(provider) {
97
+ this.ethQuery = new eth_query_1.default(provider);
98
+ }
99
+ get provider() {
100
+ throw new Error('Property only used for setting');
101
+ }
102
+ /**
103
+ * Starts a new polling interval.
104
+ *
105
+ * @param interval - Polling interval trigger a 'refresh'.
106
+ */
107
+ poll(interval) {
108
+ return __awaiter(this, void 0, void 0, function* () {
109
+ const releaseLock = yield this.mutex.acquire();
110
+ interval && this.configure({ interval }, false, false);
111
+ this.handle && clearTimeout(this.handle);
112
+ yield this.refresh();
113
+ this.handle = setTimeout(() => {
114
+ releaseLock();
115
+ this.poll(this.config.interval);
116
+ }, this.config.interval);
117
+ });
118
+ }
119
+ /**
120
+ * Fetches the balance of a given address from the blockchain.
121
+ *
122
+ * @param address - The account address to fetch the balance for.
123
+ * @returns A promise that resolves to the balance in a hex string format.
124
+ */
125
+ getBalanceFromChain(address) {
126
+ return __awaiter(this, void 0, void 0, function* () {
127
+ return yield (0, controller_utils_1.safelyExecuteWithTimeout)(() => __awaiter(this, void 0, void 0, function* () {
128
+ (0, utils_1.assert)(this.ethQuery, 'Provider not set.');
129
+ return yield (0, controller_utils_1.query)(this.ethQuery, 'getBalance', [address]);
130
+ }));
131
+ });
132
+ }
133
+ /**
134
+ * Sync accounts balances with some additional addresses.
135
+ *
136
+ * @param addresses - the additional addresses, may be hardware wallet addresses.
137
+ * @returns accounts - addresses with synced balance
138
+ */
139
+ syncBalanceWithAddresses(addresses) {
140
+ return __awaiter(this, void 0, void 0, function* () {
141
+ return yield Promise.all(addresses.map((address) => {
142
+ return (0, controller_utils_1.safelyExecuteWithTimeout)(() => __awaiter(this, void 0, void 0, function* () {
143
+ (0, utils_1.assert)(this.ethQuery, 'Provider not set.');
144
+ const balance = yield (0, controller_utils_1.query)(this.ethQuery, 'getBalance', [address]);
145
+ return [address, balance];
146
+ }));
147
+ })).then((value) => {
148
+ return value.reduce((obj, item) => {
149
+ if (!item) {
150
+ return obj;
151
+ }
152
+ const [address, balance] = item;
153
+ return Object.assign(Object.assign({}, obj), { [address]: {
154
+ balance,
155
+ } });
156
+ }, {});
157
+ });
158
+ });
159
+ }
160
+ }
161
+ exports.AccountTrackerController = AccountTrackerController;
162
+ exports.default = AccountTrackerController;
163
+ //# sourceMappingURL=AccountTrackerController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AccountTrackerController.js","sourceRoot":"","sources":["../src/AccountTrackerController.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BaseConfig, BaseState } from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport {\n BNToHex,\n query,\n safelyExecuteWithTimeout,\n} from '@metamask/controller-utils';\nimport EthQuery from '@metamask/eth-query';\nimport type { Provider } from '@metamask/eth-query';\nimport type { PreferencesState } from '@metamask/preferences-controller';\nimport { assert } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\n\n/**\n * @type AccountInformation\n *\n * Account information object\n * @property balance - Hex string of an account balancec in wei\n */\nexport interface AccountInformation {\n balance: string;\n}\n\n/**\n * @type AccountTrackerConfig\n *\n * Account tracker controller configuration\n * @property provider - Provider used to create a new underlying EthQuery instance\n */\nexport interface AccountTrackerConfig extends BaseConfig {\n interval: number;\n provider?: Provider;\n}\n\n/**\n * @type AccountTrackerState\n *\n * Account tracker controller state\n * @property accounts - Map of addresses to account information\n */\nexport interface AccountTrackerState extends BaseState {\n accounts: { [address: string]: AccountInformation };\n}\n\n/**\n * Controller that tracks the network balances for all user accounts.\n */\nexport class AccountTrackerController extends BaseController<\n AccountTrackerConfig,\n AccountTrackerState\n> {\n private ethQuery?: EthQuery;\n\n private readonly mutex = new Mutex();\n\n private handle?: ReturnType<typeof setTimeout>;\n\n private syncAccounts() {\n const { accounts } = this.state;\n const addresses = Object.keys(this.getIdentities());\n const existing = Object.keys(accounts);\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\n oldAddresses.forEach((address) => {\n delete accounts[address];\n });\n this.update({ accounts: { ...accounts } });\n }\n\n /**\n * Name of this controller used during composition\n */\n override name = 'AccountTrackerController';\n\n private readonly getIdentities: () => PreferencesState['identities'];\n\n private readonly getSelectedAddress: () => PreferencesState['selectedAddress'];\n\n private readonly getMultiAccountBalancesEnabled: () => PreferencesState['isMultiAccountBalancesEnabled'];\n\n /**\n * Creates an AccountTracker instance.\n *\n * @param options - The controller options.\n * @param options.onPreferencesStateChange - Allows subscribing to preference controller state changes.\n * @param options.getIdentities - Gets the identities from the Preferences store.\n * @param options.getSelectedAddress - Gets the selected address from the Preferences store.\n * @param options.getMultiAccountBalancesEnabled - Gets the multi account balances enabled flag from the Preferences store.\n * @param config - Initial options used to configure this controller.\n * @param state - Initial state to set on this controller.\n */\n constructor(\n {\n onPreferencesStateChange,\n getIdentities,\n getSelectedAddress,\n getMultiAccountBalancesEnabled,\n }: {\n onPreferencesStateChange: (\n listener: (preferencesState: PreferencesState) => void,\n ) => void;\n getIdentities: () => PreferencesState['identities'];\n getSelectedAddress: () => PreferencesState['selectedAddress'];\n getMultiAccountBalancesEnabled: () => PreferencesState['isMultiAccountBalancesEnabled'];\n },\n config?: Partial<AccountTrackerConfig>,\n state?: Partial<AccountTrackerState>,\n ) {\n super(config, state);\n this.defaultConfig = {\n interval: 10000,\n };\n this.defaultState = { accounts: {} };\n this.initialize();\n this.getIdentities = getIdentities;\n this.getSelectedAddress = getSelectedAddress;\n this.getMultiAccountBalancesEnabled = getMultiAccountBalancesEnabled;\n onPreferencesStateChange(() => {\n this.refresh();\n });\n this.poll();\n }\n\n /**\n * Sets a new provider.\n *\n * TODO: Replace this wth a method.\n *\n * @param provider - Provider used to create a new underlying EthQuery instance.\n */\n set provider(provider: Provider) {\n this.ethQuery = new EthQuery(provider);\n }\n\n get provider() {\n throw new Error('Property only used for setting');\n }\n\n /**\n * Starts a new polling interval.\n *\n * @param interval - Polling interval trigger a 'refresh'.\n */\n async poll(interval?: number): Promise<void> {\n const releaseLock = await this.mutex.acquire();\n interval && this.configure({ interval }, false, false);\n this.handle && clearTimeout(this.handle);\n await this.refresh();\n this.handle = setTimeout(() => {\n releaseLock();\n this.poll(this.config.interval);\n }, this.config.interval);\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 refresh = async () => {\n this.syncAccounts();\n const accounts = { ...this.state.accounts };\n const isMultiAccountBalancesEnabled = this.getMultiAccountBalancesEnabled();\n\n const accountsToUpdate = isMultiAccountBalancesEnabled\n ? Object.keys(accounts)\n : [this.getSelectedAddress()];\n\n for (const address of accountsToUpdate) {\n accounts[address] = {\n balance: BNToHex(await this.getBalanceFromChain(address)),\n };\n }\n\n this.update({ accounts });\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 * @returns A promise that resolves to the balance in a hex string format.\n */\n private async getBalanceFromChain(\n address: string,\n ): Promise<string | undefined> {\n return await safelyExecuteWithTimeout(async () => {\n assert(this.ethQuery, 'Provider not set.');\n return await query(this.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 * @returns accounts - addresses with synced balance\n */\n async syncBalanceWithAddresses(\n addresses: string[],\n ): Promise<Record<string, { balance: string }>> {\n return await Promise.all(\n addresses.map((address): Promise<[string, string] | undefined> => {\n return safelyExecuteWithTimeout(async () => {\n assert(this.ethQuery, 'Provider not set.');\n const balance = await query(this.ethQuery, 'getBalance', [address]);\n return [address, balance];\n });\n }),\n ).then((value) => {\n return value.reduce((obj, item) => {\n if (!item) {\n return obj;\n }\n\n const [address, balance] = item;\n return {\n ...obj,\n [address]: {\n balance,\n },\n };\n }, {});\n });\n }\n}\n\nexport default AccountTrackerController;\n"]}