@strkfarm/sdk 2.0.0-dev.50 → 2.0.0-dev.51

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.
@@ -8,6 +8,11 @@ import { logger } from "@/utils/logger";
8
8
  import { AvnuWrapper } from "./avnu";
9
9
  import { BlockIdentifier } from "starknet";
10
10
  import { PricerAvnuApi } from "./pricer-avnu-api";
11
+ import {
12
+ convertQuoteAmountToUsd,
13
+ PRICER_USDC_ADDRESS,
14
+ resolveQuoteTokenConfig,
15
+ } from "./pricer-quote-utils";
11
16
 
12
17
  export interface PriceInfo {
13
18
  price: number,
@@ -41,7 +46,7 @@ export class Pricer extends PricerBase {
41
46
  */
42
47
  // ! switch to USDC (new) later
43
48
  protected PRICE_API = `https://api.coinbase.com/v2/prices/{{PRICER_KEY}}/buy`;
44
- protected EKUBO_API = 'https://prod-api-quoter.ekubo.org/23448594291968334/{{AMOUNT}}/{{TOKEN_ADDRESS}}/0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb'; // e.g. ETH/USDC
49
+ protected EKUBO_API = `https://prod-api-quoter.ekubo.org/23448594291968334/{{AMOUNT}}/{{TOKEN_ADDRESS}}/${PRICER_USDC_ADDRESS}`; // e.g. ETH/USDC
45
50
 
46
51
  constructor(config: IConfig, tokens: TokenInfo[], refreshInterval = 30000, staleTime = 60000) {
47
52
  super(config, tokens);
@@ -242,48 +247,80 @@ export class Pricer extends PricerBase {
242
247
  throw new Error("Not implemented");
243
248
  }
244
249
 
250
+ protected async _resolveQuoteTokenUsdPrice(symbol: string): Promise<number> {
251
+ const cached = this.prices[symbol];
252
+ if (cached && !this.isStale(cached.timestamp, symbol)) {
253
+ return cached.price;
254
+ }
255
+
256
+ const quoteToken = this.tokens.find((t) => t.symbol === symbol);
257
+ if (!quoteToken) {
258
+ throw new FatalError(`Quote token ${symbol} not found in pricer tokens`);
259
+ }
260
+
261
+ return await this._getPrice(quoteToken);
262
+ }
263
+
264
+ protected async _convertDexQuoteToUsd(
265
+ token: TokenInfo,
266
+ quoteAmount: number,
267
+ ): Promise<number> {
268
+ const quoteConfig = resolveQuoteTokenConfig(token, this.tokens);
269
+ const usdPrice = await convertQuoteAmountToUsd(
270
+ token.symbol,
271
+ quoteAmount,
272
+ quoteConfig,
273
+ this._resolveQuoteTokenUsdPrice.bind(this),
274
+ );
275
+ logger.verbose(
276
+ `${token.symbol}: ${quoteAmount} ${quoteConfig.symbol} -> $${usdPrice}`,
277
+ );
278
+ return usdPrice;
279
+ }
280
+
245
281
  async _getAvnuPrice(token: TokenInfo, amountIn = new Web3Number(1, token.decimals), retry = 0): Promise<number> {
246
- logger.verbose(`Getting price of ${token.symbol} using Ekubo, amountIn: ${amountIn.toWei()}`);
247
-
282
+ const quoteConfig = resolveQuoteTokenConfig(token, this.tokens);
283
+ logger.verbose(`Getting price of ${token.symbol} using Avnu, amountIn: ${amountIn.toWei()}`);
284
+
248
285
  const avnuWrapper = new AvnuWrapper();
249
- const usdcAddress = '0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb';
250
- const quote = await avnuWrapper.getQuotes(token.address.toString(), usdcAddress, amountIn.toWei(), '0x1');
286
+ const quote = await avnuWrapper.getQuotes(
287
+ token.address.toString(),
288
+ quoteConfig.address,
289
+ amountIn.toWei(),
290
+ "0x1",
291
+ );
251
292
  const multiplier = 1 / amountIn.toNumber();
252
- const outputUSDC = Number(Web3Number.fromWei(quote.buyAmount.toString(), 6).toFixed(6)) * multiplier;
253
- logger.verbose(`Avnu: ${token.symbol} -> USDC: ${outputUSDC}, retry: ${retry}`);
254
- if (outputUSDC === 0 && retry < 3) {
255
- // try again with a higher amount
256
- const amountIn = new Web3Number(100, token.decimals); // 100 unit of token
257
- return await this._getAvnuPrice(token, amountIn, retry + 1);
293
+ const outputQuote = Number(
294
+ Web3Number.fromWei(quote.buyAmount.toString(), quoteConfig.decimals).toFixed(6),
295
+ ) * multiplier;
296
+ logger.verbose(`Avnu: ${token.symbol} -> ${quoteConfig.symbol}: ${outputQuote}, retry: ${retry}`);
297
+ if (outputQuote === 0 && retry < 3) {
298
+ const retryAmountIn = new Web3Number(100, token.decimals);
299
+ return await this._getAvnuPrice(token, retryAmountIn, retry + 1);
258
300
  }
259
301
 
260
- // if usdc depegs, it will not longer be 1 USD
261
- // so we need to get the price of USDC in USD
262
- // and then convert the outputUSDC to USD
263
- const usdcPrice = 1; // (await this.getPrice('USDC')).price;
264
- logger.verbose(`USDC Price: ${usdcPrice}`);
265
- return outputUSDC * usdcPrice;
302
+ return await this._convertDexQuoteToUsd(token, outputQuote);
266
303
  }
267
304
 
268
305
  async _getPriceEkubo(token: TokenInfo, amountIn = new Web3Number(1, token.decimals), retry = 0): Promise<number> {
306
+ const quoteConfig = resolveQuoteTokenConfig(token, this.tokens);
269
307
  logger.verbose(`Getting price of ${token.symbol} using Ekubo, amountIn: ${amountIn.toWei()}`);
270
- const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address.toString()).replace("{{AMOUNT}}", amountIn.toWei());
308
+ const url = this.EKUBO_API
309
+ .replace("{{TOKEN_ADDRESS}}", token.address.toString())
310
+ .replace("{{AMOUNT}}", amountIn.toWei())
311
+ .replace(PRICER_USDC_ADDRESS, quoteConfig.address);
271
312
  const result = await axios.get(url);
272
313
  const data: any = result.data;
273
314
  const multiplier = 1 / amountIn.toNumber();
274
- const outputUSDC = Number(Web3Number.fromWei(data.total_calculated, 6).toFixed(6)) * multiplier;
275
- logger.verbose(`Ekubo: ${token.symbol} -> USDC: ${outputUSDC}, retry: ${retry}`);
276
- if (outputUSDC === 0 && retry < 3) {
277
- // try again with a higher amount
278
- const amountIn = new Web3Number(100, token.decimals); // 100 unit of token
279
- return await this._getPriceEkubo(token, amountIn, retry + 1);
315
+ const outputQuote = Number(
316
+ Web3Number.fromWei(data.total_calculated, quoteConfig.decimals).toFixed(6),
317
+ ) * multiplier;
318
+ logger.verbose(`Ekubo: ${token.symbol} -> ${quoteConfig.symbol}: ${outputQuote}, retry: ${retry}`);
319
+ if (outputQuote === 0 && retry < 3) {
320
+ const retryAmountIn = new Web3Number(100, token.decimals);
321
+ return await this._getPriceEkubo(token, retryAmountIn, retry + 1);
280
322
  }
281
323
 
282
- // if usdc depegs, it will not longer be 1 USD
283
- // so we need to get the price of USDC in USD
284
- // and then convert the outputUSDC to USD
285
- const usdcPrice = 1; // (await this.getPrice('USDC')).price;
286
- logger.verbose(`USDC Price: ${usdcPrice}`);
287
- return outputUSDC * usdcPrice;
324
+ return await this._convertDexQuoteToUsd(token, outputQuote);
288
325
  }
289
326
  }