@metamask/assets-controllers 20.0.0 → 22.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.
- package/CHANGELOG.md +80 -1
- package/dist/AccountTrackerController.d.ts +28 -7
- package/dist/AccountTrackerController.d.ts.map +1 -1
- package/dist/AccountTrackerController.js +104 -30
- package/dist/AccountTrackerController.js.map +1 -1
- package/dist/AssetsContractController.d.ts +3 -3
- package/dist/AssetsContractController.d.ts.map +1 -1
- package/dist/AssetsContractController.js +9 -3
- package/dist/AssetsContractController.js.map +1 -1
- package/dist/CurrencyRateController.d.ts +2 -2
- package/dist/CurrencyRateController.d.ts.map +1 -1
- package/dist/CurrencyRateController.js +1 -1
- package/dist/CurrencyRateController.js.map +1 -1
- package/dist/NftController.d.ts +73 -1
- package/dist/NftController.d.ts.map +1 -1
- package/dist/NftController.js +26 -9
- package/dist/NftController.js.map +1 -1
- package/dist/NftDetectionController.d.ts +7 -4
- package/dist/NftDetectionController.d.ts.map +1 -1
- package/dist/NftDetectionController.js +26 -14
- package/dist/NftDetectionController.js.map +1 -1
- package/dist/Standards/ERC20Standard.d.ts.map +1 -1
- package/dist/Standards/ERC20Standard.js +4 -0
- package/dist/Standards/ERC20Standard.js.map +1 -1
- package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.d.ts +11 -10
- package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.d.ts.map +1 -1
- package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.js +106 -85
- package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.js.map +1 -1
- package/dist/Standards/NftStandards/ERC721/ERC721Standard.d.ts.map +1 -1
- package/dist/Standards/NftStandards/ERC721/ERC721Standard.js +2 -0
- package/dist/Standards/NftStandards/ERC721/ERC721Standard.js.map +1 -1
- package/dist/Standards/standards-types.d.ts.map +1 -1
- package/dist/Standards/standards-types.js.map +1 -1
- package/dist/TokenDetectionController.d.ts +2 -2
- package/dist/TokenDetectionController.d.ts.map +1 -1
- package/dist/TokenDetectionController.js +1 -1
- package/dist/TokenDetectionController.js.map +1 -1
- package/dist/TokenListController.d.ts +2 -2
- package/dist/TokenListController.d.ts.map +1 -1
- package/dist/TokenListController.js +3 -15
- package/dist/TokenListController.js.map +1 -1
- package/dist/TokenRatesController.d.ts +9 -75
- package/dist/TokenRatesController.d.ts.map +1 -1
- package/dist/TokenRatesController.js +180 -203
- package/dist/TokenRatesController.js.map +1 -1
- package/dist/TokensController.d.ts +6 -8
- package/dist/TokensController.d.ts.map +1 -1
- package/dist/TokensController.js +70 -21
- package/dist/TokensController.js.map +1 -1
- package/dist/assetsUtil.d.ts +59 -9
- package/dist/assetsUtil.d.ts.map +1 -1
- package/dist/assetsUtil.js +138 -27
- package/dist/assetsUtil.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/token-prices-service/abstract-token-prices-service.d.ts +62 -0
- package/dist/token-prices-service/abstract-token-prices-service.d.ts.map +1 -0
- package/dist/token-prices-service/abstract-token-prices-service.js +3 -0
- package/dist/token-prices-service/abstract-token-prices-service.js.map +1 -0
- package/dist/token-prices-service/codefi-v2.d.ts +80 -0
- package/dist/token-prices-service/codefi-v2.d.ts.map +1 -0
- package/dist/token-prices-service/codefi-v2.js +327 -0
- package/dist/token-prices-service/codefi-v2.js.map +1 -0
- package/dist/token-prices-service/index.d.ts +3 -0
- package/dist/token-prices-service/index.d.ts.map +1 -0
- package/dist/token-prices-service/index.js +6 -0
- package/dist/token-prices-service/index.js.map +1 -0
- package/dist/token-service.d.ts.map +1 -1
- package/dist/token-service.js +1 -1
- package/dist/token-service.js.map +1 -1
- package/package.json +6 -3
|
@@ -8,60 +8,67 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
12
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
13
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
14
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
15
|
-
};
|
|
16
11
|
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
17
12
|
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
18
13
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
19
14
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
20
15
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
21
16
|
};
|
|
22
|
-
var
|
|
17
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
18
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
19
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
20
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
21
|
+
};
|
|
22
|
+
var _TokenRatesController_instances, _TokenRatesController_pollState, _TokenRatesController_tokenPricesService, _TokenRatesController_inProcessExchangeRateUpdates, _TokenRatesController_getTokenAddresses, _TokenRatesController_stopPoll, _TokenRatesController_poll, _TokenRatesController_fetchAndMapExchangeRates, _TokenRatesController_fetchAndMapExchangeRatesForSupportedNativeCurrency, _TokenRatesController_fetchAndMapExchangeRatesForUnsupportedNativeCurrency;
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
24
|
exports.TokenRatesController = void 0;
|
|
25
25
|
const controller_utils_1 = require("@metamask/controller-utils");
|
|
26
26
|
const polling_controller_1 = require("@metamask/polling-controller");
|
|
27
|
+
const lodash_1 = require("lodash");
|
|
28
|
+
const assetsUtil_1 = require("./assetsUtil");
|
|
27
29
|
const crypto_compare_1 = require("./crypto-compare");
|
|
28
30
|
var PollState;
|
|
29
31
|
(function (PollState) {
|
|
30
32
|
PollState["Active"] = "Active";
|
|
31
33
|
PollState["Inactive"] = "Inactive";
|
|
32
34
|
})(PollState || (PollState = {}));
|
|
33
|
-
const CoinGeckoApi = {
|
|
34
|
-
BASE_URL: 'https://api.coingecko.com/api/v3',
|
|
35
|
-
getTokenPriceURL(chainSlug, query) {
|
|
36
|
-
return `${this.BASE_URL}/simple/token_price/${chainSlug}?${query}`;
|
|
37
|
-
},
|
|
38
|
-
getPlatformsURL() {
|
|
39
|
-
return `${this.BASE_URL}/asset_platforms`;
|
|
40
|
-
},
|
|
41
|
-
getSupportedVsCurrencies() {
|
|
42
|
-
return `${this.BASE_URL}/simple/supported_vs_currencies`;
|
|
43
|
-
},
|
|
44
|
-
};
|
|
45
35
|
/**
|
|
46
|
-
*
|
|
36
|
+
* The maximum number of token addresses that should be sent to the Price API in
|
|
37
|
+
* a single request.
|
|
38
|
+
*/
|
|
39
|
+
const TOKEN_PRICES_BATCH_SIZE = 100;
|
|
40
|
+
/**
|
|
41
|
+
* Uses the CryptoCompare API to fetch the exchange rate between one currency
|
|
42
|
+
* and another, i.e., the multiplier to apply the amount of one currency in
|
|
43
|
+
* order to convert it to another.
|
|
47
44
|
*
|
|
48
|
-
* @param
|
|
49
|
-
* @param
|
|
50
|
-
* @
|
|
45
|
+
* @param args - The arguments to this function.
|
|
46
|
+
* @param args.from - The currency to convert from.
|
|
47
|
+
* @param args.to - The currency to convert to.
|
|
48
|
+
* @returns The exchange rate between `fromCurrency` to `toCurrency` if one
|
|
49
|
+
* exists, or null if one does not.
|
|
51
50
|
*/
|
|
52
|
-
function
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
function getCurrencyConversionRate({ from, to, }) {
|
|
52
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
53
|
+
const includeUSDRate = false;
|
|
54
|
+
try {
|
|
55
|
+
const result = yield (0, crypto_compare_1.fetchExchangeRate)(to, from, includeUSDRate);
|
|
56
|
+
return result.conversionRate;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
if (error instanceof Error &&
|
|
60
|
+
error.message.includes('market does not exist for this coin pair')) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
59
66
|
}
|
|
60
67
|
/**
|
|
61
68
|
* Controller that passively polls on a set interval for token-to-fiat exchange rates
|
|
62
69
|
* for tokens stored in the TokensController
|
|
63
70
|
*/
|
|
64
|
-
class TokenRatesController extends polling_controller_1.
|
|
71
|
+
class TokenRatesController extends polling_controller_1.StaticIntervalPollingControllerV1 {
|
|
65
72
|
/**
|
|
66
73
|
* Creates a TokenRatesController instance.
|
|
67
74
|
*
|
|
@@ -75,22 +82,16 @@ class TokenRatesController extends polling_controller_1.PollingControllerV1 {
|
|
|
75
82
|
* @param options.onPreferencesStateChange - Allows subscribing to preference controller state changes.
|
|
76
83
|
* @param options.onTokensStateChange - Allows subscribing to token controller state changes.
|
|
77
84
|
* @param options.onNetworkStateChange - Allows subscribing to network state changes.
|
|
85
|
+
* @param options.tokenPricesService - An object in charge of retrieving token prices.
|
|
78
86
|
* @param config - Initial options used to configure this controller.
|
|
79
87
|
* @param state - Initial state to set on this controller.
|
|
80
88
|
*/
|
|
81
|
-
constructor({ interval = 3 * 60 * 1000, threshold = 6 * 60 * 60 * 1000, getNetworkClientById, chainId: initialChainId, ticker: initialTicker, selectedAddress: initialSelectedAddress, onPreferencesStateChange, onTokensStateChange, onNetworkStateChange, }, config, state) {
|
|
89
|
+
constructor({ interval = 3 * 60 * 1000, threshold = 6 * 60 * 60 * 1000, getNetworkClientById, chainId: initialChainId, ticker: initialTicker, selectedAddress: initialSelectedAddress, onPreferencesStateChange, onTokensStateChange, onNetworkStateChange, tokenPricesService, }, config, state) {
|
|
82
90
|
super(config, state);
|
|
83
91
|
_TokenRatesController_instances.add(this);
|
|
84
|
-
this.tokenList = [];
|
|
85
|
-
this.supportedChains = {
|
|
86
|
-
timestamp: 0,
|
|
87
|
-
data: null,
|
|
88
|
-
};
|
|
89
|
-
this.supportedVsCurrencies = {
|
|
90
|
-
timestamp: 0,
|
|
91
|
-
data: [],
|
|
92
|
-
};
|
|
93
92
|
_TokenRatesController_pollState.set(this, PollState.Inactive);
|
|
93
|
+
_TokenRatesController_tokenPricesService.set(this, void 0);
|
|
94
|
+
_TokenRatesController_inProcessExchangeRateUpdates.set(this, {});
|
|
94
95
|
/**
|
|
95
96
|
* Name of this controller used during composition
|
|
96
97
|
*/
|
|
@@ -112,28 +113,25 @@ class TokenRatesController extends polling_controller_1.PollingControllerV1 {
|
|
|
112
113
|
this.initialize();
|
|
113
114
|
this.setIntervalLength(interval);
|
|
114
115
|
this.getNetworkClientById = getNetworkClientById;
|
|
116
|
+
__classPrivateFieldSet(this, _TokenRatesController_tokenPricesService, tokenPricesService, "f");
|
|
115
117
|
if (config === null || config === void 0 ? void 0 : config.disabled) {
|
|
116
118
|
this.configure({ disabled: true }, false, false);
|
|
117
119
|
}
|
|
118
|
-
__classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_updateTokenList).call(this);
|
|
119
120
|
onPreferencesStateChange(({ selectedAddress }) => __awaiter(this, void 0, void 0, function* () {
|
|
120
121
|
if (this.config.selectedAddress !== selectedAddress) {
|
|
121
122
|
this.configure({ selectedAddress });
|
|
122
|
-
__classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_updateTokenList).call(this);
|
|
123
123
|
if (__classPrivateFieldGet(this, _TokenRatesController_pollState, "f") === PollState.Active) {
|
|
124
124
|
yield this.updateExchangeRates();
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
}));
|
|
128
128
|
onTokensStateChange(({ allTokens, allDetectedTokens }) => __awaiter(this, void 0, void 0, function* () {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
__classPrivateFieldGet(this,
|
|
134
|
-
|
|
135
|
-
yield this.updateExchangeRates();
|
|
136
|
-
}
|
|
129
|
+
const previousTokenAddresses = __classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_getTokenAddresses).call(this, this.config.chainId);
|
|
130
|
+
this.configure({ allTokens, allDetectedTokens });
|
|
131
|
+
const newTokenAddresses = __classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_getTokenAddresses).call(this, this.config.chainId);
|
|
132
|
+
if (!(0, lodash_1.isEqual)(previousTokenAddresses, newTokenAddresses) &&
|
|
133
|
+
__classPrivateFieldGet(this, _TokenRatesController_pollState, "f") === PollState.Active) {
|
|
134
|
+
yield this.updateExchangeRates();
|
|
137
135
|
}
|
|
138
136
|
}));
|
|
139
137
|
onNetworkStateChange(({ providerConfig }) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -142,7 +140,6 @@ class TokenRatesController extends polling_controller_1.PollingControllerV1 {
|
|
|
142
140
|
this.config.nativeCurrency !== ticker) {
|
|
143
141
|
this.update({ contractExchangeRates: {} });
|
|
144
142
|
this.configure({ chainId, nativeCurrency: ticker });
|
|
145
|
-
__classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_updateTokenList).call(this);
|
|
146
143
|
if (__classPrivateFieldGet(this, _TokenRatesController_pollState, "f") === PollState.Active) {
|
|
147
144
|
yield this.updateExchangeRates();
|
|
148
145
|
}
|
|
@@ -166,84 +163,15 @@ class TokenRatesController extends polling_controller_1.PollingControllerV1 {
|
|
|
166
163
|
__classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_stopPoll).call(this);
|
|
167
164
|
__classPrivateFieldSet(this, _TokenRatesController_pollState, PollState.Inactive, "f");
|
|
168
165
|
}
|
|
169
|
-
/**
|
|
170
|
-
* Fetches a pairs of token address and native currency.
|
|
171
|
-
*
|
|
172
|
-
* @param chainSlug - The chain string identifier.
|
|
173
|
-
* @param vsCurrency - The currency used to generate pairs against the tokens.
|
|
174
|
-
* @param tokenAddresses - The addresses for the token contracts.
|
|
175
|
-
* @returns The exchange rates for the given pairs.
|
|
176
|
-
*/
|
|
177
|
-
fetchExchangeRate(chainSlug, vsCurrency, tokenAddresses = this.tokenList.map((token) => token.address)) {
|
|
178
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
179
|
-
const tokenPairs = tokenAddresses.join(',');
|
|
180
|
-
const query = `contract_addresses=${tokenPairs}&vs_currencies=${vsCurrency.toLowerCase()}`;
|
|
181
|
-
return (0, controller_utils_1.handleFetch)(CoinGeckoApi.getTokenPriceURL(chainSlug, query));
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Checks if the current native currency is a supported vs currency to use
|
|
186
|
-
* to query for token exchange rates.
|
|
187
|
-
*
|
|
188
|
-
* @param nativeCurrency - The native currency to check.
|
|
189
|
-
* @returns A boolean indicating whether it's a supported vsCurrency.
|
|
190
|
-
*/
|
|
191
|
-
checkIsSupportedVsCurrency(nativeCurrency) {
|
|
192
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
193
|
-
const { threshold } = this.config;
|
|
194
|
-
const { timestamp, data } = this.supportedVsCurrencies;
|
|
195
|
-
const now = Date.now();
|
|
196
|
-
if (now - timestamp > threshold) {
|
|
197
|
-
const currencies = yield (0, controller_utils_1.handleFetch)(CoinGeckoApi.getSupportedVsCurrencies());
|
|
198
|
-
this.supportedVsCurrencies = {
|
|
199
|
-
data: currencies,
|
|
200
|
-
timestamp: Date.now(),
|
|
201
|
-
};
|
|
202
|
-
return currencies.includes(nativeCurrency.toLowerCase());
|
|
203
|
-
}
|
|
204
|
-
return data.includes(nativeCurrency.toLowerCase());
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* Gets the slug from cached supported platforms CoinGecko API response for the chain ID.
|
|
209
|
-
* If cached supported platforms response is stale, fetches and updates it.
|
|
210
|
-
*
|
|
211
|
-
* @param chainId - The chain ID.
|
|
212
|
-
* @returns The CoinGecko slug for the chain ID.
|
|
213
|
-
*/
|
|
214
|
-
getChainSlug(chainId = this.config.chainId) {
|
|
215
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
216
|
-
const { threshold } = this.config;
|
|
217
|
-
const { data, timestamp } = this.supportedChains;
|
|
218
|
-
const now = Date.now();
|
|
219
|
-
if (now - timestamp > threshold) {
|
|
220
|
-
const platforms = yield (0, controller_utils_1.handleFetch)(CoinGeckoApi.getPlatformsURL());
|
|
221
|
-
this.supportedChains = {
|
|
222
|
-
data: platforms,
|
|
223
|
-
timestamp: Date.now(),
|
|
224
|
-
};
|
|
225
|
-
return findChainSlug(chainId, platforms);
|
|
226
|
-
}
|
|
227
|
-
return findChainSlug(chainId, data);
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
166
|
/**
|
|
231
167
|
* Updates exchange rates for all tokens.
|
|
232
168
|
*/
|
|
233
169
|
updateExchangeRates() {
|
|
234
170
|
return __awaiter(this, void 0, void 0, function* () {
|
|
235
|
-
if (this.tokenList.length === 0 || this.disabled) {
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
171
|
const { chainId, nativeCurrency } = this.config;
|
|
239
|
-
const tokenAddresses = this.tokenList.map((token) => token.address);
|
|
240
172
|
yield this.updateExchangeRatesByChainId({
|
|
241
173
|
chainId,
|
|
242
174
|
nativeCurrency,
|
|
243
|
-
tokenAddresses,
|
|
244
|
-
});
|
|
245
|
-
this.update({
|
|
246
|
-
contractExchangeRates: this.state.contractExchangeRatesByChainId[chainId][nativeCurrency],
|
|
247
175
|
});
|
|
248
176
|
});
|
|
249
177
|
}
|
|
@@ -253,117 +181,80 @@ class TokenRatesController extends polling_controller_1.PollingControllerV1 {
|
|
|
253
181
|
* @param options - The options to fetch exchange rates.
|
|
254
182
|
* @param options.chainId - The chain ID.
|
|
255
183
|
* @param options.nativeCurrency - The ticker for the chain.
|
|
256
|
-
* @param options.tokenAddresses - The addresses for the token contracts.
|
|
257
184
|
*/
|
|
258
|
-
updateExchangeRatesByChainId({ chainId, nativeCurrency,
|
|
259
|
-
var _a
|
|
185
|
+
updateExchangeRatesByChainId({ chainId, nativeCurrency, }) {
|
|
186
|
+
var _a;
|
|
260
187
|
return __awaiter(this, void 0, void 0, function* () {
|
|
261
|
-
if (
|
|
188
|
+
if (this.disabled) {
|
|
262
189
|
return;
|
|
263
190
|
}
|
|
264
|
-
const
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
tokenAddresses.forEach((tokenAddress) => {
|
|
268
|
-
const address = (0, controller_utils_1.toChecksumHexAddress)(tokenAddress);
|
|
269
|
-
newContractExchangeRates[address] = undefined;
|
|
270
|
-
});
|
|
191
|
+
const tokenAddresses = __classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_getTokenAddresses).call(this, chainId);
|
|
192
|
+
if (tokenAddresses.length === 0) {
|
|
193
|
+
return;
|
|
271
194
|
}
|
|
272
|
-
|
|
273
|
-
|
|
195
|
+
const updateKey = `${chainId}:${nativeCurrency}`;
|
|
196
|
+
if (updateKey in __classPrivateFieldGet(this, _TokenRatesController_inProcessExchangeRateUpdates, "f")) {
|
|
197
|
+
// This prevents redundant updates
|
|
198
|
+
// This promise is resolved after the in-progress update has finished,
|
|
199
|
+
// and state has been updated.
|
|
200
|
+
yield __classPrivateFieldGet(this, _TokenRatesController_inProcessExchangeRateUpdates, "f")[updateKey];
|
|
201
|
+
return;
|
|
274
202
|
}
|
|
275
|
-
const
|
|
276
|
-
this
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
* Checks if the active network's native currency is supported by the coingecko API.
|
|
283
|
-
* If supported, it fetches and maps contractExchange rates to a format to be consumed by the UI.
|
|
284
|
-
* If not supported, it fetches contractExchange rates and maps them from token/fallback-currency
|
|
285
|
-
* to token/nativeCurrency.
|
|
286
|
-
*
|
|
287
|
-
* @param nativeCurrency - The native currency ticker against which to fetch exchange rates
|
|
288
|
-
* @param chainSlug - The unique slug used to id the chain by the coingecko api
|
|
289
|
-
* should be used to query token exchange rates.
|
|
290
|
-
* @param tokenAddresses - The addresses for the token contracts against which to fetch exchange rates.
|
|
291
|
-
* @returns An object with conversion rates for each token
|
|
292
|
-
* related to the network's native currency.
|
|
293
|
-
*/
|
|
294
|
-
fetchAndMapExchangeRates(nativeCurrency, chainSlug, tokenAddresses = this.tokenList.map((token) => token.address)) {
|
|
295
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
296
|
-
const contractExchangeRates = {};
|
|
297
|
-
// check if native currency is supported as a vs_currency by the API
|
|
298
|
-
const nativeCurrencySupported = yield this.checkIsSupportedVsCurrency(nativeCurrency);
|
|
299
|
-
if (nativeCurrencySupported) {
|
|
300
|
-
// If it is we can do a simple fetch against the CoinGecko API
|
|
301
|
-
const prices = yield this.fetchExchangeRate(chainSlug, nativeCurrency, tokenAddresses);
|
|
302
|
-
tokenAddresses.forEach((tokenAddress) => {
|
|
303
|
-
const price = prices[tokenAddress.toLowerCase()];
|
|
304
|
-
contractExchangeRates[(0, controller_utils_1.toChecksumHexAddress)(tokenAddress)] = price
|
|
305
|
-
? price[nativeCurrency.toLowerCase()]
|
|
306
|
-
: 0;
|
|
203
|
+
const { promise: inProgressUpdate, resolve: updateSucceeded, reject: updateFailed, } = createDeferredPromise({ suppressUnhandledRejection: true });
|
|
204
|
+
__classPrivateFieldGet(this, _TokenRatesController_inProcessExchangeRateUpdates, "f")[updateKey] = inProgressUpdate;
|
|
205
|
+
try {
|
|
206
|
+
const newContractExchangeRates = yield __classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_fetchAndMapExchangeRates).call(this, {
|
|
207
|
+
tokenAddresses,
|
|
208
|
+
chainId,
|
|
209
|
+
nativeCurrency,
|
|
307
210
|
});
|
|
211
|
+
const existingContractExchangeRates = this.state.contractExchangeRates;
|
|
212
|
+
const updatedContractExchangeRates = chainId === this.config.chainId &&
|
|
213
|
+
nativeCurrency === this.config.nativeCurrency
|
|
214
|
+
? newContractExchangeRates
|
|
215
|
+
: existingContractExchangeRates;
|
|
216
|
+
const existingContractExchangeRatesForChainId = (_a = this.state.contractExchangeRatesByChainId[chainId]) !== null && _a !== void 0 ? _a : {};
|
|
217
|
+
const updatedContractExchangeRatesForChainId = Object.assign(Object.assign({}, this.state.contractExchangeRatesByChainId), { [chainId]: Object.assign(Object.assign({}, existingContractExchangeRatesForChainId), { [nativeCurrency]: Object.assign(Object.assign({}, existingContractExchangeRatesForChainId[nativeCurrency]), newContractExchangeRates) }) });
|
|
218
|
+
this.update({
|
|
219
|
+
contractExchangeRates: updatedContractExchangeRates,
|
|
220
|
+
contractExchangeRatesByChainId: updatedContractExchangeRatesForChainId,
|
|
221
|
+
});
|
|
222
|
+
updateSucceeded();
|
|
308
223
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
[
|
|
316
|
-
tokenExchangeRates,
|
|
317
|
-
{ conversionRate: vsCurrencyToNativeCurrencyConversionRate },
|
|
318
|
-
] = yield Promise.all([
|
|
319
|
-
this.fetchExchangeRate(chainSlug, controller_utils_1.FALL_BACK_VS_CURRENCY, tokenAddresses),
|
|
320
|
-
(0, crypto_compare_1.fetchExchangeRate)(nativeCurrency, controller_utils_1.FALL_BACK_VS_CURRENCY, false),
|
|
321
|
-
]);
|
|
322
|
-
}
|
|
323
|
-
catch (error) {
|
|
324
|
-
if (error instanceof Error &&
|
|
325
|
-
error.message.includes('market does not exist for this coin pair')) {
|
|
326
|
-
return {};
|
|
327
|
-
}
|
|
328
|
-
throw error;
|
|
329
|
-
}
|
|
330
|
-
for (const [tokenAddress, conversion] of Object.entries(tokenExchangeRates)) {
|
|
331
|
-
const tokenToVsCurrencyConversionRate = conversion[controller_utils_1.FALL_BACK_VS_CURRENCY.toLowerCase()];
|
|
332
|
-
contractExchangeRates[(0, controller_utils_1.toChecksumHexAddress)(tokenAddress)] =
|
|
333
|
-
tokenToVsCurrencyConversionRate *
|
|
334
|
-
vsCurrencyToNativeCurrencyConversionRate;
|
|
335
|
-
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
updateFailed(error);
|
|
226
|
+
throw error;
|
|
227
|
+
}
|
|
228
|
+
finally {
|
|
229
|
+
delete __classPrivateFieldGet(this, _TokenRatesController_inProcessExchangeRateUpdates, "f")[updateKey];
|
|
336
230
|
}
|
|
337
|
-
return contractExchangeRates;
|
|
338
231
|
});
|
|
339
232
|
}
|
|
340
233
|
/**
|
|
341
|
-
* Updates token rates for the given networkClientId
|
|
234
|
+
* Updates token rates for the given networkClientId
|
|
342
235
|
*
|
|
343
236
|
* @param networkClientId - The network client ID used to get a ticker value.
|
|
344
|
-
* @param options - The polling options.
|
|
345
|
-
* @param options.tokenAddresses - The addresses for the token contracts.
|
|
346
237
|
* @returns The controller state.
|
|
347
238
|
*/
|
|
348
|
-
_executePoll(networkClientId
|
|
239
|
+
_executePoll(networkClientId) {
|
|
349
240
|
return __awaiter(this, void 0, void 0, function* () {
|
|
350
241
|
const networkClient = this.getNetworkClientById(networkClientId);
|
|
351
242
|
yield this.updateExchangeRatesByChainId({
|
|
352
243
|
chainId: networkClient.configuration.chainId,
|
|
353
244
|
nativeCurrency: networkClient.configuration.ticker,
|
|
354
|
-
tokenAddresses: options.tokenAddresses,
|
|
355
245
|
});
|
|
356
246
|
});
|
|
357
247
|
}
|
|
358
248
|
}
|
|
359
249
|
exports.TokenRatesController = TokenRatesController;
|
|
360
|
-
_TokenRatesController_pollState = new WeakMap(), _TokenRatesController_instances = new WeakSet(),
|
|
250
|
+
_TokenRatesController_pollState = new WeakMap(), _TokenRatesController_tokenPricesService = new WeakMap(), _TokenRatesController_inProcessExchangeRateUpdates = new WeakMap(), _TokenRatesController_instances = new WeakSet(), _TokenRatesController_getTokenAddresses = function _TokenRatesController_getTokenAddresses(chainId) {
|
|
361
251
|
var _a, _b;
|
|
362
252
|
const { allTokens, allDetectedTokens } = this.config;
|
|
363
|
-
const tokens = ((_a = allTokens[
|
|
364
|
-
const detectedTokens = ((_b = allDetectedTokens[
|
|
365
|
-
|
|
366
|
-
|
|
253
|
+
const tokens = ((_a = allTokens[chainId]) === null || _a === void 0 ? void 0 : _a[this.config.selectedAddress]) || [];
|
|
254
|
+
const detectedTokens = ((_b = allDetectedTokens[chainId]) === null || _b === void 0 ? void 0 : _b[this.config.selectedAddress]) || [];
|
|
255
|
+
return [
|
|
256
|
+
...new Set([...tokens, ...detectedTokens].map((token) => (0, controller_utils_1.toHex)((0, controller_utils_1.toChecksumHexAddress)(token.address)))),
|
|
257
|
+
].sort();
|
|
367
258
|
}, _TokenRatesController_stopPoll = function _TokenRatesController_stopPoll() {
|
|
368
259
|
if (this.handle) {
|
|
369
260
|
clearTimeout(this.handle);
|
|
@@ -377,6 +268,92 @@ _TokenRatesController_pollState = new WeakMap(), _TokenRatesController_instances
|
|
|
377
268
|
__classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_poll).call(this);
|
|
378
269
|
}, this.config.interval);
|
|
379
270
|
});
|
|
271
|
+
}, _TokenRatesController_fetchAndMapExchangeRates = function _TokenRatesController_fetchAndMapExchangeRates({ tokenAddresses, chainId, nativeCurrency, }) {
|
|
272
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
273
|
+
if (!__classPrivateFieldGet(this, _TokenRatesController_tokenPricesService, "f").validateChainIdSupported(chainId)) {
|
|
274
|
+
return tokenAddresses.reduce((obj, tokenAddress) => {
|
|
275
|
+
return Object.assign(Object.assign({}, obj), { [tokenAddress]: undefined });
|
|
276
|
+
}, {});
|
|
277
|
+
}
|
|
278
|
+
if (__classPrivateFieldGet(this, _TokenRatesController_tokenPricesService, "f").validateCurrencySupported(nativeCurrency)) {
|
|
279
|
+
return yield __classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_fetchAndMapExchangeRatesForSupportedNativeCurrency).call(this, {
|
|
280
|
+
tokenAddresses,
|
|
281
|
+
chainId,
|
|
282
|
+
nativeCurrency,
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
return yield __classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_fetchAndMapExchangeRatesForUnsupportedNativeCurrency).call(this, {
|
|
286
|
+
tokenAddresses,
|
|
287
|
+
nativeCurrency,
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
}, _TokenRatesController_fetchAndMapExchangeRatesForSupportedNativeCurrency = function _TokenRatesController_fetchAndMapExchangeRatesForSupportedNativeCurrency({ tokenAddresses, chainId, nativeCurrency, }) {
|
|
291
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
292
|
+
const tokenPricesByTokenAddress = yield (0, assetsUtil_1.reduceInBatchesSerially)({
|
|
293
|
+
values: tokenAddresses,
|
|
294
|
+
batchSize: TOKEN_PRICES_BATCH_SIZE,
|
|
295
|
+
eachBatch: (allTokenPricesByTokenAddress, batch) => __awaiter(this, void 0, void 0, function* () {
|
|
296
|
+
const tokenPricesByTokenAddressForBatch = yield __classPrivateFieldGet(this, _TokenRatesController_tokenPricesService, "f").fetchTokenPrices({
|
|
297
|
+
tokenAddresses: batch,
|
|
298
|
+
chainId,
|
|
299
|
+
currency: nativeCurrency,
|
|
300
|
+
});
|
|
301
|
+
return Object.assign(Object.assign({}, allTokenPricesByTokenAddress), tokenPricesByTokenAddressForBatch);
|
|
302
|
+
}),
|
|
303
|
+
initialResult: {},
|
|
304
|
+
});
|
|
305
|
+
return Object.entries(tokenPricesByTokenAddress).reduce((obj, [tokenAddress, tokenPrice]) => {
|
|
306
|
+
return Object.assign(Object.assign({}, obj), { [tokenAddress]: tokenPrice.value });
|
|
307
|
+
}, {});
|
|
308
|
+
});
|
|
309
|
+
}, _TokenRatesController_fetchAndMapExchangeRatesForUnsupportedNativeCurrency = function _TokenRatesController_fetchAndMapExchangeRatesForUnsupportedNativeCurrency({ tokenAddresses, nativeCurrency, }) {
|
|
310
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
311
|
+
const [contractExchangeRates, fallbackCurrencyToNativeCurrencyConversionRate,] = yield Promise.all([
|
|
312
|
+
__classPrivateFieldGet(this, _TokenRatesController_instances, "m", _TokenRatesController_fetchAndMapExchangeRatesForSupportedNativeCurrency).call(this, {
|
|
313
|
+
tokenAddresses,
|
|
314
|
+
chainId: this.config.chainId,
|
|
315
|
+
nativeCurrency: controller_utils_1.FALL_BACK_VS_CURRENCY,
|
|
316
|
+
}),
|
|
317
|
+
getCurrencyConversionRate({
|
|
318
|
+
from: controller_utils_1.FALL_BACK_VS_CURRENCY,
|
|
319
|
+
to: nativeCurrency,
|
|
320
|
+
}),
|
|
321
|
+
]);
|
|
322
|
+
if (fallbackCurrencyToNativeCurrencyConversionRate === null) {
|
|
323
|
+
return {};
|
|
324
|
+
}
|
|
325
|
+
return Object.entries(contractExchangeRates).reduce((obj, [tokenAddress, tokenValue]) => {
|
|
326
|
+
return Object.assign(Object.assign({}, obj), { [tokenAddress]: tokenValue
|
|
327
|
+
? tokenValue * fallbackCurrencyToNativeCurrencyConversionRate
|
|
328
|
+
: undefined });
|
|
329
|
+
}, {});
|
|
330
|
+
});
|
|
380
331
|
};
|
|
332
|
+
/**
|
|
333
|
+
* Create a defered Promise.
|
|
334
|
+
*
|
|
335
|
+
* TODO: Migrate this to utils
|
|
336
|
+
*
|
|
337
|
+
* @param args - The arguments.
|
|
338
|
+
* @param args.suppressUnhandledRejection - This option adds an empty error handler
|
|
339
|
+
* to the Promise to suppress the UnhandledPromiseRejection error. This can be
|
|
340
|
+
* useful if the deferred Promise is sometimes intentionally not used.
|
|
341
|
+
* @returns A deferred Promise.
|
|
342
|
+
*/
|
|
343
|
+
function createDeferredPromise({ suppressUnhandledRejection = false, }) {
|
|
344
|
+
let resolve;
|
|
345
|
+
let reject;
|
|
346
|
+
const promise = new Promise((innerResolve, innerReject) => {
|
|
347
|
+
resolve = innerResolve;
|
|
348
|
+
reject = innerReject;
|
|
349
|
+
});
|
|
350
|
+
if (suppressUnhandledRejection) {
|
|
351
|
+
promise.catch((_error) => {
|
|
352
|
+
// This handler is used to suppress the UnhandledPromiseRejection error
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
// @ts-expect-error We know that these are assigned, but TypeScript doesn't
|
|
356
|
+
return { promise, resolve, reject };
|
|
357
|
+
}
|
|
381
358
|
exports.default = TokenRatesController;
|
|
382
359
|
//# sourceMappingURL=TokenRatesController.js.map
|