@metamask/assets-controllers 1.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 (58) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/LICENSE +20 -0
  3. package/README.md +30 -0
  4. package/dist/AccountTrackerController.d.ts +88 -0
  5. package/dist/AccountTrackerController.js +138 -0
  6. package/dist/AccountTrackerController.js.map +1 -0
  7. package/dist/AssetsContractController.d.ts +176 -0
  8. package/dist/AssetsContractController.js +314 -0
  9. package/dist/AssetsContractController.js.map +1 -0
  10. package/dist/CurrencyRateController.d.ts +98 -0
  11. package/dist/CurrencyRateController.js +193 -0
  12. package/dist/CurrencyRateController.js.map +1 -0
  13. package/dist/NftController.d.ts +409 -0
  14. package/dist/NftController.js +835 -0
  15. package/dist/NftController.js.map +1 -0
  16. package/dist/NftDetectionController.d.ts +179 -0
  17. package/dist/NftDetectionController.js +204 -0
  18. package/dist/NftDetectionController.js.map +1 -0
  19. package/dist/Standards/ERC20Standard.d.ts +42 -0
  20. package/dist/Standards/ERC20Standard.js +121 -0
  21. package/dist/Standards/ERC20Standard.js.map +1 -0
  22. package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.d.ts +78 -0
  23. package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.js +148 -0
  24. package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.js.map +1 -0
  25. package/dist/Standards/NftStandards/ERC721/ERC721Standard.d.ts +88 -0
  26. package/dist/Standards/NftStandards/ERC721/ERC721Standard.js +182 -0
  27. package/dist/Standards/NftStandards/ERC721/ERC721Standard.js.map +1 -0
  28. package/dist/Standards/standards-types.d.ts +14 -0
  29. package/dist/Standards/standards-types.js +3 -0
  30. package/dist/Standards/standards-types.js.map +1 -0
  31. package/dist/TokenBalancesController.d.ts +69 -0
  32. package/dist/TokenBalancesController.js +94 -0
  33. package/dist/TokenBalancesController.js.map +1 -0
  34. package/dist/TokenDetectionController.d.ts +84 -0
  35. package/dist/TokenDetectionController.js +185 -0
  36. package/dist/TokenDetectionController.js.map +1 -0
  37. package/dist/TokenListController.d.ts +114 -0
  38. package/dist/TokenListController.js +256 -0
  39. package/dist/TokenListController.js.map +1 -0
  40. package/dist/TokenRatesController.d.ts +167 -0
  41. package/dist/TokenRatesController.js +284 -0
  42. package/dist/TokenRatesController.js.map +1 -0
  43. package/dist/TokensController.d.ts +238 -0
  44. package/dist/TokensController.js +530 -0
  45. package/dist/TokensController.js.map +1 -0
  46. package/dist/assetsUtil.d.ts +106 -0
  47. package/dist/assetsUtil.js +228 -0
  48. package/dist/assetsUtil.js.map +1 -0
  49. package/dist/crypto-compare.d.ts +12 -0
  50. package/dist/crypto-compare.js +67 -0
  51. package/dist/crypto-compare.js.map +1 -0
  52. package/dist/index.d.ts +11 -0
  53. package/dist/index.js +31 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/token-service.d.ts +29 -0
  56. package/dist/token-service.js +134 -0
  57. package/dist/token-service.js.map +1 -0
  58. package/package.json +75 -0
