@metamask/assets-controllers 25.0.0 → 27.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/CHANGELOG.md +210 -39
  2. package/dist/AccountTrackerController.js +9 -236
  3. package/dist/AccountTrackerController.js.map +1 -1
  4. package/dist/AccountTrackerController.mjs +10 -0
  5. package/dist/AccountTrackerController.mjs.map +1 -0
  6. package/dist/AssetsContractController.js +17 -385
  7. package/dist/AssetsContractController.js.map +1 -1
  8. package/dist/AssetsContractController.mjs +18 -0
  9. package/dist/AssetsContractController.mjs.map +1 -0
  10. package/dist/CurrencyRateController.js +10 -157
  11. package/dist/CurrencyRateController.js.map +1 -1
  12. package/dist/CurrencyRateController.mjs +11 -0
  13. package/dist/CurrencyRateController.mjs.map +1 -0
  14. package/dist/NftController.js +15 -1039
  15. package/dist/NftController.js.map +1 -1
  16. package/dist/NftController.mjs +16 -0
  17. package/dist/NftController.mjs.map +1 -0
  18. package/dist/NftDetectionController.js +12 -215
  19. package/dist/NftDetectionController.js.map +1 -1
  20. package/dist/NftDetectionController.mjs +13 -0
  21. package/dist/NftDetectionController.mjs.map +1 -0
  22. package/dist/Standards/ERC20Standard.js +8 -144
  23. package/dist/Standards/ERC20Standard.js.map +1 -1
  24. package/dist/Standards/ERC20Standard.mjs +9 -0
  25. package/dist/Standards/ERC20Standard.mjs.map +1 -0
  26. package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.js +8 -217
  27. package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.js.map +1 -1
  28. package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.mjs +9 -0
  29. package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.mjs.map +1 -0
  30. package/dist/Standards/NftStandards/ERC721/ERC721Standard.js +8 -175
  31. package/dist/Standards/NftStandards/ERC721/ERC721Standard.js.map +1 -1
  32. package/dist/Standards/NftStandards/ERC721/ERC721Standard.mjs +9 -0
  33. package/dist/Standards/NftStandards/ERC721/ERC721Standard.mjs.map +1 -0
  34. package/dist/TokenBalancesController.js +11 -144
  35. package/dist/TokenBalancesController.js.map +1 -1
  36. package/dist/TokenBalancesController.mjs +12 -0
  37. package/dist/TokenBalancesController.mjs.map +1 -0
  38. package/dist/TokenDetectionController.js +16 -245
  39. package/dist/TokenDetectionController.js.map +1 -1
  40. package/dist/TokenDetectionController.mjs +17 -0
  41. package/dist/TokenDetectionController.mjs.map +1 -0
  42. package/dist/TokenListController.js +13 -250
  43. package/dist/TokenListController.js.map +1 -1
  44. package/dist/TokenListController.mjs +14 -0
  45. package/dist/TokenListController.mjs.map +1 -0
  46. package/dist/TokenRatesController.js +11 -328
  47. package/dist/TokenRatesController.js.map +1 -1
  48. package/dist/TokenRatesController.mjs +12 -0
  49. package/dist/TokenRatesController.mjs.map +1 -0
  50. package/dist/TokensController.js +15 -636
  51. package/dist/TokensController.js.map +1 -1
  52. package/dist/TokensController.mjs +16 -0
  53. package/dist/TokensController.mjs.map +1 -0
  54. package/dist/assetsUtil.js +41 -380
  55. package/dist/assetsUtil.js.map +1 -1
  56. package/dist/assetsUtil.mjs +42 -0
  57. package/dist/assetsUtil.mjs.map +1 -0
  58. package/dist/chunk-23F5W3A2.mjs +157 -0
  59. package/dist/chunk-23F5W3A2.mjs.map +1 -0
  60. package/dist/chunk-27KOXCQK.mjs +1 -0
  61. package/dist/chunk-27KOXCQK.mjs.map +1 -0
  62. package/dist/chunk-3FMWI46J.mjs +361 -0
  63. package/dist/chunk-3FMWI46J.mjs.map +1 -0
  64. package/dist/chunk-3FOTFZIL.mjs +411 -0
  65. package/dist/chunk-3FOTFZIL.mjs.map +1 -0
  66. package/dist/chunk-4LY47RPI.mjs +139 -0
  67. package/dist/chunk-4LY47RPI.mjs.map +1 -0
  68. package/dist/chunk-5C7ZVZNM.mjs +267 -0
  69. package/dist/chunk-5C7ZVZNM.mjs.map +1 -0
  70. package/dist/chunk-64EHFYLM.mjs +245 -0
  71. package/dist/chunk-64EHFYLM.mjs.map +1 -0
  72. package/dist/chunk-6C2ZIK7A.js +245 -0
  73. package/dist/chunk-6C2ZIK7A.js.map +1 -0
  74. package/dist/chunk-6DTCHPBB.mjs +178 -0
  75. package/dist/chunk-6DTCHPBB.mjs.map +1 -0
  76. package/dist/chunk-74IP34EL.js +1177 -0
  77. package/dist/chunk-74IP34EL.js.map +1 -0
  78. package/dist/chunk-BZI7P3TD.js +115 -0
  79. package/dist/chunk-BZI7P3TD.js.map +1 -0
  80. package/dist/chunk-C4PQK53K.js +32 -0
  81. package/dist/chunk-C4PQK53K.js.map +1 -0
  82. package/dist/chunk-CP3HC7AQ.mjs +12 -0
  83. package/dist/chunk-CP3HC7AQ.mjs.map +1 -0
  84. package/dist/chunk-GHZX5DE4.js +215 -0
  85. package/dist/chunk-GHZX5DE4.js.map +1 -0
  86. package/dist/chunk-GMKIOYCB.js +361 -0
  87. package/dist/chunk-GMKIOYCB.js.map +1 -0
  88. package/dist/chunk-H6TOSWUM.js +157 -0
  89. package/dist/chunk-H6TOSWUM.js.map +1 -0
  90. package/dist/chunk-HWFBJFHS.js +284 -0
  91. package/dist/chunk-HWFBJFHS.js.map +1 -0
  92. package/dist/chunk-J2JQQNHN.mjs +115 -0
  93. package/dist/chunk-J2JQQNHN.mjs.map +1 -0
  94. package/dist/chunk-J6HPEQL3.mjs +704 -0
  95. package/dist/chunk-J6HPEQL3.mjs.map +1 -0
  96. package/dist/chunk-JC4WAN2J.mjs +1177 -0
  97. package/dist/chunk-JC4WAN2J.mjs.map +1 -0
  98. package/dist/chunk-LD4GC7OR.js +139 -0
  99. package/dist/chunk-LD4GC7OR.js.map +1 -0
  100. package/dist/chunk-NG2UOKDD.js +178 -0
  101. package/dist/chunk-NG2UOKDD.js.map +1 -0
  102. package/dist/chunk-NGIXA5M5.mjs +418 -0
  103. package/dist/chunk-NGIXA5M5.mjs.map +1 -0
  104. package/dist/chunk-NLNXQHAU.js +704 -0
  105. package/dist/chunk-NLNXQHAU.js.map +1 -0
  106. package/dist/chunk-OBUR4TXH.js +1 -0
  107. package/dist/chunk-OBUR4TXH.js.map +1 -0
  108. package/dist/chunk-PAJTKWEC.mjs +246 -0
  109. package/dist/chunk-PAJTKWEC.mjs.map +1 -0
  110. package/dist/chunk-PRIXT2R6.js +411 -0
  111. package/dist/chunk-PRIXT2R6.js.map +1 -0
  112. package/dist/chunk-PUFSYRJZ.js +74 -0
  113. package/dist/chunk-PUFSYRJZ.js.map +1 -0
  114. package/dist/chunk-QHRPRO5U.mjs +74 -0
  115. package/dist/chunk-QHRPRO5U.mjs.map +1 -0
  116. package/dist/chunk-QR4CX2JT.mjs +284 -0
  117. package/dist/chunk-QR4CX2JT.mjs.map +1 -0
  118. package/dist/chunk-RGHTNZQ6.js +12 -0
  119. package/dist/chunk-RGHTNZQ6.js.map +1 -0
  120. package/dist/chunk-TCO22VIO.mjs +32 -0
  121. package/dist/chunk-TCO22VIO.mjs.map +1 -0
  122. package/dist/chunk-TDKCVCGP.mjs +215 -0
  123. package/dist/chunk-TDKCVCGP.mjs.map +1 -0
  124. package/dist/chunk-UAH5YURZ.js +343 -0
  125. package/dist/chunk-UAH5YURZ.js.map +1 -0
  126. package/dist/chunk-V4ZO3F2S.js +246 -0
  127. package/dist/chunk-V4ZO3F2S.js.map +1 -0
  128. package/dist/chunk-VDJBJAUB.js +418 -0
  129. package/dist/chunk-VDJBJAUB.js.map +1 -0
  130. package/dist/chunk-WRQ7POD7.mjs +343 -0
  131. package/dist/chunk-WRQ7POD7.mjs.map +1 -0
  132. package/dist/chunk-XUI43LEZ.mjs +30 -0
  133. package/dist/chunk-XUI43LEZ.mjs.map +1 -0
  134. package/dist/chunk-YD3NRMFC.js +267 -0
  135. package/dist/chunk-YD3NRMFC.js.map +1 -0
  136. package/dist/chunk-Z4BLTVTB.js +30 -0
  137. package/dist/chunk-Z4BLTVTB.js.map +1 -0
  138. package/dist/constants.js +7 -9
  139. package/dist/constants.js.map +1 -1
  140. package/dist/constants.mjs +8 -0
  141. package/dist/constants.mjs.map +1 -0
  142. package/dist/crypto-compare.js +7 -66
  143. package/dist/crypto-compare.js.map +1 -1
  144. package/dist/crypto-compare.mjs +8 -0
  145. package/dist/crypto-compare.mjs.map +1 -0
  146. package/dist/index.js +72 -36
  147. package/dist/index.js.map +1 -1
  148. package/dist/index.mjs +73 -0
  149. package/dist/index.mjs.map +1 -0
  150. package/dist/token-prices-service/abstract-token-prices-service.js +1 -3
  151. package/dist/token-prices-service/abstract-token-prices-service.js.map +1 -1
  152. package/dist/token-prices-service/abstract-token-prices-service.mjs +1 -0
  153. package/dist/token-prices-service/abstract-token-prices-service.mjs.map +1 -0
  154. package/dist/token-prices-service/codefi-v2.js +11 -353
  155. package/dist/token-prices-service/codefi-v2.js.map +1 -1
  156. package/dist/token-prices-service/codefi-v2.mjs +12 -0
  157. package/dist/token-prices-service/codefi-v2.mjs.map +1 -0
  158. package/dist/token-prices-service/index.js +8 -5
  159. package/dist/token-prices-service/index.js.map +1 -1
  160. package/dist/token-prices-service/index.mjs +9 -0
  161. package/dist/token-prices-service/index.mjs.map +1 -0
  162. package/dist/token-service.js +14 -133
  163. package/dist/token-service.js.map +1 -1
  164. package/dist/token-service.mjs +15 -0
  165. package/dist/token-service.mjs.map +1 -0
  166. package/dist/tsconfig.build.tsbuildinfo +1 -0
  167. package/dist/types/AccountTrackerController.d.ts.map +1 -0
  168. package/dist/{AssetsContractController.d.ts → types/AssetsContractController.d.ts} +5 -6
  169. package/dist/types/AssetsContractController.d.ts.map +1 -0
  170. package/dist/types/CurrencyRateController.d.ts.map +1 -0
  171. package/dist/types/NftController.d.ts.map +1 -0
  172. package/dist/types/NftDetectionController.d.ts.map +1 -0
  173. package/dist/{Standards → types/Standards}/ERC20Standard.d.ts +1 -2
  174. package/dist/types/Standards/ERC20Standard.d.ts.map +1 -0
  175. package/dist/{Standards → types/Standards}/NftStandards/ERC1155/ERC1155Standard.d.ts +1 -2
  176. package/dist/types/Standards/NftStandards/ERC1155/ERC1155Standard.d.ts.map +1 -0
  177. package/dist/types/Standards/NftStandards/ERC721/ERC721Standard.d.ts.map +1 -0
  178. package/dist/{TokenBalancesController.d.ts → types/TokenBalancesController.d.ts} +12 -10
  179. package/dist/types/TokenBalancesController.d.ts.map +1 -0
  180. package/dist/types/TokenDetectionController.d.ts +111 -0
  181. package/dist/types/TokenDetectionController.d.ts.map +1 -0
  182. package/dist/types/TokenListController.d.ts.map +1 -0
  183. package/dist/types/TokenRatesController.d.ts.map +1 -0
  184. package/dist/{TokensController.d.ts → types/TokensController.d.ts} +26 -19
  185. package/dist/types/TokensController.d.ts.map +1 -0
  186. package/dist/{assetsUtil.d.ts → types/assetsUtil.d.ts} +1 -2
  187. package/dist/types/assetsUtil.d.ts.map +1 -0
  188. package/dist/types/constants.d.ts.map +1 -0
  189. package/dist/types/crypto-compare.d.ts.map +1 -0
  190. package/dist/{index.d.ts → types/index.d.ts} +6 -3
  191. package/dist/types/index.d.ts.map +1 -0
  192. package/dist/types/token-prices-service/abstract-token-prices-service.d.ts.map +1 -0
  193. package/dist/types/token-prices-service/codefi-v2.d.ts.map +1 -0
  194. package/dist/types/token-prices-service/index.d.ts.map +1 -0
  195. package/dist/types/token-service.d.ts.map +1 -0
  196. package/package.json +30 -13
  197. package/dist/AccountTrackerController.d.ts.map +0 -1
  198. package/dist/AssetsContractController.d.ts.map +0 -1
  199. package/dist/CurrencyRateController.d.ts.map +0 -1
  200. package/dist/NftController.d.ts.map +0 -1
  201. package/dist/NftDetectionController.d.ts.map +0 -1
  202. package/dist/Standards/ERC20Standard.d.ts.map +0 -1
  203. package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.d.ts.map +0 -1
  204. package/dist/Standards/NftStandards/ERC721/ERC721Standard.d.ts.map +0 -1
  205. package/dist/Standards/standards-types.d.ts +0 -15
  206. package/dist/Standards/standards-types.d.ts.map +0 -1
  207. package/dist/Standards/standards-types.js +0 -3
  208. package/dist/Standards/standards-types.js.map +0 -1
  209. package/dist/TokenBalancesController.d.ts.map +0 -1
  210. package/dist/TokenDetectionController.d.ts +0 -88
  211. package/dist/TokenDetectionController.d.ts.map +0 -1
  212. package/dist/TokenListController.d.ts.map +0 -1
  213. package/dist/TokenRatesController.d.ts.map +0 -1
  214. package/dist/TokensController.d.ts.map +0 -1
  215. package/dist/assetsUtil.d.ts.map +0 -1
  216. package/dist/constants.d.ts.map +0 -1
  217. package/dist/crypto-compare.d.ts.map +0 -1
  218. package/dist/index.d.ts.map +0 -1
  219. package/dist/token-prices-service/abstract-token-prices-service.d.ts.map +0 -1
  220. package/dist/token-prices-service/codefi-v2.d.ts.map +0 -1
  221. package/dist/token-prices-service/index.d.ts.map +0 -1
  222. package/dist/token-service.d.ts.map +0 -1
  223. /package/dist/{AccountTrackerController.d.ts → types/AccountTrackerController.d.ts} +0 -0
  224. /package/dist/{CurrencyRateController.d.ts → types/CurrencyRateController.d.ts} +0 -0
  225. /package/dist/{NftController.d.ts → types/NftController.d.ts} +0 -0
  226. /package/dist/{NftDetectionController.d.ts → types/NftDetectionController.d.ts} +0 -0
  227. /package/dist/{Standards → types/Standards}/NftStandards/ERC721/ERC721Standard.d.ts +0 -0
  228. /package/dist/{TokenListController.d.ts → types/TokenListController.d.ts} +0 -0
  229. /package/dist/{TokenRatesController.d.ts → types/TokenRatesController.d.ts} +0 -0
  230. /package/dist/{constants.d.ts → types/constants.d.ts} +0 -0
  231. /package/dist/{crypto-compare.d.ts → types/crypto-compare.d.ts} +0 -0
  232. /package/dist/{token-prices-service → types/token-prices-service}/abstract-token-prices-service.d.ts +0 -0
  233. /package/dist/{token-prices-service → types/token-prices-service}/codefi-v2.d.ts +0 -0
  234. /package/dist/{token-prices-service → types/token-prices-service}/index.d.ts +0 -0
  235. /package/dist/{token-service.d.ts → types/token-service.d.ts} +0 -0