@@ -0,0 +1,284 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.TokenRatesController = void 0;
13
+ const base_controller_1 = require("@metamask/base-controller");
14
+ const controller_utils_1 = require("@metamask/controller-utils");
15
+ const crypto_compare_1 = require("./crypto-compare");
16
+ const CoinGeckoApi = {
17
+ BASE_URL: 'https://api.coingecko.com/api/v3',
18
+ getTokenPriceURL(chainSlug, query) {
19
+ return `${this.BASE_URL}/simple/token_price/${chainSlug}?${query}`;
20
+ },
21
+ getPlatformsURL() {
22
+ return `${this.BASE_URL}/asset_platforms`;
23
+ },
24
+ getSupportedVsCurrencies() {
25
+ return `${this.BASE_URL}/simple/supported_vs_currencies`;
26
+ },
27
+ };
28
+ /**
29
+ * Finds the chain slug in the data array given a chainId.
30
+ *
31
+ * @param chainId - The current chain ID.
32
+ * @param data - A list platforms supported by the CoinGecko API.
33
+ * @returns The CoinGecko slug for the given chain ID, or `null` if the slug was not found.
34
+ */
35
+ function findChainSlug(chainId, data) {
36
+ var _a;
37
+ if (!data) {
38
+ return null;
39
+ }
40
+ const chain = (_a = data.find(({ chain_identifier }) => chain_identifier !== null && String(chain_identifier) === chainId)) !== null && _a !== void 0 ? _a : null;
41
+ return (chain === null || chain === void 0 ? void 0 : chain.id) || null;
42
+ }
43
+ /**
44
+ * Controller that passively polls on a set interval for token-to-fiat exchange rates
45
+ * for tokens stored in the TokensController
46
+ */
47
+ class TokenRatesController extends base_controller_1.BaseController {
48
+ /**
49
+ * Creates a TokenRatesController instance.
50
+ *
51
+ * @param options - The controller options.
52
+ * @param options.onTokensStateChange - Allows subscribing to token controller state changes.
53
+ * @param options.onCurrencyRateStateChange - Allows subscribing to currency rate controller state changes.
54
+ * @param options.onNetworkStateChange - Allows subscribing to network state changes.
55
+ * @param config - Initial options used to configure this controller.
56
+ * @param state - Initial state to set on this controller.
57
+ */
58
+ constructor({ onTokensStateChange, onCurrencyRateStateChange, onNetworkStateChange, }, config, state) {
59
+ super(config, state);
60
+ this.tokenList = [];
61
+ this.supportedChains = {
62
+ timestamp: 0,
63
+ data: null,
64
+ };
65
+ this.supportedVsCurrencies = {
66
+ timestamp: 0,
67
+ data: [],
68
+ };
69
+ /**
70
+ * Name of this controller used during composition
71
+ */
72
+ this.name = 'TokenRatesController';
73
+ this.defaultConfig = {
74
+ disabled: true,
75
+ interval: 3 * 60 * 1000,
76
+ nativeCurrency: 'eth',
77
+ chainId: '',
78
+ tokens: [],
79
+ threshold: 6 * 60 * 60 * 1000,
80
+ };
81
+ this.defaultState = {
82
+ contractExchangeRates: {},
83
+ };
84
+ this.initialize();
85
+ this.configure({ disabled: false }, false, false);
86
+ onTokensStateChange(({ tokens, detectedTokens }) => {
87
+ this.configure({ tokens: [...tokens, ...detectedTokens] });
88
+ });
89
+ onCurrencyRateStateChange((currencyRateState) => {
90
+ this.configure({ nativeCurrency: currencyRateState.nativeCurrency });
91
+ });
92
+ onNetworkStateChange(({ provider }) => {
93
+ const { chainId } = provider;
94
+ this.update({ contractExchangeRates: {} });
95
+ this.configure({ chainId });
96
+ });
97
+ this.poll();
98
+ }
99
+ /**
100
+ * Sets a new polling interval.
101
+ *
102
+ * @param interval - Polling interval used to fetch new token rates.
103
+ */
104
+ poll(interval) {
105
+ return __awaiter(this, void 0, void 0, function* () {
106
+ interval && this.configure({ interval }, false, false);
107
+ this.handle && clearTimeout(this.handle);
108
+ yield (0, controller_utils_1.safelyExecute)(() => this.updateExchangeRates());
109
+ this.handle = setTimeout(() => {
110
+ this.poll(this.config.interval);
111
+ }, this.config.interval);
112
+ });
113
+ }
114
+ /**
115
+ * Sets a new chainId.
116
+ *
117
+ * TODO: Replace this with a method.
118
+ *
119
+ * @param _chainId - The current chain ID.
120
+ */
121
+ set chainId(_chainId) {
122
+ !this.disabled && (0, controller_utils_1.safelyExecute)(() => this.updateExchangeRates());
123
+ }
124
+ get chainId() {
125
+ throw new Error('Property only used for setting');
126
+ }
127
+ /**
128
+ * Sets a new token list to track prices.
129
+ *
130
+ * TODO: Replace this with a method.
131
+ *
132
+ * @param tokens - List of tokens to track exchange rates for.
133
+ */
134
+ set tokens(tokens) {
135
+ this.tokenList = tokens;
136
+ !this.disabled && (0, controller_utils_1.safelyExecute)(() => this.updateExchangeRates());
137
+ }
138
+ get tokens() {
139
+ throw new Error('Property only used for setting');
140
+ }
141
+ /**
142
+ * Fetches a pairs of token address and native currency.
143
+ *
144
+ * @param chainSlug - Chain string identifier.
145
+ * @param vsCurrency - Query according to tokens in tokenList and native currency.
146
+ * @returns The exchange rates for the given pairs.
147
+ */
148
+ fetchExchangeRate(chainSlug, vsCurrency) {
149
+ return __awaiter(this, void 0, void 0, function* () {
150
+ const tokenPairs = this.tokenList.map((token) => token.address).join(',');
151
+ const query = `contract_addresses=${tokenPairs}&vs_currencies=${vsCurrency.toLowerCase()}`;
152
+ return (0, controller_utils_1.handleFetch)(CoinGeckoApi.getTokenPriceURL(chainSlug, query));
153
+ });
154
+ }
155
+ /**
156
+ * Checks if the current native currency is a supported vs currency to use
157
+ * to query for token exchange rates.
158
+ *
159
+ * @param nativeCurrency - The native currency of the currently active network.
160
+ * @returns A boolean indicating whether it's a supported vsCurrency.
161
+ */
162
+ checkIsSupportedVsCurrency(nativeCurrency) {
163
+ return __awaiter(this, void 0, void 0, function* () {
164
+ const { threshold } = this.config;
165
+ const { timestamp, data } = this.supportedVsCurrencies;
166
+ const now = Date.now();
167
+ if (now - timestamp > threshold) {
168
+ const currencies = yield (0, controller_utils_1.handleFetch)(CoinGeckoApi.getSupportedVsCurrencies());
169
+ this.supportedVsCurrencies = {
170
+ data: currencies,
171
+ timestamp: Date.now(),
172
+ };
173
+ return currencies.includes(nativeCurrency.toLowerCase());
174
+ }
175
+ return data.includes(nativeCurrency.toLowerCase());
176
+ });
177
+ }
178
+ /**
179
+ * Gets current chain ID slug from cached supported platforms CoinGecko API response.
180
+ * If cached supported platforms response is stale, fetches and updates it.
181
+ *
182
+ * @returns The CoinGecko slug for the current chain ID.
183
+ */
184
+ getChainSlug() {
185
+ return __awaiter(this, void 0, void 0, function* () {
186
+ const { threshold, chainId } = this.config;
187
+ const { data, timestamp } = this.supportedChains;
188
+ const now = Date.now();
189
+ if (now - timestamp > threshold) {
190
+ const platforms = yield (0, controller_utils_1.handleFetch)(CoinGeckoApi.getPlatformsURL());
191
+ this.supportedChains = {
192
+ data: platforms,
193
+ timestamp: Date.now(),
194
+ };
195
+ return findChainSlug(chainId, platforms);
196
+ }
197
+ return findChainSlug(chainId, data);
198
+ });
199
+ }
200
+ /**
201
+ * Updates exchange rates for all tokens.
202
+ */
203
+ updateExchangeRates() {
204
+ return __awaiter(this, void 0, void 0, function* () {
205
+ if (this.tokenList.length === 0 || this.disabled) {
206
+ return;
207
+ }
208
+ const slug = yield this.getChainSlug();
209
+ let newContractExchangeRates = {};
210
+ if (!slug) {
211
+ this.tokenList.forEach((token) => {
212
+ const address = (0, controller_utils_1.toChecksumHexAddress)(token.address);
213
+ newContractExchangeRates[address] = undefined;
214
+ });
215
+ }
216
+ else {
217
+ const { nativeCurrency } = this.config;
218
+ newContractExchangeRates = yield this.fetchAndMapExchangeRates(nativeCurrency, slug);
219
+ }
220
+ this.update({ contractExchangeRates: newContractExchangeRates });
221
+ });
222
+ }
223
+ /**
224
+ * Checks if the active network's native currency is supported by the coingecko API.
225
+ * If supported, it fetches and maps contractExchange rates to a format to be consumed by the UI.
226
+ * If not supported, it fetches contractExchange rates and maps them from token/fallback-currency
227
+ * to token/nativeCurrency.
228
+ *
229
+ * @param nativeCurrency - The native currency of the currently active network.
230
+ * @param slug - The unique slug used to id the chain by the coingecko api
231
+ * should be used to query token exchange rates.
232
+ * @returns An object with conversion rates for each token
233
+ * related to the network's native currency.
234
+ */
235
+ fetchAndMapExchangeRates(nativeCurrency, slug) {
236
+ return __awaiter(this, void 0, void 0, function* () {
237
+ const contractExchangeRates = {};
238
+ // check if native currency is supported as a vs_currency by the API
239
+ const nativeCurrencySupported = yield this.checkIsSupportedVsCurrency(nativeCurrency);
240
+ if (nativeCurrencySupported) {
241
+ // If it is we can do a simple fetch against the CoinGecko API
242
+ const prices = yield this.fetchExchangeRate(slug, nativeCurrency);
243
+ this.tokenList.forEach((token) => {
244
+ const price = prices[token.address.toLowerCase()];
245
+ contractExchangeRates[(0, controller_utils_1.toChecksumHexAddress)(token.address)] = price
246
+ ? price[nativeCurrency.toLowerCase()]
247
+ : 0;
248
+ });
249
+ }
250
+ else {
251
+ // if native currency is not supported we need to use a fallback vsCurrency, get the exchange rates
252
+ // in token/fallback-currency format and convert them to expected token/nativeCurrency format.
253
+ let tokenExchangeRates;
254
+ let vsCurrencyToNativeCurrencyConversionRate = 0;
255
+ try {
256
+ [
257
+ tokenExchangeRates,
258
+ { conversionRate: vsCurrencyToNativeCurrencyConversionRate },
259
+ ] = yield Promise.all([
260
+ this.fetchExchangeRate(slug, controller_utils_1.FALL_BACK_VS_CURRENCY),
261
+ (0, crypto_compare_1.fetchExchangeRate)(nativeCurrency, controller_utils_1.FALL_BACK_VS_CURRENCY, false),
262
+ ]);
263
+ }
264
+ catch (error) {
265
+ if (error instanceof Error &&
266
+ error.message.includes('market does not exist for this coin pair')) {
267
+ return {};
268
+ }
269
+ throw error;
270
+ }
271
+ for (const [tokenAddress, conversion] of Object.entries(tokenExchangeRates)) {
272
+ const tokenToVsCurrencyConversionRate = conversion[controller_utils_1.FALL_BACK_VS_CURRENCY.toLowerCase()];
273
+ contractExchangeRates[(0, controller_utils_1.toChecksumHexAddress)(tokenAddress)] =
274
+ tokenToVsCurrencyConversionRate *
275
+ vsCurrencyToNativeCurrencyConversionRate;
276
+ }
277
+ }
278
+ return contractExchangeRates;
279
+ });
280
+ }
281
+ }
282
+ exports.TokenRatesController = TokenRatesController;
283
+ exports.default = TokenRatesController;
284
+ //# sourceMappingURL=TokenRatesController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenRatesController.js","sourceRoot":"","sources":["../src/TokenRatesController.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,+DAImC;AACnC,iEAKoC;AAEpC,qDAAgF;AAwFhF,MAAM,YAAY,GAAG;IACnB,QAAQ,EAAE,kCAAkC;IAC5C,gBAAgB,CAAC,SAAiB,EAAE,KAAa;QAC/C,OAAO,GAAG,IAAI,CAAC,QAAQ,uBAAuB,SAAS,IAAI,KAAK,EAAE,CAAC;IACrE,CAAC;IACD,eAAe;QACb,OAAO,GAAG,IAAI,CAAC,QAAQ,kBAAkB,CAAC;IAC5C,CAAC;IACD,wBAAwB;QACtB,OAAO,GAAG,IAAI,CAAC,QAAQ,iCAAiC,CAAC;IAC3D,CAAC;CACF,CAAC;AAEF;;;;;;GAMG;AACH,SAAS,aAAa,CACpB,OAAe,EACf,IAAgC;;IAEhC,IAAI,CAAC,IAAI,EAAE;QACT,OAAO,IAAI,CAAC;KACb;IACD,MAAM,KAAK,GACT,MAAA,IAAI,CAAC,IAAI,CACP,CAAC,EAAE,gBAAgB,EAAE,EAAE,EAAE,CACvB,gBAAgB,KAAK,IAAI,IAAI,MAAM,CAAC,gBAAgB,CAAC,KAAK,OAAO,CACpE,mCAAI,IAAI,CAAC;IACZ,OAAO,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,EAAE,KAAI,IAAI,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACH,MAAa,oBAAqB,SAAQ,gCAGzC;IAoBC;;;;;;;;;OASG;IACH,YACE,EACE,mBAAmB,EACnB,yBAAyB,EACzB,oBAAoB,GAWrB,EACD,MAAkC,EAClC,KAAgC;QAEhC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QA9Cf,cAAS,GAAY,EAAE,CAAC;QAExB,oBAAe,GAAyB;YAC9C,SAAS,EAAE,CAAC;YACZ,IAAI,EAAE,IAAI;SACX,CAAC;QAEM,0BAAqB,GAA+B;YAC1D,SAAS,EAAE,CAAC;YACZ,IAAI,EAAE,EAAE;SACT,CAAC;QAEF;;WAEG;QACM,SAAI,GAAG,sBAAsB,CAAC;QAgCrC,IAAI,CAAC,aAAa,GAAG;YACnB,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;YACvB,cAAc,EAAE,KAAK;YACrB,OAAO,EAAE,EAAE;YACX,MAAM,EAAE,EAAE;YACV,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;SAC9B,CAAC;QAEF,IAAI,CAAC,YAAY,GAAG;YAClB,qBAAqB,EAAE,EAAE;SAC1B,CAAC;QACF,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAClD,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,EAAE,EAAE;YACjD,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;QAEH,yBAAyB,CAAC,CAAC,iBAAiB,EAAE,EAAE;YAC9C,IAAI,CAAC,SAAS,CAAC,EAAE,cAAc,EAAE,iBAAiB,CAAC,cAAc,EAAE,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;QAEH,oBAAoB,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;YACpC,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC;YAC7B,IAAI,CAAC,MAAM,CAAC,EAAE,qBAAqB,EAAE,EAAE,EAAE,CAAC,CAAC;YAC3C,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAED;;;;OAIG;IACG,IAAI,CAAC,QAAiB;;YAC1B,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YACvD,IAAI,CAAC,MAAM,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACzC,MAAM,IAAA,gCAAa,EAAC,GAAG,EAAE,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC;YACtD,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAClC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC3B,CAAC;KAAA;IAED;;;;;;OAMG;IACH,IAAI,OAAO,CAAC,QAAgB;QAC1B,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAA,gCAAa,EAAC,GAAG,EAAE,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,IAAI,OAAO;QACT,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;OAMG;IACH,IAAI,MAAM,CAAC,MAAe;QACxB,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;QACxB,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAA,gCAAa,EAAC,GAAG,EAAE,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,IAAI,MAAM;QACR,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;OAMG;IACG,iBAAiB,CACrB,SAAiB,EACjB,UAAkB;;YAElB,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC1E,MAAM,KAAK,GAAG,sBAAsB,UAAU,kBAAkB,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC;YAC3F,OAAO,IAAA,8BAAW,EAAC,YAAY,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;QACtE,CAAC;KAAA;IAED;;;;;;OAMG;IACW,0BAA0B,CAAC,cAAsB;;YAC7D,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;YAClC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,qBAAqB,CAAC;YAEvD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAEvB,IAAI,GAAG,GAAG,SAAS,GAAG,SAAS,EAAE;gBAC/B,MAAM,UAAU,GAAG,MAAM,IAAA,8BAAW,EAClC,YAAY,CAAC,wBAAwB,EAAE,CACxC,CAAC;gBACF,IAAI,CAAC,qBAAqB,GAAG;oBAC3B,IAAI,EAAE,UAAU;oBAChB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;iBACtB,CAAC;gBACF,OAAO,UAAU,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC,CAAC;aAC1D;YAED,OAAO,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC,CAAC;QACrD,CAAC;KAAA;IAED;;;;;OAKG;IACG,YAAY;;YAChB,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;YAC3C,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC;YAEjD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAEvB,IAAI,GAAG,GAAG,SAAS,GAAG,SAAS,EAAE;gBAC/B,MAAM,SAAS,GAAG,MAAM,IAAA,8BAAW,EAAC,YAAY,CAAC,eAAe,EAAE,CAAC,CAAC;gBACpE,IAAI,CAAC,eAAe,GAAG;oBACrB,IAAI,EAAE,SAAS;oBACf,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;iBACtB,CAAC;gBACF,OAAO,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;aAC1C;YAED,OAAO,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACtC,CAAC;KAAA;IAED;;OAEG;IACG,mBAAmB;;YACvB,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE;gBAChD,OAAO;aACR;YACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;YAEvC,IAAI,wBAAwB,GAA0B,EAAE,CAAC;YACzD,IAAI,CAAC,IAAI,EAAE;gBACT,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;oBAC/B,MAAM,OAAO,GAAG,IAAA,uCAAoB,EAAC,KAAK,CAAC,OAAO,CAAC,CAAC;oBACpD,wBAAwB,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;gBAChD,CAAC,CAAC,CAAC;aACJ;iBAAM;gBACL,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;gBACvC,wBAAwB,GAAG,MAAM,IAAI,CAAC,wBAAwB,CAC5D,cAAc,EACd,IAAI,CACL,CAAC;aACH;YACD,IAAI,CAAC,MAAM,CAAC,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,CAAC,CAAC;QACnE,CAAC;KAAA;IAED;;;;;;;;;;;OAWG;IACG,wBAAwB,CAC5B,cAAsB,EACtB,IAAY;;YAEZ,MAAM,qBAAqB,GAA0B,EAAE,CAAC;YAExD,oEAAoE;YACpE,MAAM,uBAAuB,GAAG,MAAM,IAAI,CAAC,0BAA0B,CACnE,cAAc,CACf,CAAC;YAEF,IAAI,uBAAuB,EAAE;gBAC3B,8DAA8D;gBAC9D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;gBAClE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;oBAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;oBAClD,qBAAqB,CAAC,IAAA,uCAAoB,EAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK;wBAChE,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC;wBACrC,CAAC,CAAC,CAAC,CAAC;gBACR,CAAC,CAAC,CAAC;aACJ;iBAAM;gBACL,mGAAmG;gBACnG,8FAA8F;gBAC9F,IAAI,kBAAkB,CAAC;gBACvB,IAAI,wCAAwC,GAAG,CAAC,CAAC;gBACjD,IAAI;oBACF;wBACE,kBAAkB;wBAClB,EAAE,cAAc,EAAE,wCAAwC,EAAE;qBAC7D,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;wBACpB,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,wCAAqB,CAAC;wBACnD,IAAA,kCAAuB,EAAC,cAAc,EAAE,wCAAqB,EAAE,KAAK,CAAC;qBACtE,CAAC,CAAC;iBACJ;gBAAC,OAAO,KAAK,EAAE;oBACd,IACE,KAAK,YAAY,KAAK;wBACtB,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,0CAA0C,CAAC,EAClE;wBACA,OAAO,EAAE,CAAC;qBACX;oBACD,MAAM,KAAK,CAAC;iBACb;gBAED,KAAK,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CACrD,kBAAkB,CACnB,EAAE;oBACD,MAAM,+BAA+B,GACnC,UAAU,CAAC,wCAAqB,CAAC,WAAW,EAAE,CAAC,CAAC;oBAClD,qBAAqB,CAAC,IAAA,uCAAoB,EAAC,YAAY,CAAC,CAAC;wBACvD,+BAA+B;4BAC/B,wCAAwC,CAAC;iBAC5C;aACF;YAED,OAAO,qBAAqB,CAAC;QAC/B,CAAC;KAAA;CACF;AAhSD,oDAgSC;AAED,kBAAe,oBAAoB,CAAC","sourcesContent":["import {\n BaseController,\n BaseConfig,\n BaseState,\n} from '@metamask/base-controller';\nimport {\n safelyExecute,\n handleFetch,\n toChecksumHexAddress,\n FALL_BACK_VS_CURRENCY,\n} from '@metamask/controller-utils';\nimport type { NetworkState } from '@metamask/network-controller';\nimport { fetchExchangeRate as fetchNativeExchangeRate } from './crypto-compare';\nimport type { TokensState } from './TokensController';\nimport type { CurrencyRateState } from './CurrencyRateController';\n\n/**\n * @type CoinGeckoResponse\n *\n * CoinGecko API response representation\n */\nexport interface CoinGeckoResponse {\n [address: string]: {\n [currency: string]: number;\n };\n}\n/**\n * @type CoinGeckoPlatform\n *\n * CoinGecko supported platform API representation\n */\nexport interface CoinGeckoPlatform {\n id: string;\n chain_identifier: null | number;\n name: string;\n shortname: string;\n}\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 */\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}\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 */\nexport interface TokenRatesConfig extends BaseConfig {\n interval: number;\n nativeCurrency: string;\n chainId: string;\n tokens: Token[];\n threshold: number;\n}\n\ninterface ContractExchangeRates {\n [address: string]: number | undefined;\n}\n\ninterface SupportedChainsCache {\n timestamp: number;\n data: CoinGeckoPlatform[] | null;\n}\n\ninterface SupportedVsCurrenciesCache {\n timestamp: number;\n data: string[];\n}\n\n/**\n * @type TokenRatesState\n *\n * Token rates controller state\n * @property contractExchangeRates - Hash of token contract addresses to exchange rates\n * @property supportedChains - Cached chain data\n */\nexport interface TokenRatesState extends BaseState {\n contractExchangeRates: ContractExchangeRates;\n}\n\nconst CoinGeckoApi = {\n BASE_URL: 'https://api.coingecko.com/api/v3',\n getTokenPriceURL(chainSlug: string, query: string) {\n return `${this.BASE_URL}/simple/token_price/${chainSlug}?${query}`;\n },\n getPlatformsURL() {\n return `${this.BASE_URL}/asset_platforms`;\n },\n getSupportedVsCurrencies() {\n return `${this.BASE_URL}/simple/supported_vs_currencies`;\n },\n};\n\n/**\n * Finds the chain slug in the data array given a chainId.\n *\n * @param chainId - The current chain ID.\n * @param data - A list platforms supported by the CoinGecko API.\n * @returns The CoinGecko slug for the given chain ID, or `null` if the slug was not found.\n */\nfunction findChainSlug(\n chainId: string,\n data: CoinGeckoPlatform[] | null,\n): string | null {\n if (!data) {\n return null;\n }\n const chain =\n data.find(\n ({ chain_identifier }) =>\n chain_identifier !== null && String(chain_identifier) === chainId,\n ) ?? null;\n return chain?.id || null;\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 BaseController<\n TokenRatesConfig,\n TokenRatesState\n> {\n private handle?: ReturnType<typeof setTimeout>;\n\n private tokenList: Token[] = [];\n\n private supportedChains: SupportedChainsCache = {\n timestamp: 0,\n data: null,\n };\n\n private supportedVsCurrencies: SupportedVsCurrenciesCache = {\n timestamp: 0,\n data: [],\n };\n\n /**\n * Name of this controller used during composition\n */\n override name = 'TokenRatesController';\n\n /**\n * Creates a TokenRatesController instance.\n *\n * @param options - The controller options.\n * @param options.onTokensStateChange - Allows subscribing to token controller state changes.\n * @param options.onCurrencyRateStateChange - Allows subscribing to currency rate controller state changes.\n * @param options.onNetworkStateChange - Allows subscribing to network state changes.\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 onTokensStateChange,\n onCurrencyRateStateChange,\n onNetworkStateChange,\n }: {\n onTokensStateChange: (\n listener: (tokensState: TokensState) => void,\n ) => void;\n onCurrencyRateStateChange: (\n listener: (currencyRateState: CurrencyRateState) => void,\n ) => void;\n onNetworkStateChange: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n },\n config?: Partial<TokenRatesConfig>,\n state?: Partial<TokenRatesState>,\n ) {\n super(config, state);\n this.defaultConfig = {\n disabled: true,\n interval: 3 * 60 * 1000,\n nativeCurrency: 'eth',\n chainId: '',\n tokens: [],\n threshold: 6 * 60 * 60 * 1000,\n };\n\n this.defaultState = {\n contractExchangeRates: {},\n };\n this.initialize();\n this.configure({ disabled: false }, false, false);\n onTokensStateChange(({ tokens, detectedTokens }) => {\n this.configure({ tokens: [...tokens, ...detectedTokens] });\n });\n\n onCurrencyRateStateChange((currencyRateState) => {\n this.configure({ nativeCurrency: currencyRateState.nativeCurrency });\n });\n\n onNetworkStateChange(({ provider }) => {\n const { chainId } = provider;\n this.update({ contractExchangeRates: {} });\n this.configure({ chainId });\n });\n this.poll();\n }\n\n /**\n * Sets a new polling interval.\n *\n * @param interval - Polling interval used to fetch new token rates.\n */\n async poll(interval?: number): Promise<void> {\n interval && this.configure({ interval }, false, false);\n this.handle && clearTimeout(this.handle);\n await safelyExecute(() => this.updateExchangeRates());\n this.handle = setTimeout(() => {\n this.poll(this.config.interval);\n }, this.config.interval);\n }\n\n /**\n * Sets a new chainId.\n *\n * TODO: Replace this with a method.\n *\n * @param _chainId - The current chain ID.\n */\n set chainId(_chainId: string) {\n !this.disabled && safelyExecute(() => this.updateExchangeRates());\n }\n\n get chainId() {\n throw new Error('Property only used for setting');\n }\n\n /**\n * Sets a new token list to track prices.\n *\n * TODO: Replace this with a method.\n *\n * @param tokens - List of tokens to track exchange rates for.\n */\n set tokens(tokens: Token[]) {\n this.tokenList = tokens;\n !this.disabled && safelyExecute(() => this.updateExchangeRates());\n }\n\n get tokens() {\n throw new Error('Property only used for setting');\n }\n\n /**\n * Fetches a pairs of token address and native currency.\n *\n * @param chainSlug - Chain string identifier.\n * @param vsCurrency - Query according to tokens in tokenList and native currency.\n * @returns The exchange rates for the given pairs.\n */\n async fetchExchangeRate(\n chainSlug: string,\n vsCurrency: string,\n ): Promise<CoinGeckoResponse> {\n const tokenPairs = this.tokenList.map((token) => token.address).join(',');\n const query = `contract_addresses=${tokenPairs}&vs_currencies=${vsCurrency.toLowerCase()}`;\n return handleFetch(CoinGeckoApi.getTokenPriceURL(chainSlug, query));\n }\n\n /**\n * Checks if the current native currency is a supported vs currency to use\n * to query for token exchange rates.\n *\n * @param nativeCurrency - The native currency of the currently active network.\n * @returns A boolean indicating whether it's a supported vsCurrency.\n */\n private async checkIsSupportedVsCurrency(nativeCurrency: string) {\n const { threshold } = this.config;\n const { timestamp, data } = this.supportedVsCurrencies;\n\n const now = Date.now();\n\n if (now - timestamp > threshold) {\n const currencies = await handleFetch(\n CoinGeckoApi.getSupportedVsCurrencies(),\n );\n this.supportedVsCurrencies = {\n data: currencies,\n timestamp: Date.now(),\n };\n return currencies.includes(nativeCurrency.toLowerCase());\n }\n\n return data.includes(nativeCurrency.toLowerCase());\n }\n\n /**\n * Gets current chain ID slug from cached supported platforms CoinGecko API response.\n * If cached supported platforms response is stale, fetches and updates it.\n *\n * @returns The CoinGecko slug for the current chain ID.\n */\n async getChainSlug(): Promise<string | null> {\n const { threshold, chainId } = this.config;\n const { data, timestamp } = this.supportedChains;\n\n const now = Date.now();\n\n if (now - timestamp > threshold) {\n const platforms = await handleFetch(CoinGeckoApi.getPlatformsURL());\n this.supportedChains = {\n data: platforms,\n timestamp: Date.now(),\n };\n return findChainSlug(chainId, platforms);\n }\n\n return findChainSlug(chainId, data);\n }\n\n /**\n * Updates exchange rates for all tokens.\n */\n async updateExchangeRates() {\n if (this.tokenList.length === 0 || this.disabled) {\n return;\n }\n const slug = await this.getChainSlug();\n\n let newContractExchangeRates: ContractExchangeRates = {};\n if (!slug) {\n this.tokenList.forEach((token) => {\n const address = toChecksumHexAddress(token.address);\n newContractExchangeRates[address] = undefined;\n });\n } else {\n const { nativeCurrency } = this.config;\n newContractExchangeRates = await this.fetchAndMapExchangeRates(\n nativeCurrency,\n slug,\n );\n }\n this.update({ contractExchangeRates: newContractExchangeRates });\n }\n\n /**\n * Checks if the active network's native currency is supported by the coingecko API.\n * If supported, it fetches and maps contractExchange rates to a format to be consumed by the UI.\n * If not supported, it fetches contractExchange rates and maps them from token/fallback-currency\n * to token/nativeCurrency.\n *\n * @param nativeCurrency - The native currency of the currently active network.\n * @param slug - The unique slug used to id the chain by the coingecko api\n * should be used to query token exchange rates.\n * @returns An object with conversion rates for each token\n * related to the network's native currency.\n */\n async fetchAndMapExchangeRates(\n nativeCurrency: string,\n slug: string,\n ): Promise<ContractExchangeRates> {\n const contractExchangeRates: ContractExchangeRates = {};\n\n // check if native currency is supported as a vs_currency by the API\n const nativeCurrencySupported = await this.checkIsSupportedVsCurrency(\n nativeCurrency,\n );\n\n if (nativeCurrencySupported) {\n // If it is we can do a simple fetch against the CoinGecko API\n const prices = await this.fetchExchangeRate(slug, nativeCurrency);\n this.tokenList.forEach((token) => {\n const price = prices[token.address.toLowerCase()];\n contractExchangeRates[toChecksumHexAddress(token.address)] = price\n ? price[nativeCurrency.toLowerCase()]\n : 0;\n });\n } else {\n // if native currency is not supported we need to use a fallback vsCurrency, get the exchange rates\n // in token/fallback-currency format and convert them to expected token/nativeCurrency format.\n let tokenExchangeRates;\n let vsCurrencyToNativeCurrencyConversionRate = 0;\n try {\n [\n tokenExchangeRates,\n { conversionRate: vsCurrencyToNativeCurrencyConversionRate },\n ] = await Promise.all([\n this.fetchExchangeRate(slug, FALL_BACK_VS_CURRENCY),\n fetchNativeExchangeRate(nativeCurrency, FALL_BACK_VS_CURRENCY, false),\n ]);\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes('market does not exist for this coin pair')\n ) {\n return {};\n }\n throw error;\n }\n\n for (const [tokenAddress, conversion] of Object.entries(\n tokenExchangeRates,\n )) {\n const tokenToVsCurrencyConversionRate =\n conversion[FALL_BACK_VS_CURRENCY.toLowerCase()];\n contractExchangeRates[toChecksumHexAddress(tokenAddress)] =\n tokenToVsCurrencyConversionRate *\n vsCurrencyToNativeCurrencyConversionRate;\n }\n }\n\n return contractExchangeRates;\n }\n}\n\nexport default TokenRatesController;\n"]}
@@ -0,0 +1,238 @@
1
+ /// <reference types="node" />
2
+ import { EventEmitter } from 'events';
3
+ import { Contract } from '@ethersproject/contracts';
4
+ import { BaseController, BaseConfig, BaseState } from '@metamask/base-controller';
5
+ import type { PreferencesState } from '@metamask/preferences-controller';
6
+ import type { NetworkState } from '@metamask/network-controller';
7
+ import { NetworkType } from '@metamask/controller-utils';
8
+ import type { Token } from './TokenRatesController';
9
+ /**
10
+ * @type TokensConfig
11
+ *
12
+ * Tokens controller configuration
13
+ * @property networkType - Network ID as per net_version
14
+ * @property selectedAddress - Vault selected address
15
+ */
16
+ export interface TokensConfig extends BaseConfig {
17
+ networkType: NetworkType;
18
+ selectedAddress: string;
19
+ chainId: string;
20
+ provider: any;
21
+ }
22
+ /**
23
+ * @type AssetSuggestionResult
24
+ * @property result - Promise resolving to a new suggested asset address
25
+ * @property suggestedAssetMeta - Meta information about this new suggested asset
26
+ */
27
+ interface AssetSuggestionResult {
28
+ result: Promise<string>;
29
+ suggestedAssetMeta: SuggestedAssetMeta;
30
+ }
31
+ declare enum SuggestedAssetStatus {
32
+ accepted = "accepted",
33
+ failed = "failed",
34
+ pending = "pending",
35
+ rejected = "rejected"
36
+ }
37
+ export declare type SuggestedAssetMetaBase = {
38
+ id: string;
39
+ time: number;
40
+ type: string;
41
+ asset: Token;
42
+ };
43
+ /**
44
+ * @type SuggestedAssetMeta
45
+ *
46
+ * Suggested asset by EIP747 meta data
47
+ * @property error - Synthesized error information for failed asset suggestions
48
+ * @property id - Generated UUID associated with this suggested asset
49
+ * @property status - String status of this this suggested asset
50
+ * @property time - Timestamp associated with this this suggested asset
51
+ * @property type - Type type this suggested asset
52
+ * @property asset - Asset suggested object
53
+ */
54
+ export declare type SuggestedAssetMeta = (SuggestedAssetMetaBase & {
55
+ status: SuggestedAssetStatus.failed;
56
+ error: Error;
57
+ }) | (SuggestedAssetMetaBase & {
58
+ status: SuggestedAssetStatus.accepted | SuggestedAssetStatus.rejected | SuggestedAssetStatus.pending;
59
+ });
60
+ /**
61
+ * @type TokensState
62
+ *
63
+ * Assets controller state
64
+ * @property tokens - List of tokens associated with the active network and address pair
65
+ * @property ignoredTokens - List of ignoredTokens associated with the active network and address pair
66
+ * @property detectedTokens - List of detected tokens associated with the active network and address pair
67
+ * @property allTokens - Object containing tokens by network and account
68
+ * @property allIgnoredTokens - Object containing hidden/ignored tokens by network and account
69
+ * @property allDetectedTokens - Object containing tokens detected with non-zero balances
70
+ * @property suggestedAssets - List of pending suggested assets to be added or canceled
71
+ */
72
+ export interface TokensState extends BaseState {
73
+ tokens: Token[];
74
+ ignoredTokens: string[];
75
+ detectedTokens: Token[];
76
+ allTokens: {
77
+ [key: string]: {
78
+ [key: string]: Token[];
79
+ };
80
+ };
81
+ allIgnoredTokens: {
82
+ [key: string]: {
83
+ [key: string]: string[];
84
+ };
85
+ };
86
+ allDetectedTokens: {
87
+ [key: string]: {
88
+ [key: string]: Token[];
89
+ };
90
+ };
91
+ suggestedAssets: SuggestedAssetMeta[];
92
+ }
93
+ /**
94
+ * Controller that stores assets and exposes convenience methods
95
+ */
96
+ export declare class TokensController extends BaseController<TokensConfig, TokensState> {
97
+ private mutex;
98
+ private ethersProvider;
99
+ private abortController;
100
+ private failSuggestedAsset;
101
+ /**
102
+ * Fetch metadata for a token.
103
+ *
104
+ * @param tokenAddress - The address of the token.
105
+ * @returns The token metadata.
106
+ */
107
+ private fetchTokenMetadata;
108
+ /**
109
+ * EventEmitter instance used to listen to specific EIP747 events
110
+ */
111
+ hub: EventEmitter;
112
+ /**
113
+ * Name of this controller used during composition
114
+ */
115
+ name: string;
116
+ /**
117
+ * Creates a TokensController instance.
118
+ *
119
+ * @param options - The controller options.
120
+ * @param options.onPreferencesStateChange - Allows subscribing to preference controller state changes.
121
+ * @param options.onNetworkStateChange - Allows subscribing to network controller state changes.
122
+ * @param options.config - Initial options used to configure this controller.
123
+ * @param options.state - Initial state to set on this controller.
124
+ */
125
+ constructor({ onPreferencesStateChange, onNetworkStateChange, config, state, }: {
126
+ onPreferencesStateChange: (listener: (preferencesState: PreferencesState) => void) => void;
127
+ onNetworkStateChange: (listener: (networkState: NetworkState) => void) => void;
128
+ config?: Partial<TokensConfig>;
129
+ state?: Partial<TokensState>;
130
+ });
131
+ _instantiateNewEthersProvider(): any;
132
+ /**
133
+ * Adds a token to the stored token list.
134
+ *
135
+ * @param address - Hex address of the token contract.
136
+ * @param symbol - Symbol of the token.
137
+ * @param decimals - Number of decimals the token uses.
138
+ * @param image - Image of the token.
139
+ * @returns Current token list.
140
+ */
141
+ addToken(address: string, symbol: string, decimals: number, image?: string): Promise<Token[]>;
142
+ /**
143
+ * Add a batch of tokens.
144
+ *
145
+ * @param tokensToImport - Array of tokens to import.
146
+ */
147
+ addTokens(tokensToImport: Token[]): Promise<void>;
148
+ /**
149
+ * Ignore a batch of tokens.
150
+ *
151
+ * @param tokenAddressesToIgnore - Array of token addresses to ignore.
152
+ */
153
+ ignoreTokens(tokenAddressesToIgnore: string[]): void;
154
+ /**
155
+ * Adds a batch of detected tokens to the stored token list.
156
+ *
157
+ * @param incomingDetectedTokens - Array of detected tokens to be added or updated.
158
+ */
159
+ addDetectedTokens(incomingDetectedTokens: Token[]): Promise<void>;
160
+ /**
161
+ * Adds isERC721 field to token object. This is called when a user attempts to add tokens that
162
+ * were previously added which do not yet had isERC721 field.
163
+ *
164
+ * @param tokenAddress - The contract address of the token requiring the isERC721 field added.
165
+ * @returns The new token object with the added isERC721 field.
166
+ */
167
+ updateTokenType(tokenAddress: string): Promise<Token>;
168
+ /**
169
+ * Detects whether or not a token is ERC-721 compatible.
170
+ *
171
+ * @param tokenAddress - The token contract address.
172
+ * @returns A boolean indicating whether the token address passed in supports the EIP-721
173
+ * interface.
174
+ */
175
+ _detectIsERC721(tokenAddress: string): Promise<any>;
176
+ _createEthersContract(tokenAddress: string, abi: string, ethersProvider: any): Contract;
177
+ _generateRandomId(): string;
178
+ /**
179
+ * Adds a new suggestedAsset to state. Parameters will be validated according to
180
+ * asset type being watched. A `<suggestedAssetMeta.id>:pending` hub event will be emitted once added.
181
+ *
182
+ * @param asset - The asset to be watched. For now only ERC20 tokens are accepted.
183
+ * @param type - The asset type.
184
+ * @returns Object containing a Promise resolving to the suggestedAsset address if accepted.
185
+ */
186
+ watchAsset(asset: Token, type: string): Promise<AssetSuggestionResult>;
187
+ /**
188
+ * Accepts to watch an asset and updates it's status and deletes the suggestedAsset from state,
189
+ * adding the asset to corresponding asset state. In this case ERC20 tokens.
190
+ * A `<suggestedAssetMeta.id>:finished` hub event is fired after accepted or failure.
191
+ *
192
+ * @param suggestedAssetID - The ID of the suggestedAsset to accept.
193
+ */
194
+ acceptWatchAsset(suggestedAssetID: string): Promise<void>;
195
+ /**
196
+ * Rejects a watchAsset request based on its ID by setting its status to "rejected"
197
+ * and emitting a `<suggestedAssetMeta.id>:finished` hub event.
198
+ *
199
+ * @param suggestedAssetID - The ID of the suggestedAsset to accept.
200
+ */
201
+ rejectWatchAsset(suggestedAssetID: string): void;
202
+ /**
203
+ * Takes a new tokens and ignoredTokens array for the current network/account combination
204
+ * and returns new allTokens and allIgnoredTokens state to update to.
205
+ *
206
+ * @param params - Object that holds token params.
207
+ * @param params.newTokens - The new tokens to set for the current network and selected account.
208
+ * @param params.newIgnoredTokens - The new ignored tokens to set for the current network and selected account.
209
+ * @param params.newDetectedTokens - The new detected tokens to set for the current network and selected account.
210
+ * @returns The updated `allTokens` and `allIgnoredTokens` state.
211
+ */
212
+ _getNewAllTokensState(params: {
213
+ newTokens?: Token[];
214
+ newIgnoredTokens?: string[];
215
+ newDetectedTokens?: Token[];
216
+ }): {
217
+ newAllTokens: {
218
+ [key: string]: {
219
+ [key: string]: Token[];
220
+ };
221
+ };
222
+ newAllIgnoredTokens: {
223
+ [key: string]: {
224
+ [key: string]: string[];
225
+ };
226
+ };
227
+ newAllDetectedTokens: {
228
+ [key: string]: {
229
+ [key: string]: Token[];
230
+ };
231
+ };
232
+ };
233
+ /**
234
+ * Removes all tokens from the ignored list.
235
+ */
236
+ clearIgnoredTokens(): void;
237
+ }
238
+ export default TokensController;