@@ -0,0 +1,418 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+ var _chunkC4PQK53Kjs = require('./chunk-C4PQK53K.js');
4
+
5
+
6
+
7
+ var _chunkYD3NRMFCjs = require('./chunk-YD3NRMFC.js');
8
+
9
+
10
+
11
+
12
+
13
+ var _chunkZ4BLTVTBjs = require('./chunk-Z4BLTVTB.js');
14
+
15
+ // src/TokenRatesController.ts
16
+
17
+
18
+
19
+
20
+
21
+ var _controllerutils = require('@metamask/controller-utils');
22
+ var _pollingcontroller = require('@metamask/polling-controller');
23
+ var _utils = require('@metamask/utils');
24
+ var _lodash = require('lodash');
25
+ async function getCurrencyConversionRate({
26
+ from,
27
+ to
28
+ }) {
29
+ const includeUSDRate = false;
30
+ try {
31
+ const result = await _chunkC4PQK53Kjs.fetchExchangeRate.call(void 0,
32
+ to,
33
+ from,
34
+ includeUSDRate
35
+ );
36
+ return result.conversionRate;
37
+ } catch (error) {
38
+ if (error instanceof Error && error.message.includes("market does not exist for this coin pair")) {
39
+ return null;
40
+ }
41
+ throw error;
42
+ }
43
+ }
44
+ var _pollState, _tokenPricesService, _inProcessExchangeRateUpdates, _getTokenAddresses, getTokenAddresses_fn, _stopPoll, stopPoll_fn, _poll, poll_fn, _fetchAndMapExchangeRates, fetchAndMapExchangeRates_fn, _fetchAndMapExchangeRatesForSupportedNativeCurrency, fetchAndMapExchangeRatesForSupportedNativeCurrency_fn, _fetchAndMapExchangeRatesForUnsupportedNativeCurrency, fetchAndMapExchangeRatesForUnsupportedNativeCurrency_fn;
45
+ var TokenRatesController = class extends _pollingcontroller.StaticIntervalPollingControllerV1 {
46
+ /**
47
+ * Creates a TokenRatesController instance.
48
+ *
49
+ * @param options - The controller options.
50
+ * @param options.interval - The polling interval in ms
51
+ * @param options.threshold - The duration in ms before metadata fetched from CoinGecko is considered stale
52
+ * @param options.getNetworkClientById - Gets the network client with the given id from the NetworkController.
53
+ * @param options.chainId - The chain ID of the current network.
54
+ * @param options.ticker - The ticker for the current network.
55
+ * @param options.selectedAddress - The current selected address.
56
+ * @param options.onPreferencesStateChange - Allows subscribing to preference controller state changes.
57
+ * @param options.onTokensStateChange - Allows subscribing to token controller state changes.
58
+ * @param options.onNetworkStateChange - Allows subscribing to network state changes.
59
+ * @param options.tokenPricesService - An object in charge of retrieving token prices.
60
+ * @param config - Initial options used to configure this controller.
61
+ * @param state - Initial state to set on this controller.
62
+ */
63
+ constructor({
64
+ interval = 3 * 60 * 1e3,
65
+ threshold = 6 * 60 * 60 * 1e3,
66
+ getNetworkClientById,
67
+ chainId: initialChainId,
68
+ ticker: initialTicker,
69
+ selectedAddress: initialSelectedAddress,
70
+ onPreferencesStateChange,
71
+ onTokensStateChange,
72
+ onNetworkStateChange,
73
+ tokenPricesService
74
+ }, config, state) {
75
+ super(config, state);
76
+ /**
77
+ * Get the user's tokens for the given chain.
78
+ *
79
+ * @param chainId - The chain ID.
80
+ * @returns The list of tokens addresses for the current chain
81
+ */
82
+ _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _getTokenAddresses);
83
+ /**
84
+ * Clear the active polling timer, if present.
85
+ */
86
+ _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _stopPoll);
87
+ /**
88
+ * Poll for exchange rate updates.
89
+ */
90
+ _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _poll);
91
+ /**
92
+ * Uses the token prices service to retrieve exchange rates for tokens in a
93
+ * particular currency.
94
+ *
95
+ * If the price API does not support the given chain ID, returns an empty
96
+ * object.
97
+ *
98
+ * If the price API does not support the given currency, retrieves exchange
99
+ * rates in a known currency instead, then converts those rates using the
100
+ * exchange rate between the known currency and desired currency.
101
+ *
102
+ * @param args - The arguments to this function.
103
+ * @param args.tokenAddresses - Addresses for tokens.
104
+ * @param args.chainId - The EIP-155 ID of the chain where the tokens live.
105
+ * @param args.nativeCurrency - The native currency in which to request
106
+ * exchange rates.
107
+ * @returns A map from token address to its exchange rate in the native
108
+ * currency, or an empty map if no exchange rates can be obtained for the
109
+ * chain ID.
110
+ */
111
+ _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _fetchAndMapExchangeRates);
112
+ /**
113
+ * Retrieves prices in the given currency for the given tokens on the given
114
+ * chain. Ensures that token addresses are checksum addresses.
115
+ *
116
+ * @param args - The arguments to this function.
117
+ * @param args.tokenAddresses - Addresses for tokens.
118
+ * @param args.chainId - The EIP-155 ID of the chain where the tokens live.
119
+ * @param args.nativeCurrency - The native currency in which to request
120
+ * prices.
121
+ * @returns A map of the token addresses (as checksums) to their prices in the
122
+ * native currency.
123
+ */
124
+ _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _fetchAndMapExchangeRatesForSupportedNativeCurrency);
125
+ /**
126
+ * If the price API does not support a given native currency, then we need to
127
+ * convert it to a fallback currency and feed that currency into the price
128
+ * API, then convert the prices to our desired native currency.
129
+ *
130
+ * @param args - The arguments to this function.
131
+ * @param args.tokenAddresses - Addresses for tokens.
132
+ * @param args.nativeCurrency - The native currency in which to request
133
+ * prices.
134
+ * @returns A map of the token addresses (as checksums) to their prices in the
135
+ * native currency.
136
+ */
137
+ _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _fetchAndMapExchangeRatesForUnsupportedNativeCurrency);
138
+ _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _pollState, "Inactive" /* Inactive */);
139
+ _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _tokenPricesService, void 0);
140
+ _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _inProcessExchangeRateUpdates, {});
141
+ /**
142
+ * Name of this controller used during composition
143
+ */
144
+ this.name = "TokenRatesController";
145
+ this.defaultConfig = {
146
+ interval,
147
+ threshold,
148
+ disabled: false,
149
+ nativeCurrency: initialTicker,
150
+ chainId: initialChainId,
151
+ selectedAddress: initialSelectedAddress,
152
+ allTokens: {},
153
+ // TODO: initialize these correctly, maybe as part of BaseControllerV2 migration
154
+ allDetectedTokens: {}
155
+ };
156
+ this.defaultState = {
157
+ contractExchangeRates: {},
158
+ contractExchangeRatesByChainId: {}
159
+ };
160
+ this.initialize();
161
+ this.setIntervalLength(interval);
162
+ this.getNetworkClientById = getNetworkClientById;
163
+ _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _tokenPricesService, tokenPricesService);
164
+ if (config?.disabled) {
165
+ this.configure({ disabled: true }, false, false);
166
+ }
167
+ onPreferencesStateChange(async ({ selectedAddress }) => {
168
+ if (this.config.selectedAddress !== selectedAddress) {
169
+ this.configure({ selectedAddress });
170
+ if (_chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _pollState) === "Active" /* Active */) {
171
+ await this.updateExchangeRates();
172
+ }
173
+ }
174
+ });
175
+ onTokensStateChange(async ({ allTokens, allDetectedTokens }) => {
176
+ const previousTokenAddresses = _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _getTokenAddresses, getTokenAddresses_fn).call(this, this.config.chainId);
177
+ this.configure({ allTokens, allDetectedTokens });
178
+ const newTokenAddresses = _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _getTokenAddresses, getTokenAddresses_fn).call(this, this.config.chainId);
179
+ if (!_lodash.isEqual.call(void 0, previousTokenAddresses, newTokenAddresses) && _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _pollState) === "Active" /* Active */) {
180
+ await this.updateExchangeRates();
181
+ }
182
+ });
183
+ onNetworkStateChange(async ({ providerConfig }) => {
184
+ const { chainId, ticker } = providerConfig;
185
+ if (this.config.chainId !== chainId || this.config.nativeCurrency !== ticker) {
186
+ this.update({ contractExchangeRates: {} });
187
+ this.configure({ chainId, nativeCurrency: ticker });
188
+ if (_chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _pollState) === "Active" /* Active */) {
189
+ await this.updateExchangeRates();
190
+ }
191
+ }
192
+ });
193
+ }
194
+ /**
195
+ * Start (or restart) polling.
196
+ */
197
+ async start() {
198
+ _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _stopPoll, stopPoll_fn).call(this);
199
+ _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _pollState, "Active" /* Active */);
200
+ await _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _poll, poll_fn).call(this);
201
+ }
202
+ /**
203
+ * Stop polling.
204
+ */
205
+ stop() {
206
+ _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _stopPoll, stopPoll_fn).call(this);
207
+ _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _pollState, "Inactive" /* Inactive */);
208
+ }
209
+ /**
210
+ * Updates exchange rates for all tokens.
211
+ */
212
+ async updateExchangeRates() {
213
+ const { chainId, nativeCurrency } = this.config;
214
+ await this.updateExchangeRatesByChainId({
215
+ chainId,
216
+ nativeCurrency
217
+ });
218
+ }
219
+ /**
220
+ * Updates exchange rates for all tokens.
221
+ *
222
+ * @param options - The options to fetch exchange rates.
223
+ * @param options.chainId - The chain ID.
224
+ * @param options.nativeCurrency - The ticker for the chain.
225
+ */
226
+ async updateExchangeRatesByChainId({
227
+ chainId,
228
+ nativeCurrency
229
+ }) {
230
+ if (this.disabled) {
231
+ return;
232
+ }
233
+ const tokenAddresses = _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _getTokenAddresses, getTokenAddresses_fn).call(this, chainId);
234
+ if (tokenAddresses.length === 0) {
235
+ return;
236
+ }
237
+ const updateKey = `${chainId}:${nativeCurrency}`;
238
+ if (updateKey in _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _inProcessExchangeRateUpdates)) {
239
+ await _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _inProcessExchangeRateUpdates)[updateKey];
240
+ return;
241
+ }
242
+ const {
243
+ promise: inProgressUpdate,
244
+ resolve: updateSucceeded,
245
+ reject: updateFailed
246
+ } = _utils.createDeferredPromise.call(void 0, { suppressUnhandledRejection: true });
247
+ _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _inProcessExchangeRateUpdates)[updateKey] = inProgressUpdate;
248
+ try {
249
+ const newContractExchangeRates = await _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _fetchAndMapExchangeRates, fetchAndMapExchangeRates_fn).call(this, {
250
+ tokenAddresses,
251
+ chainId,
252
+ nativeCurrency
253
+ });
254
+ const existingContractExchangeRates = this.state.contractExchangeRates;
255
+ const updatedContractExchangeRates = chainId === this.config.chainId && nativeCurrency === this.config.nativeCurrency ? newContractExchangeRates : existingContractExchangeRates;
256
+ const existingContractExchangeRatesForChainId = this.state.contractExchangeRatesByChainId[chainId] ?? {};
257
+ const updatedContractExchangeRatesForChainId = {
258
+ ...this.state.contractExchangeRatesByChainId,
259
+ [chainId]: {
260
+ ...existingContractExchangeRatesForChainId,
261
+ [nativeCurrency]: {
262
+ ...existingContractExchangeRatesForChainId[nativeCurrency],
263
+ ...newContractExchangeRates
264
+ }
265
+ }
266
+ };
267
+ this.update({
268
+ contractExchangeRates: updatedContractExchangeRates,
269
+ contractExchangeRatesByChainId: updatedContractExchangeRatesForChainId
270
+ });
271
+ updateSucceeded();
272
+ } catch (error) {
273
+ updateFailed(error);
274
+ throw error;
275
+ } finally {
276
+ delete _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _inProcessExchangeRateUpdates)[updateKey];
277
+ }
278
+ }
279
+ /**
280
+ * Updates token rates for the given networkClientId
281
+ *
282
+ * @param networkClientId - The network client ID used to get a ticker value.
283
+ * @returns The controller state.
284
+ */
285
+ async _executePoll(networkClientId) {
286
+ const networkClient = this.getNetworkClientById(networkClientId);
287
+ await this.updateExchangeRatesByChainId({
288
+ chainId: networkClient.configuration.chainId,
289
+ nativeCurrency: networkClient.configuration.ticker
290
+ });
291
+ }
292
+ };
293
+ _pollState = new WeakMap();
294
+ _tokenPricesService = new WeakMap();
295
+ _inProcessExchangeRateUpdates = new WeakMap();
296
+ _getTokenAddresses = new WeakSet();
297
+ getTokenAddresses_fn = function(chainId) {
298
+ const { allTokens, allDetectedTokens } = this.config;
299
+ const tokens = allTokens[chainId]?.[this.config.selectedAddress] || [];
300
+ const detectedTokens = allDetectedTokens[chainId]?.[this.config.selectedAddress] || [];
301
+ return [
302
+ ...new Set(
303
+ [...tokens, ...detectedTokens].map(
304
+ (token) => _controllerutils.toHex.call(void 0, _controllerutils.toChecksumHexAddress.call(void 0, token.address))
305
+ )
306
+ )
307
+ ].sort();
308
+ };
309
+ _stopPoll = new WeakSet();
310
+ stopPoll_fn = function() {
311
+ if (this.handle) {
312
+ clearTimeout(this.handle);
313
+ }
314
+ };
315
+ _poll = new WeakSet();
316
+ poll_fn = async function() {
317
+ await _controllerutils.safelyExecute.call(void 0, () => this.updateExchangeRates());
318
+ this.handle = setTimeout(() => {
319
+ _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _poll, poll_fn).call(this);
320
+ }, this.config.interval);
321
+ };
322
+ _fetchAndMapExchangeRates = new WeakSet();
323
+ fetchAndMapExchangeRates_fn = async function({
324
+ tokenAddresses,
325
+ chainId,
326
+ nativeCurrency
327
+ }) {
328
+ if (!_chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _tokenPricesService).validateChainIdSupported(chainId)) {
329
+ return tokenAddresses.reduce((obj, tokenAddress) => {
330
+ return {
331
+ ...obj,
332
+ [tokenAddress]: void 0
333
+ };
334
+ }, {});
335
+ }
336
+ if (_chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _tokenPricesService).validateCurrencySupported(nativeCurrency)) {
337
+ return await _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _fetchAndMapExchangeRatesForSupportedNativeCurrency, fetchAndMapExchangeRatesForSupportedNativeCurrency_fn).call(this, {
338
+ tokenAddresses,
339
+ chainId,
340
+ nativeCurrency
341
+ });
342
+ }
343
+ return await _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _fetchAndMapExchangeRatesForUnsupportedNativeCurrency, fetchAndMapExchangeRatesForUnsupportedNativeCurrency_fn).call(this, {
344
+ tokenAddresses,
345
+ nativeCurrency
346
+ });
347
+ };
348
+ _fetchAndMapExchangeRatesForSupportedNativeCurrency = new WeakSet();
349
+ fetchAndMapExchangeRatesForSupportedNativeCurrency_fn = async function({
350
+ tokenAddresses,
351
+ chainId,
352
+ nativeCurrency
353
+ }) {
354
+ const tokenPricesByTokenAddress = await _chunkYD3NRMFCjs.reduceInBatchesSerially.call(void 0, {
355
+ values: [...tokenAddresses].sort(),
356
+ batchSize: _chunkYD3NRMFCjs.TOKEN_PRICES_BATCH_SIZE,
357
+ eachBatch: async (allTokenPricesByTokenAddress, batch) => {
358
+ const tokenPricesByTokenAddressForBatch = await _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _tokenPricesService).fetchTokenPrices({
359
+ tokenAddresses: batch,
360
+ chainId,
361
+ currency: nativeCurrency
362
+ });
363
+ return {
364
+ ...allTokenPricesByTokenAddress,
365
+ ...tokenPricesByTokenAddressForBatch
366
+ };
367
+ },
368
+ initialResult: {}
369
+ });
370
+ return Object.entries(tokenPricesByTokenAddress).reduce(
371
+ (obj, [tokenAddress, tokenPrice]) => {
372
+ return {
373
+ ...obj,
374
+ [tokenAddress]: tokenPrice?.value
375
+ };
376
+ },
377
+ {}
378
+ );
379
+ };
380
+ _fetchAndMapExchangeRatesForUnsupportedNativeCurrency = new WeakSet();
381
+ fetchAndMapExchangeRatesForUnsupportedNativeCurrency_fn = async function({
382
+ tokenAddresses,
383
+ nativeCurrency
384
+ }) {
385
+ const [
386
+ contractExchangeRates,
387
+ fallbackCurrencyToNativeCurrencyConversionRate
388
+ ] = await Promise.all([
389
+ _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _fetchAndMapExchangeRatesForSupportedNativeCurrency, fetchAndMapExchangeRatesForSupportedNativeCurrency_fn).call(this, {
390
+ tokenAddresses,
391
+ chainId: this.config.chainId,
392
+ nativeCurrency: _controllerutils.FALL_BACK_VS_CURRENCY
393
+ }),
394
+ getCurrencyConversionRate({
395
+ from: _controllerutils.FALL_BACK_VS_CURRENCY,
396
+ to: nativeCurrency
397
+ })
398
+ ]);
399
+ if (fallbackCurrencyToNativeCurrencyConversionRate === null) {
400
+ return {};
401
+ }
402
+ return Object.entries(contractExchangeRates).reduce(
403
+ (obj, [tokenAddress, tokenValue]) => {
404
+ return {
405
+ ...obj,
406
+ [tokenAddress]: tokenValue ? tokenValue * fallbackCurrencyToNativeCurrencyConversionRate : void 0
407
+ };
408
+ },
409
+ {}
410
+ );
411
+ };
412
+ var TokenRatesController_default = TokenRatesController;
413
+
414
+
415
+
416
+
417
+ exports.TokenRatesController = TokenRatesController; exports.TokenRatesController_default = TokenRatesController_default;
418
+ //# sourceMappingURL=chunk-VDJBJAUB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/TokenRatesController.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BaseConfig, BaseState } from '@metamask/base-controller';\nimport {\n safelyExecute,\n toChecksumHexAddress,\n FALL_BACK_VS_CURRENCY,\n toHex,\n} from '@metamask/controller-utils';\nimport type {\n NetworkClientId,\n NetworkController,\n NetworkState,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingControllerV1 } from '@metamask/polling-controller';\nimport type { PreferencesState } from '@metamask/preferences-controller';\nimport { createDeferredPromise, type Hex } from '@metamask/utils';\nimport { isEqual } from 'lodash';\n\nimport { reduceInBatchesSerially, TOKEN_PRICES_BATCH_SIZE } from './assetsUtil';\nimport { fetchExchangeRate as fetchNativeCurrencyExchangeRate } from './crypto-compare';\nimport type { AbstractTokenPricesService } from './token-prices-service/abstract-token-prices-service';\nimport type { TokensState } from './TokensController';\n\n/**\n * @type Token\n *\n * Token representation\n * @property address - Hex address of the token contract\n * @property decimals - Number of decimals the token uses\n * @property symbol - Symbol of the token\n * @property image - Image of the token, url or bit32 image\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface Token {\n address: string;\n decimals: number;\n symbol: string;\n aggregators?: string[];\n image?: string;\n balanceError?: unknown;\n isERC721?: boolean;\n name?: string;\n}\n\n/**\n * @type TokenRatesConfig\n *\n * Token rates controller configuration\n * @property interval - Polling interval used to fetch new token rates\n * @property nativeCurrency - Current native currency selected to use base of rates\n * @property chainId - Current network chainId\n * @property tokens - List of tokens to track exchange rates for\n * @property threshold - Threshold to invalidate the supportedChains\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface TokenRatesConfig extends BaseConfig {\n interval: number;\n nativeCurrency: string;\n chainId: Hex;\n selectedAddress: string;\n allTokens: { [chainId: Hex]: { [key: string]: Token[] } };\n allDetectedTokens: { [chainId: Hex]: { [key: string]: Token[] } };\n threshold: number;\n}\n\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface ContractExchangeRates {\n [address: string]: number | undefined;\n}\n\nenum PollState {\n Active = 'Active',\n Inactive = 'Inactive',\n}\n\n/**\n * @type TokenRatesState\n *\n * Token rates controller state\n * @property contractExchangeRates - Hash of token contract addresses to exchange rates (single globally selected chain, will be deprecated soon)\n * @property contractExchangeRatesByChainId - Hash of token contract addresses to exchange rates keyed by chain ID and native currency (ticker)\n */\n// This interface was created before this ESLint rule was added.\n// Convert to a `type` in a future major version.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\nexport interface TokenRatesState extends BaseState {\n contractExchangeRates: ContractExchangeRates;\n contractExchangeRatesByChainId: Record<\n Hex,\n Record<string, ContractExchangeRates>\n >;\n}\n\n/**\n * Uses the CryptoCompare API to fetch the exchange rate between one currency\n * and another, i.e., the multiplier to apply the amount of one currency in\n * order to convert it to another.\n *\n * @param args - The arguments to this function.\n * @param args.from - The currency to convert from.\n * @param args.to - The currency to convert to.\n * @returns The exchange rate between `fromCurrency` to `toCurrency` if one\n * exists, or null if one does not.\n */\nasync function getCurrencyConversionRate({\n from,\n to,\n}: {\n from: string;\n to: string;\n}) {\n const includeUSDRate = false;\n try {\n const result = await fetchNativeCurrencyExchangeRate(\n to,\n from,\n includeUSDRate,\n );\n return result.conversionRate;\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes('market does not exist for this coin pair')\n ) {\n return null;\n }\n throw error;\n }\n}\n\n/**\n * Controller that passively polls on a set interval for token-to-fiat exchange rates\n * for tokens stored in the TokensController\n */\nexport class TokenRatesController extends StaticIntervalPollingControllerV1<\n TokenRatesConfig,\n TokenRatesState\n> {\n private handle?: ReturnType<typeof setTimeout>;\n\n #pollState = PollState.Inactive;\n\n #tokenPricesService: AbstractTokenPricesService;\n\n #inProcessExchangeRateUpdates: Record<`${Hex}:${string}`, Promise<void>> = {};\n\n /**\n * Name of this controller used during composition\n */\n override name = 'TokenRatesController';\n\n private readonly getNetworkClientById: NetworkController['getNetworkClientById'];\n\n /**\n * Creates a TokenRatesController instance.\n *\n * @param options - The controller options.\n * @param options.interval - The polling interval in ms\n * @param options.threshold - The duration in ms before metadata fetched from CoinGecko is considered stale\n * @param options.getNetworkClientById - Gets the network client with the given id from the NetworkController.\n * @param options.chainId - The chain ID of the current network.\n * @param options.ticker - The ticker for the current network.\n * @param options.selectedAddress - The current selected address.\n * @param options.onPreferencesStateChange - Allows subscribing to preference controller state changes.\n * @param options.onTokensStateChange - Allows subscribing to token controller state changes.\n * @param options.onNetworkStateChange - Allows subscribing to network state changes.\n * @param options.tokenPricesService - An object in charge of retrieving token prices.\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 interval = 3 * 60 * 1000,\n threshold = 6 * 60 * 60 * 1000,\n getNetworkClientById,\n chainId: initialChainId,\n ticker: initialTicker,\n selectedAddress: initialSelectedAddress,\n onPreferencesStateChange,\n onTokensStateChange,\n onNetworkStateChange,\n tokenPricesService,\n }: {\n interval?: number;\n threshold?: number;\n getNetworkClientById: NetworkController['getNetworkClientById'];\n chainId: Hex;\n ticker: string;\n selectedAddress: string;\n onPreferencesStateChange: (\n listener: (preferencesState: PreferencesState) => void,\n ) => void;\n onTokensStateChange: (\n listener: (tokensState: TokensState) => void,\n ) => void;\n onNetworkStateChange: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n tokenPricesService: AbstractTokenPricesService;\n },\n config?: Partial<TokenRatesConfig>,\n state?: Partial<TokenRatesState>,\n ) {\n super(config, state);\n this.defaultConfig = {\n interval,\n threshold,\n disabled: false,\n nativeCurrency: initialTicker,\n chainId: initialChainId,\n selectedAddress: initialSelectedAddress,\n allTokens: {}, // TODO: initialize these correctly, maybe as part of BaseControllerV2 migration\n allDetectedTokens: {},\n };\n\n this.defaultState = {\n contractExchangeRates: {},\n contractExchangeRatesByChainId: {},\n };\n this.initialize();\n this.setIntervalLength(interval);\n this.getNetworkClientById = getNetworkClientById;\n this.#tokenPricesService = tokenPricesService;\n\n if (config?.disabled) {\n this.configure({ disabled: true }, false, false);\n }\n\n onPreferencesStateChange(async ({ selectedAddress }) => {\n if (this.config.selectedAddress !== selectedAddress) {\n this.configure({ selectedAddress });\n if (this.#pollState === PollState.Active) {\n await this.updateExchangeRates();\n }\n }\n });\n\n onTokensStateChange(async ({ allTokens, allDetectedTokens }) => {\n const previousTokenAddresses = this.#getTokenAddresses(\n this.config.chainId,\n );\n this.configure({ allTokens, allDetectedTokens });\n const newTokenAddresses = this.#getTokenAddresses(this.config.chainId);\n if (\n !isEqual(previousTokenAddresses, newTokenAddresses) &&\n this.#pollState === PollState.Active\n ) {\n await this.updateExchangeRates();\n }\n });\n\n onNetworkStateChange(async ({ providerConfig }) => {\n const { chainId, ticker } = providerConfig;\n if (\n this.config.chainId !== chainId ||\n this.config.nativeCurrency !== ticker\n ) {\n this.update({ contractExchangeRates: {} });\n this.configure({ chainId, nativeCurrency: ticker });\n if (this.#pollState === PollState.Active) {\n await this.updateExchangeRates();\n }\n }\n });\n }\n\n /**\n * Get the user's tokens for the given chain.\n *\n * @param chainId - The chain ID.\n * @returns The list of tokens addresses for the current chain\n */\n #getTokenAddresses(chainId: Hex): Hex[] {\n const { allTokens, allDetectedTokens } = this.config;\n const tokens = allTokens[chainId]?.[this.config.selectedAddress] || [];\n const detectedTokens =\n allDetectedTokens[chainId]?.[this.config.selectedAddress] || [];\n\n return [\n ...new Set(\n [...tokens, ...detectedTokens].map((token) =>\n toHex(toChecksumHexAddress(token.address)),\n ),\n ),\n ].sort();\n }\n\n /**\n * Start (or restart) polling.\n */\n async start() {\n this.#stopPoll();\n this.#pollState = PollState.Active;\n await this.#poll();\n }\n\n /**\n * Stop polling.\n */\n stop() {\n this.#stopPoll();\n this.#pollState = PollState.Inactive;\n }\n\n /**\n * Clear the active polling timer, if present.\n */\n #stopPoll() {\n if (this.handle) {\n clearTimeout(this.handle);\n }\n }\n\n /**\n * Poll for exchange rate updates.\n */\n async #poll() {\n await safelyExecute(() => this.updateExchangeRates());\n\n // Poll using recursive `setTimeout` instead of `setInterval` so that\n // requests don't stack if they take longer than the polling interval\n this.handle = setTimeout(() => {\n this.#poll();\n }, this.config.interval);\n }\n\n /**\n * Updates exchange rates for all tokens.\n */\n async updateExchangeRates() {\n const { chainId, nativeCurrency } = this.config;\n await this.updateExchangeRatesByChainId({\n chainId,\n nativeCurrency,\n });\n }\n\n /**\n * Updates exchange rates for all tokens.\n *\n * @param options - The options to fetch exchange rates.\n * @param options.chainId - The chain ID.\n * @param options.nativeCurrency - The ticker for the chain.\n */\n async updateExchangeRatesByChainId({\n chainId,\n nativeCurrency,\n }: {\n chainId: Hex;\n nativeCurrency: string;\n }) {\n if (this.disabled) {\n return;\n }\n\n const tokenAddresses = this.#getTokenAddresses(chainId);\n if (tokenAddresses.length === 0) {\n return;\n }\n\n const updateKey: `${Hex}:${string}` = `${chainId}:${nativeCurrency}`;\n if (updateKey in this.#inProcessExchangeRateUpdates) {\n // This prevents redundant updates\n // This promise is resolved after the in-progress update has finished,\n // and state has been updated.\n await this.#inProcessExchangeRateUpdates[updateKey];\n return;\n }\n\n const {\n promise: inProgressUpdate,\n resolve: updateSucceeded,\n reject: updateFailed,\n } = createDeferredPromise({ suppressUnhandledRejection: true });\n this.#inProcessExchangeRateUpdates[updateKey] = inProgressUpdate;\n\n try {\n const newContractExchangeRates = await this.#fetchAndMapExchangeRates({\n tokenAddresses,\n chainId,\n nativeCurrency,\n });\n\n const existingContractExchangeRates = this.state.contractExchangeRates;\n const updatedContractExchangeRates =\n chainId === this.config.chainId &&\n nativeCurrency === this.config.nativeCurrency\n ? newContractExchangeRates\n : existingContractExchangeRates;\n\n const existingContractExchangeRatesForChainId =\n this.state.contractExchangeRatesByChainId[chainId] ?? {};\n const updatedContractExchangeRatesForChainId = {\n ...this.state.contractExchangeRatesByChainId,\n [chainId]: {\n ...existingContractExchangeRatesForChainId,\n [nativeCurrency]: {\n ...existingContractExchangeRatesForChainId[nativeCurrency],\n ...newContractExchangeRates,\n },\n },\n };\n\n this.update({\n contractExchangeRates: updatedContractExchangeRates,\n contractExchangeRatesByChainId: updatedContractExchangeRatesForChainId,\n });\n updateSucceeded();\n } catch (error: unknown) {\n updateFailed(error);\n throw error;\n } finally {\n delete this.#inProcessExchangeRateUpdates[updateKey];\n }\n }\n\n /**\n * Uses the token prices service to retrieve exchange rates for tokens in a\n * particular currency.\n *\n * If the price API does not support the given chain ID, returns an empty\n * object.\n *\n * If the price API does not support the given currency, retrieves exchange\n * rates in a known currency instead, then converts those rates using the\n * exchange rate between the known currency and desired currency.\n *\n * @param args - The arguments to this function.\n * @param args.tokenAddresses - Addresses for tokens.\n * @param args.chainId - The EIP-155 ID of the chain where the tokens live.\n * @param args.nativeCurrency - The native currency in which to request\n * exchange rates.\n * @returns A map from token address to its exchange rate in the native\n * currency, or an empty map if no exchange rates can be obtained for the\n * chain ID.\n */\n async #fetchAndMapExchangeRates({\n tokenAddresses,\n chainId,\n nativeCurrency,\n }: {\n tokenAddresses: Hex[];\n chainId: Hex;\n nativeCurrency: string;\n }): Promise<ContractExchangeRates> {\n if (!this.#tokenPricesService.validateChainIdSupported(chainId)) {\n return tokenAddresses.reduce((obj, tokenAddress) => {\n return {\n ...obj,\n [tokenAddress]: undefined,\n };\n }, {});\n }\n\n if (this.#tokenPricesService.validateCurrencySupported(nativeCurrency)) {\n return await this.#fetchAndMapExchangeRatesForSupportedNativeCurrency({\n tokenAddresses,\n chainId,\n nativeCurrency,\n });\n }\n\n return await this.#fetchAndMapExchangeRatesForUnsupportedNativeCurrency({\n tokenAddresses,\n nativeCurrency,\n });\n }\n\n /**\n * Updates token rates for the given networkClientId\n *\n * @param networkClientId - The network client ID used to get a ticker value.\n * @returns The controller state.\n */\n async _executePoll(networkClientId: NetworkClientId): Promise<void> {\n const networkClient = this.getNetworkClientById(networkClientId);\n await this.updateExchangeRatesByChainId({\n chainId: networkClient.configuration.chainId,\n nativeCurrency: networkClient.configuration.ticker,\n });\n }\n\n /**\n * Retrieves prices in the given currency for the given tokens on the given\n * chain. Ensures that token addresses are checksum addresses.\n *\n * @param args - The arguments to this function.\n * @param args.tokenAddresses - Addresses for tokens.\n * @param args.chainId - The EIP-155 ID of the chain where the tokens live.\n * @param args.nativeCurrency - The native currency in which to request\n * prices.\n * @returns A map of the token addresses (as checksums) to their prices in the\n * native currency.\n */\n async #fetchAndMapExchangeRatesForSupportedNativeCurrency({\n tokenAddresses,\n chainId,\n nativeCurrency,\n }: {\n tokenAddresses: Hex[];\n chainId: Hex;\n nativeCurrency: string;\n }): Promise<ContractExchangeRates> {\n const tokenPricesByTokenAddress = await reduceInBatchesSerially<\n Hex,\n Awaited<ReturnType<AbstractTokenPricesService['fetchTokenPrices']>>\n >({\n values: [...tokenAddresses].sort(),\n batchSize: TOKEN_PRICES_BATCH_SIZE,\n eachBatch: async (allTokenPricesByTokenAddress, batch) => {\n const tokenPricesByTokenAddressForBatch =\n await this.#tokenPricesService.fetchTokenPrices({\n tokenAddresses: batch,\n chainId,\n currency: nativeCurrency,\n });\n\n return {\n ...allTokenPricesByTokenAddress,\n ...tokenPricesByTokenAddressForBatch,\n };\n },\n initialResult: {},\n });\n\n return Object.entries(tokenPricesByTokenAddress).reduce(\n (obj, [tokenAddress, tokenPrice]) => {\n return {\n ...obj,\n [tokenAddress]: tokenPrice?.value,\n };\n },\n {},\n );\n }\n\n /**\n * If the price API does not support a given native currency, then we need to\n * convert it to a fallback currency and feed that currency into the price\n * API, then convert the prices to our desired native currency.\n *\n * @param args - The arguments to this function.\n * @param args.tokenAddresses - Addresses for tokens.\n * @param args.nativeCurrency - The native currency in which to request\n * prices.\n * @returns A map of the token addresses (as checksums) to their prices in the\n * native currency.\n */\n async #fetchAndMapExchangeRatesForUnsupportedNativeCurrency({\n tokenAddresses,\n nativeCurrency,\n }: {\n tokenAddresses: Hex[];\n nativeCurrency: string;\n }): Promise<ContractExchangeRates> {\n const [\n contractExchangeRates,\n fallbackCurrencyToNativeCurrencyConversionRate,\n ] = await Promise.all([\n this.#fetchAndMapExchangeRatesForSupportedNativeCurrency({\n tokenAddresses,\n chainId: this.config.chainId,\n nativeCurrency: FALL_BACK_VS_CURRENCY,\n }),\n getCurrencyConversionRate({\n from: FALL_BACK_VS_CURRENCY,\n to: nativeCurrency,\n }),\n ]);\n\n if (fallbackCurrencyToNativeCurrencyConversionRate === null) {\n return {};\n }\n\n return Object.entries(contractExchangeRates).reduce(\n (obj, [tokenAddress, tokenValue]) => {\n return {\n ...obj,\n [tokenAddress]: tokenValue\n ? tokenValue * fallbackCurrencyToNativeCurrencyConversionRate\n : undefined,\n };\n },\n {},\n );\n }\n}\n\nexport default TokenRatesController;\n"]}