@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.
@@ -75194,7 +75194,8 @@ ${JSON.stringify(data, null, 2)}`;
75194
75194
  priceCheckAmount: 5e3,
75195
75195
  displayDecimals: 2,
75196
75196
  priceMethod: "Avnu",
75197
- indexingType: "lstScript" /* LST_SCRIPT */
75197
+ indexingType: "lstScript" /* LST_SCRIPT */,
75198
+ intermediateQuoteTokenSymbol: "STRK"
75198
75199
  }, {
75199
75200
  name: "ETH",
75200
75201
  symbol: "ETH",
@@ -80156,6 +80157,42 @@ ${JSON.stringify(data, null, 2)}`;
80156
80157
  }
80157
80158
  };
80158
80159
 
80160
+ // src/modules/pricer-quote-utils.ts
80161
+ var PRICER_USDC_ADDRESS = "0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb";
80162
+ var PRICER_USDC_DECIMALS = 6;
80163
+ function resolveQuoteTokenConfig(token, tokens2) {
80164
+ if (token.intermediateQuoteTokenSymbol) {
80165
+ const intermediateToken = tokens2.find(
80166
+ (t) => t.symbol === token.intermediateQuoteTokenSymbol
80167
+ );
80168
+ if (!intermediateToken) {
80169
+ throw new Error(
80170
+ `Intermediate quote token ${token.intermediateQuoteTokenSymbol} not found for ${token.symbol}`
80171
+ );
80172
+ }
80173
+ return {
80174
+ address: intermediateToken.address.toString(),
80175
+ decimals: intermediateToken.decimals,
80176
+ symbol: intermediateToken.symbol,
80177
+ isUsdQuote: false
80178
+ };
80179
+ }
80180
+ return {
80181
+ address: PRICER_USDC_ADDRESS,
80182
+ decimals: PRICER_USDC_DECIMALS,
80183
+ symbol: "USDC",
80184
+ isUsdQuote: true
80185
+ };
80186
+ }
80187
+ async function convertQuoteAmountToUsd(tokenSymbol, quoteAmount, quoteConfig, resolveUsdPrice) {
80188
+ if (quoteConfig.isUsdQuote) {
80189
+ const usdcPrice = await resolveUsdPrice("USDC");
80190
+ return quoteAmount * usdcPrice;
80191
+ }
80192
+ const intermediateUsdPrice = await resolveUsdPrice(quoteConfig.symbol);
80193
+ return quoteAmount * intermediateUsdPrice;
80194
+ }
80195
+
80159
80196
  // src/modules/pricer.ts
80160
80197
  var PRICE_METHOD_PRIORITY = [
80161
80198
  "AvnuApi",
@@ -80179,7 +80216,7 @@ ${JSON.stringify(data, null, 2)}`;
80179
80216
  */
80180
80217
  // ! switch to USDC (new) later
80181
80218
  this.PRICE_API = `https://api.coinbase.com/v2/prices/{{PRICER_KEY}}/buy`;
80182
- this.EKUBO_API = "https://prod-api-quoter.ekubo.org/23448594291968334/{{AMOUNT}}/{{TOKEN_ADDRESS}}/0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb";
80219
+ this.EKUBO_API = `https://prod-api-quoter.ekubo.org/23448594291968334/{{AMOUNT}}/{{TOKEN_ADDRESS}}/${PRICER_USDC_ADDRESS}`;
80183
80220
  this.refreshInterval = refreshInterval;
80184
80221
  this.staleTime = staleTime;
80185
80222
  this.avnuApiPricer = new PricerAvnuApi(config3, tokens2);
@@ -80352,37 +80389,67 @@ ${JSON.stringify(data, null, 2)}`;
80352
80389
  async _getPriceCoinMarketCap(token) {
80353
80390
  throw new Error("Not implemented");
80354
80391
  }
80392
+ async _resolveQuoteTokenUsdPrice(symbol) {
80393
+ const cached = this.prices[symbol];
80394
+ if (cached && !this.isStale(cached.timestamp, symbol)) {
80395
+ return cached.price;
80396
+ }
80397
+ const quoteToken = this.tokens.find((t) => t.symbol === symbol);
80398
+ if (!quoteToken) {
80399
+ throw new FatalError(`Quote token ${symbol} not found in pricer tokens`);
80400
+ }
80401
+ return await this._getPrice(quoteToken);
80402
+ }
80403
+ async _convertDexQuoteToUsd(token, quoteAmount) {
80404
+ const quoteConfig = resolveQuoteTokenConfig(token, this.tokens);
80405
+ const usdPrice = await convertQuoteAmountToUsd(
80406
+ token.symbol,
80407
+ quoteAmount,
80408
+ quoteConfig,
80409
+ this._resolveQuoteTokenUsdPrice.bind(this)
80410
+ );
80411
+ logger2.verbose(
80412
+ `${token.symbol}: ${quoteAmount} ${quoteConfig.symbol} -> $${usdPrice}`
80413
+ );
80414
+ return usdPrice;
80415
+ }
80355
80416
  async _getAvnuPrice(token, amountIn = new Web3Number(1, token.decimals), retry = 0) {
80356
- logger2.verbose(`Getting price of ${token.symbol} using Ekubo, amountIn: ${amountIn.toWei()}`);
80417
+ const quoteConfig = resolveQuoteTokenConfig(token, this.tokens);
80418
+ logger2.verbose(`Getting price of ${token.symbol} using Avnu, amountIn: ${amountIn.toWei()}`);
80357
80419
  const avnuWrapper = new AvnuWrapper();
80358
- const usdcAddress = "0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb";
80359
- const quote = await avnuWrapper.getQuotes(token.address.toString(), usdcAddress, amountIn.toWei(), "0x1");
80420
+ const quote = await avnuWrapper.getQuotes(
80421
+ token.address.toString(),
80422
+ quoteConfig.address,
80423
+ amountIn.toWei(),
80424
+ "0x1"
80425
+ );
80360
80426
  const multiplier = 1 / amountIn.toNumber();
80361
- const outputUSDC = Number(Web3Number.fromWei(quote.buyAmount.toString(), 6).toFixed(6)) * multiplier;
80362
- logger2.verbose(`Avnu: ${token.symbol} -> USDC: ${outputUSDC}, retry: ${retry}`);
80363
- if (outputUSDC === 0 && retry < 3) {
80364
- const amountIn2 = new Web3Number(100, token.decimals);
80365
- return await this._getAvnuPrice(token, amountIn2, retry + 1);
80427
+ const outputQuote = Number(
80428
+ Web3Number.fromWei(quote.buyAmount.toString(), quoteConfig.decimals).toFixed(6)
80429
+ ) * multiplier;
80430
+ logger2.verbose(`Avnu: ${token.symbol} -> ${quoteConfig.symbol}: ${outputQuote}, retry: ${retry}`);
80431
+ if (outputQuote === 0 && retry < 3) {
80432
+ const retryAmountIn = new Web3Number(100, token.decimals);
80433
+ return await this._getAvnuPrice(token, retryAmountIn, retry + 1);
80366
80434
  }
80367
- const usdcPrice = 1;
80368
- logger2.verbose(`USDC Price: ${usdcPrice}`);
80369
- return outputUSDC * usdcPrice;
80435
+ return await this._convertDexQuoteToUsd(token, outputQuote);
80370
80436
  }
80371
80437
  async _getPriceEkubo(token, amountIn = new Web3Number(1, token.decimals), retry = 0) {
80438
+ const quoteConfig = resolveQuoteTokenConfig(token, this.tokens);
80372
80439
  logger2.verbose(`Getting price of ${token.symbol} using Ekubo, amountIn: ${amountIn.toWei()}`);
80373
- const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address.toString()).replace("{{AMOUNT}}", amountIn.toWei());
80440
+ const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address.toString()).replace("{{AMOUNT}}", amountIn.toWei()).replace(PRICER_USDC_ADDRESS, quoteConfig.address);
80374
80441
  const result2 = await axios_default.get(url);
80375
80442
  const data = result2.data;
80376
80443
  const multiplier = 1 / amountIn.toNumber();
80377
- const outputUSDC = Number(Web3Number.fromWei(data.total_calculated, 6).toFixed(6)) * multiplier;
80378
- logger2.verbose(`Ekubo: ${token.symbol} -> USDC: ${outputUSDC}, retry: ${retry}`);
80379
- if (outputUSDC === 0 && retry < 3) {
80380
- const amountIn2 = new Web3Number(100, token.decimals);
80381
- return await this._getPriceEkubo(token, amountIn2, retry + 1);
80444
+ const outputQuote = Number(
80445
+ Web3Number.fromWei(data.total_calculated, quoteConfig.decimals).toFixed(6)
80446
+ ) * multiplier;
80447
+ logger2.verbose(`Ekubo: ${token.symbol} -> ${quoteConfig.symbol}: ${outputQuote}, retry: ${retry}`);
80448
+ if (outputQuote === 0 && retry < 3) {
80449
+ const retryAmountIn = new Web3Number(100, token.decimals);
80450
+ return await this._getPriceEkubo(token, retryAmountIn, retry + 1);
80382
80451
  }
80383
- const usdcPrice = 1;
80384
- logger2.verbose(`USDC Price: ${usdcPrice}`);
80385
- return outputUSDC * usdcPrice;
80452
+ return await this._convertDexQuoteToUsd(token, outputQuote);
80386
80453
  }
80387
80454
  };
80388
80455
 
@@ -93267,12 +93334,10 @@ spurious results.`);
93267
93334
 
93268
93335
  // src/modules/ekubo-pricer.ts
93269
93336
  var EkuboPricer = class extends PricerBase {
93270
- constructor(config3, tokens2) {
93337
+ constructor(config3, tokens2, resolveUsdPrice) {
93271
93338
  super(config3, tokens2);
93339
+ this.resolveUsdPrice = resolveUsdPrice;
93272
93340
  this.EKUBO_PRICE_FETCHER_ADDRESS = "0x04946fb4ad5237d97bbb1256eba2080c4fe1de156da6a7f83e3b4823bb6d7da1";
93273
- // Updating to new USDC_ADDRESS
93274
- this.USDC_ADDRESS = "0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb";
93275
- this.USDC_DECIMALS = 6;
93276
93341
  this.contract = new Contract({
93277
93342
  abi: ekubo_price_fethcer_abi_default,
93278
93343
  address: this.EKUBO_PRICE_FETCHER_ADDRESS,
@@ -93286,9 +93351,16 @@ spurious results.`);
93286
93351
  if (!tokenAddr) {
93287
93352
  throw new Error(`EkuboPricer:getPrice - no token`);
93288
93353
  }
93354
+ const tokenInfo = this.tokens.find(
93355
+ (t) => t.address.eqString(tokenAddr)
93356
+ );
93357
+ if (!tokenInfo) {
93358
+ throw new Error(`Token ${tokenAddr} not found in global tokens`);
93359
+ }
93360
+ const quoteConfig = resolveQuoteTokenConfig(tokenInfo, this.tokens);
93289
93361
  const result2 = await this.contract.call(
93290
93362
  "get_prices",
93291
- [this.USDC_ADDRESS, [tokenAddr], 3600, 1e6],
93363
+ [quoteConfig.address, [tokenAddr], 3600, 1e6],
93292
93364
  { blockIdentifier }
93293
93365
  );
93294
93366
  if (!result2 || result2.length === 0) {
@@ -93300,17 +93372,23 @@ spurious results.`);
93300
93372
  throw new Error(`EkuboPricer: Price fetch failed with variant: ${variant}`);
93301
93373
  }
93302
93374
  const rawPrice = typeof priceResult.variant.Price === "string" ? BigInt(priceResult.variant.Price) : priceResult.variant.Price;
93303
- const tokenInfo = this.tokens.find(
93304
- (t) => t.address.address.toLowerCase() === tokenAddr.toLowerCase()
93305
- );
93306
- if (!tokenInfo) {
93307
- throw new Error(`Token ${tokenAddr} not found in global tokens`);
93308
- }
93309
93375
  const priceAfterX128 = this.div2Power128(rawPrice);
93310
- const decimalAdjustment = 10 ** (tokenInfo.decimals - this.USDC_DECIMALS);
93311
- const price = priceAfterX128 * decimalAdjustment;
93376
+ const decimalAdjustment = 10 ** (tokenInfo.decimals - quoteConfig.decimals);
93377
+ const priceInQuote = priceAfterX128 * decimalAdjustment;
93378
+ if (!quoteConfig.isUsdQuote) {
93379
+ if (!this.resolveUsdPrice) {
93380
+ throw new Error(
93381
+ `EkuboPricer: USD price resolver required for ${tokenInfo.symbol} via ${quoteConfig.symbol}`
93382
+ );
93383
+ }
93384
+ const quoteUsdPrice = await this.resolveUsdPrice(quoteConfig.symbol);
93385
+ return {
93386
+ price: priceInQuote * quoteUsdPrice,
93387
+ timestamp: /* @__PURE__ */ new Date()
93388
+ };
93389
+ }
93312
93390
  return {
93313
- price,
93391
+ price: priceInQuote,
93314
93392
  timestamp: /* @__PURE__ */ new Date()
93315
93393
  };
93316
93394
  }
@@ -93338,7 +93416,10 @@ spurious results.`);
93338
93416
  ];
93339
93417
  this.apolloClient = createApolloClient(config3);
93340
93418
  this.pragma = new Pragma(config3, tokens2);
93341
- this.ekuboPricer = new EkuboPricer(config3, tokens2);
93419
+ this.ekuboPricer = new EkuboPricer(config3, tokens2, async (symbol) => {
93420
+ const priceInfo = await this.getPriceFromMyAPI(symbol);
93421
+ return priceInfo.price;
93422
+ });
93342
93423
  }
93343
93424
  async getPrice(tokenSymbol, blockNumber) {
93344
93425
  const tokenInfo = this.tokens.find((t) => t.symbol === tokenSymbol);
@@ -554,7 +554,8 @@ var defaultTokens = [{
554
554
  priceCheckAmount: 5e3,
555
555
  displayDecimals: 2,
556
556
  priceMethod: "Avnu",
557
- indexingType: "lstScript" /* LST_SCRIPT */
557
+ indexingType: "lstScript" /* LST_SCRIPT */,
558
+ intermediateQuoteTokenSymbol: "STRK"
558
559
  }, {
559
560
  name: "ETH",
560
561
  symbol: "ETH",
@@ -3941,6 +3942,42 @@ var PricerAvnuApi = class extends PricerBase {
3941
3942
  }
3942
3943
  };
3943
3944
 
3945
+ // src/modules/pricer-quote-utils.ts
3946
+ var PRICER_USDC_ADDRESS = "0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb";
3947
+ var PRICER_USDC_DECIMALS = 6;
3948
+ function resolveQuoteTokenConfig(token, tokens2) {
3949
+ if (token.intermediateQuoteTokenSymbol) {
3950
+ const intermediateToken = tokens2.find(
3951
+ (t) => t.symbol === token.intermediateQuoteTokenSymbol
3952
+ );
3953
+ if (!intermediateToken) {
3954
+ throw new Error(
3955
+ `Intermediate quote token ${token.intermediateQuoteTokenSymbol} not found for ${token.symbol}`
3956
+ );
3957
+ }
3958
+ return {
3959
+ address: intermediateToken.address.toString(),
3960
+ decimals: intermediateToken.decimals,
3961
+ symbol: intermediateToken.symbol,
3962
+ isUsdQuote: false
3963
+ };
3964
+ }
3965
+ return {
3966
+ address: PRICER_USDC_ADDRESS,
3967
+ decimals: PRICER_USDC_DECIMALS,
3968
+ symbol: "USDC",
3969
+ isUsdQuote: true
3970
+ };
3971
+ }
3972
+ async function convertQuoteAmountToUsd(tokenSymbol, quoteAmount, quoteConfig, resolveUsdPrice) {
3973
+ if (quoteConfig.isUsdQuote) {
3974
+ const usdcPrice = await resolveUsdPrice("USDC");
3975
+ return quoteAmount * usdcPrice;
3976
+ }
3977
+ const intermediateUsdPrice = await resolveUsdPrice(quoteConfig.symbol);
3978
+ return quoteAmount * intermediateUsdPrice;
3979
+ }
3980
+
3944
3981
  // src/modules/pricer.ts
3945
3982
  var PRICE_METHOD_PRIORITY = [
3946
3983
  "AvnuApi",
@@ -3964,7 +4001,7 @@ var Pricer = class extends PricerBase {
3964
4001
  */
3965
4002
  // ! switch to USDC (new) later
3966
4003
  this.PRICE_API = `https://api.coinbase.com/v2/prices/{{PRICER_KEY}}/buy`;
3967
- this.EKUBO_API = "https://prod-api-quoter.ekubo.org/23448594291968334/{{AMOUNT}}/{{TOKEN_ADDRESS}}/0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb";
4004
+ this.EKUBO_API = `https://prod-api-quoter.ekubo.org/23448594291968334/{{AMOUNT}}/{{TOKEN_ADDRESS}}/${PRICER_USDC_ADDRESS}`;
3968
4005
  this.refreshInterval = refreshInterval;
3969
4006
  this.staleTime = staleTime;
3970
4007
  this.avnuApiPricer = new PricerAvnuApi(config, tokens2);
@@ -4137,37 +4174,67 @@ var Pricer = class extends PricerBase {
4137
4174
  async _getPriceCoinMarketCap(token) {
4138
4175
  throw new Error("Not implemented");
4139
4176
  }
4177
+ async _resolveQuoteTokenUsdPrice(symbol) {
4178
+ const cached = this.prices[symbol];
4179
+ if (cached && !this.isStale(cached.timestamp, symbol)) {
4180
+ return cached.price;
4181
+ }
4182
+ const quoteToken = this.tokens.find((t) => t.symbol === symbol);
4183
+ if (!quoteToken) {
4184
+ throw new FatalError(`Quote token ${symbol} not found in pricer tokens`);
4185
+ }
4186
+ return await this._getPrice(quoteToken);
4187
+ }
4188
+ async _convertDexQuoteToUsd(token, quoteAmount) {
4189
+ const quoteConfig = resolveQuoteTokenConfig(token, this.tokens);
4190
+ const usdPrice = await convertQuoteAmountToUsd(
4191
+ token.symbol,
4192
+ quoteAmount,
4193
+ quoteConfig,
4194
+ this._resolveQuoteTokenUsdPrice.bind(this)
4195
+ );
4196
+ logger.verbose(
4197
+ `${token.symbol}: ${quoteAmount} ${quoteConfig.symbol} -> $${usdPrice}`
4198
+ );
4199
+ return usdPrice;
4200
+ }
4140
4201
  async _getAvnuPrice(token, amountIn = new Web3Number(1, token.decimals), retry = 0) {
4141
- logger.verbose(`Getting price of ${token.symbol} using Ekubo, amountIn: ${amountIn.toWei()}`);
4202
+ const quoteConfig = resolveQuoteTokenConfig(token, this.tokens);
4203
+ logger.verbose(`Getting price of ${token.symbol} using Avnu, amountIn: ${amountIn.toWei()}`);
4142
4204
  const avnuWrapper = new AvnuWrapper();
4143
- const usdcAddress = "0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb";
4144
- const quote = await avnuWrapper.getQuotes(token.address.toString(), usdcAddress, amountIn.toWei(), "0x1");
4205
+ const quote = await avnuWrapper.getQuotes(
4206
+ token.address.toString(),
4207
+ quoteConfig.address,
4208
+ amountIn.toWei(),
4209
+ "0x1"
4210
+ );
4145
4211
  const multiplier = 1 / amountIn.toNumber();
4146
- const outputUSDC = Number(Web3Number.fromWei(quote.buyAmount.toString(), 6).toFixed(6)) * multiplier;
4147
- logger.verbose(`Avnu: ${token.symbol} -> USDC: ${outputUSDC}, retry: ${retry}`);
4148
- if (outputUSDC === 0 && retry < 3) {
4149
- const amountIn2 = new Web3Number(100, token.decimals);
4150
- return await this._getAvnuPrice(token, amountIn2, retry + 1);
4212
+ const outputQuote = Number(
4213
+ Web3Number.fromWei(quote.buyAmount.toString(), quoteConfig.decimals).toFixed(6)
4214
+ ) * multiplier;
4215
+ logger.verbose(`Avnu: ${token.symbol} -> ${quoteConfig.symbol}: ${outputQuote}, retry: ${retry}`);
4216
+ if (outputQuote === 0 && retry < 3) {
4217
+ const retryAmountIn = new Web3Number(100, token.decimals);
4218
+ return await this._getAvnuPrice(token, retryAmountIn, retry + 1);
4151
4219
  }
4152
- const usdcPrice = 1;
4153
- logger.verbose(`USDC Price: ${usdcPrice}`);
4154
- return outputUSDC * usdcPrice;
4220
+ return await this._convertDexQuoteToUsd(token, outputQuote);
4155
4221
  }
4156
4222
  async _getPriceEkubo(token, amountIn = new Web3Number(1, token.decimals), retry = 0) {
4223
+ const quoteConfig = resolveQuoteTokenConfig(token, this.tokens);
4157
4224
  logger.verbose(`Getting price of ${token.symbol} using Ekubo, amountIn: ${amountIn.toWei()}`);
4158
- const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address.toString()).replace("{{AMOUNT}}", amountIn.toWei());
4225
+ const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address.toString()).replace("{{AMOUNT}}", amountIn.toWei()).replace(PRICER_USDC_ADDRESS, quoteConfig.address);
4159
4226
  const result = await axios4.get(url);
4160
4227
  const data = result.data;
4161
4228
  const multiplier = 1 / amountIn.toNumber();
4162
- const outputUSDC = Number(Web3Number.fromWei(data.total_calculated, 6).toFixed(6)) * multiplier;
4163
- logger.verbose(`Ekubo: ${token.symbol} -> USDC: ${outputUSDC}, retry: ${retry}`);
4164
- if (outputUSDC === 0 && retry < 3) {
4165
- const amountIn2 = new Web3Number(100, token.decimals);
4166
- return await this._getPriceEkubo(token, amountIn2, retry + 1);
4229
+ const outputQuote = Number(
4230
+ Web3Number.fromWei(data.total_calculated, quoteConfig.decimals).toFixed(6)
4231
+ ) * multiplier;
4232
+ logger.verbose(`Ekubo: ${token.symbol} -> ${quoteConfig.symbol}: ${outputQuote}, retry: ${retry}`);
4233
+ if (outputQuote === 0 && retry < 3) {
4234
+ const retryAmountIn = new Web3Number(100, token.decimals);
4235
+ return await this._getPriceEkubo(token, retryAmountIn, retry + 1);
4167
4236
  }
4168
- const usdcPrice = 1;
4169
- logger.verbose(`USDC Price: ${usdcPrice}`);
4170
- return outputUSDC * usdcPrice;
4237
+ return await this._convertDexQuoteToUsd(token, outputQuote);
4171
4238
  }
4172
4239
  };
4173
4240
 
@@ -4732,12 +4799,10 @@ var ekubo_price_fethcer_abi_default = [
4732
4799
 
4733
4800
  // src/modules/ekubo-pricer.ts
4734
4801
  var EkuboPricer = class extends PricerBase {
4735
- constructor(config, tokens2) {
4802
+ constructor(config, tokens2, resolveUsdPrice) {
4736
4803
  super(config, tokens2);
4804
+ this.resolveUsdPrice = resolveUsdPrice;
4737
4805
  this.EKUBO_PRICE_FETCHER_ADDRESS = "0x04946fb4ad5237d97bbb1256eba2080c4fe1de156da6a7f83e3b4823bb6d7da1";
4738
- // Updating to new USDC_ADDRESS
4739
- this.USDC_ADDRESS = "0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb";
4740
- this.USDC_DECIMALS = 6;
4741
4806
  this.contract = new Contract3({
4742
4807
  abi: ekubo_price_fethcer_abi_default,
4743
4808
  address: this.EKUBO_PRICE_FETCHER_ADDRESS,
@@ -4751,9 +4816,16 @@ var EkuboPricer = class extends PricerBase {
4751
4816
  if (!tokenAddr) {
4752
4817
  throw new Error(`EkuboPricer:getPrice - no token`);
4753
4818
  }
4819
+ const tokenInfo = this.tokens.find(
4820
+ (t) => t.address.eqString(tokenAddr)
4821
+ );
4822
+ if (!tokenInfo) {
4823
+ throw new Error(`Token ${tokenAddr} not found in global tokens`);
4824
+ }
4825
+ const quoteConfig = resolveQuoteTokenConfig(tokenInfo, this.tokens);
4754
4826
  const result = await this.contract.call(
4755
4827
  "get_prices",
4756
- [this.USDC_ADDRESS, [tokenAddr], 3600, 1e6],
4828
+ [quoteConfig.address, [tokenAddr], 3600, 1e6],
4757
4829
  { blockIdentifier }
4758
4830
  );
4759
4831
  if (!result || result.length === 0) {
@@ -4765,17 +4837,23 @@ var EkuboPricer = class extends PricerBase {
4765
4837
  throw new Error(`EkuboPricer: Price fetch failed with variant: ${variant}`);
4766
4838
  }
4767
4839
  const rawPrice = typeof priceResult.variant.Price === "string" ? BigInt(priceResult.variant.Price) : priceResult.variant.Price;
4768
- const tokenInfo = this.tokens.find(
4769
- (t) => t.address.address.toLowerCase() === tokenAddr.toLowerCase()
4770
- );
4771
- if (!tokenInfo) {
4772
- throw new Error(`Token ${tokenAddr} not found in global tokens`);
4773
- }
4774
4840
  const priceAfterX128 = this.div2Power128(rawPrice);
4775
- const decimalAdjustment = 10 ** (tokenInfo.decimals - this.USDC_DECIMALS);
4776
- const price = priceAfterX128 * decimalAdjustment;
4841
+ const decimalAdjustment = 10 ** (tokenInfo.decimals - quoteConfig.decimals);
4842
+ const priceInQuote = priceAfterX128 * decimalAdjustment;
4843
+ if (!quoteConfig.isUsdQuote) {
4844
+ if (!this.resolveUsdPrice) {
4845
+ throw new Error(
4846
+ `EkuboPricer: USD price resolver required for ${tokenInfo.symbol} via ${quoteConfig.symbol}`
4847
+ );
4848
+ }
4849
+ const quoteUsdPrice = await this.resolveUsdPrice(quoteConfig.symbol);
4850
+ return {
4851
+ price: priceInQuote * quoteUsdPrice,
4852
+ timestamp: /* @__PURE__ */ new Date()
4853
+ };
4854
+ }
4777
4855
  return {
4778
- price,
4856
+ price: priceInQuote,
4779
4857
  timestamp: /* @__PURE__ */ new Date()
4780
4858
  };
4781
4859
  }
@@ -4803,7 +4881,10 @@ var PricerFromApi = class extends PricerBase {
4803
4881
  ];
4804
4882
  this.apolloClient = createApolloClient(config);
4805
4883
  this.pragma = new Pragma(config, tokens2);
4806
- this.ekuboPricer = new EkuboPricer(config, tokens2);
4884
+ this.ekuboPricer = new EkuboPricer(config, tokens2, async (symbol) => {
4885
+ const priceInfo = await this.getPriceFromMyAPI(symbol);
4886
+ return priceInfo.price;
4887
+ });
4807
4888
  }
4808
4889
  async getPrice(tokenSymbol, blockNumber) {
4809
4890
  const tokenInfo = this.tokens.find((t) => t.symbol === tokenSymbol);
package/dist/index.d.ts CHANGED
@@ -122,6 +122,7 @@ interface TokenInfo {
122
122
  priceMethod?: PriceMethod;
123
123
  dontPrice?: boolean;
124
124
  indexingType: TokenIndexingType;
125
+ intermediateQuoteTokenSymbol?: string;
125
126
  }
126
127
  declare enum Network {
127
128
  mainnet = "mainnet",
@@ -496,6 +497,8 @@ declare class Pricer extends PricerBase {
496
497
  _getPriceAvnuApi(token: TokenInfo): Promise<number>;
497
498
  _getPriceCoinbase(token: TokenInfo): Promise<number>;
498
499
  _getPriceCoinMarketCap(token: TokenInfo): Promise<number>;
500
+ protected _resolveQuoteTokenUsdPrice(symbol: string): Promise<number>;
501
+ protected _convertDexQuoteToUsd(token: TokenInfo, quoteAmount: number): Promise<number>;
499
502
  _getAvnuPrice(token: TokenInfo, amountIn?: Web3Number, retry?: number): Promise<number>;
500
503
  _getPriceEkubo(token: TokenInfo, amountIn?: Web3Number, retry?: number): Promise<number>;
501
504
  }
@@ -3198,12 +3201,12 @@ declare class Midas {
3198
3201
  } | number>;
3199
3202
  }
3200
3203
 
3204
+ type UsdPriceResolver = (symbol: string) => Promise<number>;
3201
3205
  declare class EkuboPricer extends PricerBase {
3206
+ private readonly resolveUsdPrice?;
3202
3207
  EKUBO_PRICE_FETCHER_ADDRESS: string;
3203
3208
  readonly contract: Contract;
3204
- private readonly USDC_ADDRESS;
3205
- private readonly USDC_DECIMALS;
3206
- constructor(config: IConfig, tokens: TokenInfo[]);
3209
+ constructor(config: IConfig, tokens: TokenInfo[], resolveUsdPrice?: UsdPriceResolver | undefined);
3207
3210
  private div2Power128;
3208
3211
  getPrice(tokenAddr: string, blockIdentifier?: BlockIdentifier): Promise<PriceInfo>;
3209
3212
  }
@@ -3360,4 +3363,4 @@ declare class PasswordJsonCryptoUtil {
3360
3363
  decrypt(encryptedData: string, password: string): any;
3361
3364
  }
3362
3365
 
3363
- export { type APYInfo, APYType, AUDIT_URL, AUMTypes, AVNU_EXCHANGE, AVNU_EXCHANGE_FOR_LEGACY_USDC, AVNU_LEGACY_SANITIZER, AVNU_MIDDLEWARE, AVNU_QUOTE_URL, type AccessControlInfo, AccessControlType, type AccountInfo, type AdapterLeafType, type AllAccountsStore, type AmountInfo, type AmountsInfo, type ApproveCallParams, AuditStatus, AutoCompounderSTRK, AvnuAdapter, type AvnuAdapterConfig, type AvnuDepositParams, type AvnuSwapCallParams, type AvnuWithdrawParams, AvnuWrapper, BaseAdapter, type BaseAdapterConfig, BaseStrategy, BoostedxSTRKCarryStrategies, BoostedxSTRKCarryStrategy, type BoostedxSTRKCarryStrategySettings, type CLVaultStrategySettings, CommonAdapter, type CommonAdapterConfig, ContractAddr, DEFAULT_TROVES_STRATEGIES_API, type DecreaseLeverParams, Deployer, type DepositParams, type DualActionAmount, type DualTokenInfo, ERC20, EXTENDED_CONTRACT, EXTENDED_SANITIZER, type EkuboBounds, EkuboCLVault, EkuboCLVaultStrategies, type EkuboPoolKey, EkuboPricer, type EkuboQuote, EkuboQuoter, type EkuboRouteNode, type EkuboSplit, type FAQ, FactoryStrategyType, FatalError, type FeeBps, type FilterOption, type FlashloanCallParams, FlowChartColors, type GenerateCallFn, Global, HealthFactorMath, HyperLSTStrategies, type HyperLSTStrategySettings, type IConfig, type ICurator, type IInvestmentFlow, ILending, type ILendingMetadata, type ILendingPosition, type IProtocol, type IStrategyMetadata, type IncreaseLeverParams, Initializable, type InputModeFromAction, InstantWithdrawalVault, LSTAPRService, LSTPriceType, type LSTStats, type LeafAdapterFn, type LeafData, type LendingToken, type LoggerConfig, type LoggerLevel, type ManageCall, MarginType, Midas, MyNumber, type NetAPYDetails, type NetAPYSplit, Network, PRICE_ROUTER, type ParsedStarknetCall, PasswordJsonCryptoUtil, type PositionAPY, type PositionAmount, type PositionInfo, PositionTypeAvnuExtended, Pragma, type PriceInfo, type PriceMethod, Pricer, PricerAvnuApi, PricerBase, PricerFromApi, PricerLST, PricerRedis, Protocols, type RedemptionInfo, type RequiredFields, type RequiredKeys, type RequiredStoreConfig, type RiskFactor, RiskType, type Route, type RouteNode, SIMPLE_SANITIZER, SIMPLE_SANITIZER_V2, SIMPLE_SANITIZER_VESU_V1_DELEGATIONS, SVK_SIMPLE_SANITIZER, type SecurityMetadata, SenseiStrategies, SenseiVault, type SenseiVaultSettings, type SingleActionAmount, type SingleTokenInfo, type SourceCodeInfo, SourceCodeType, StandardMerkleTree, type StandardMerkleTreeData, StarknetCallParser, type StarknetCallParserOptions, Store, type StoreConfig, type StrategyAlert, type StrategyApyHistoryUIConfig, type StrategyCapabilities, type StrategyFilterMetadata, type StrategyInputMode, StrategyLiveStatus, type StrategyMetadata, type StrategyRegistryEntry, type StrategySettings, StrategyTag, StrategyType, type SupportedPosition, SvkTrovesAdapter, type SvkTrovesAdapterConfig, type Swap, type SwapInfo, type SwapPriceInfo, TRANSFER_SANITIZER, TelegramGroupNotif, TelegramNotif, type TokenAmount, TokenIndexingType, type TokenInfo, TokenMarketData, TokenTransferAdapter, type TokenTransferAdapterConfig, UNIVERSAL_ADAPTER_IDS, UNIVERSAL_MANAGE_IDS, UniversalLstMultiplierStrategy, type UniversalManageCall, UniversalStrategies, UniversalStrategy, type UniversalStrategySettings, UnwrapLabsCurator, type UserPositionCard, type UserPositionCardSubValueColor, type UserPositionCardsInput, type UserYoloInfo, VESU_SINGLETON, VESU_V2_MODIFY_POSITION_SANITIZER, type VaultPosition, VaultType, VesuAdapter, type VesuAdapterConfig, type VesuAmount, VesuAmountDenomination, VesuAmountType, type VesuDefiSpringRewardsCallParams, type VesuDepositParams, type VesuModifyDelegationCallParams, VesuModifyPositionAdapter, type VesuModifyPositionAdapterConfig, type VesuModifyPositionCallParams, type VesuModifyPositionDepositParams, type VesuModifyPositionWithdrawParams, VesuMultiplyAdapter, type VesuMultiplyAdapterConfig, type VesuMultiplyCallParams, VesuPoolMetadata, VesuPools, VesuRebalance, type VesuRebalanceSettings, VesuRebalanceStrategies, VesuSupplyOnlyAdapter, type VesuSupplyOnlyAdapterConfig, type VesuWithdrawParams, Web3Number, type WithdrawParams, YoLoVault, type YoloSettings, type YoloSpendingLevel, type YoloVaultSettings, type YoloVaultStatus, YoloVaultStrategies, ZkLend, _riskFactor, assert, buildStrategyRegistry, configureLogger, createBoostedXSTRKCarryStrategy, createEkuboCLStrategy, createHyperLSTStrategy, createSenseiStrategy, createStrategy, createUniversalStrategy, createVesuRebalanceStrategy, createYoloVaultStrategy, detectCapabilities, extensionMap, getAPIUsingHeadlessBrowser, getAllStrategyMetadata, getAllStrategyTags, getContractDetails, getDefaultStoreConfig, getFAQs, getFilterMetadata, getInvestmentSteps, getLiveStrategies, getMainnetConfig, getNoRiskTags, getRiskColor, getRiskExplaination, getStrategiesByType, getStrategyTagDesciption, getStrategyTypeFromMetadata, getTrovesEndpoint, getVesuSingletonAddress, highlightTextWithLinks, type i257, isDualTokenStrategy, logger, toAmountsInfo, toBigInt };
3366
+ export { type APYInfo, APYType, AUDIT_URL, AUMTypes, AVNU_EXCHANGE, AVNU_EXCHANGE_FOR_LEGACY_USDC, AVNU_LEGACY_SANITIZER, AVNU_MIDDLEWARE, AVNU_QUOTE_URL, type AccessControlInfo, AccessControlType, type AccountInfo, type AdapterLeafType, type AllAccountsStore, type AmountInfo, type AmountsInfo, type ApproveCallParams, AuditStatus, AutoCompounderSTRK, AvnuAdapter, type AvnuAdapterConfig, type AvnuDepositParams, type AvnuSwapCallParams, type AvnuWithdrawParams, AvnuWrapper, BaseAdapter, type BaseAdapterConfig, BaseStrategy, BoostedxSTRKCarryStrategies, BoostedxSTRKCarryStrategy, type BoostedxSTRKCarryStrategySettings, type CLVaultStrategySettings, CommonAdapter, type CommonAdapterConfig, ContractAddr, DEFAULT_TROVES_STRATEGIES_API, type DecreaseLeverParams, Deployer, type DepositParams, type DualActionAmount, type DualTokenInfo, ERC20, EXTENDED_CONTRACT, EXTENDED_SANITIZER, type EkuboBounds, EkuboCLVault, EkuboCLVaultStrategies, type EkuboPoolKey, EkuboPricer, type EkuboQuote, EkuboQuoter, type EkuboRouteNode, type EkuboSplit, type FAQ, FactoryStrategyType, FatalError, type FeeBps, type FilterOption, type FlashloanCallParams, FlowChartColors, type GenerateCallFn, Global, HealthFactorMath, HyperLSTStrategies, type HyperLSTStrategySettings, type IConfig, type ICurator, type IInvestmentFlow, ILending, type ILendingMetadata, type ILendingPosition, type IProtocol, type IStrategyMetadata, type IncreaseLeverParams, Initializable, type InputModeFromAction, InstantWithdrawalVault, LSTAPRService, LSTPriceType, type LSTStats, type LeafAdapterFn, type LeafData, type LendingToken, type LoggerConfig, type LoggerLevel, type ManageCall, MarginType, Midas, MyNumber, type NetAPYDetails, type NetAPYSplit, Network, PRICE_ROUTER, type ParsedStarknetCall, PasswordJsonCryptoUtil, type PositionAPY, type PositionAmount, type PositionInfo, PositionTypeAvnuExtended, Pragma, type PriceInfo, type PriceMethod, Pricer, PricerAvnuApi, PricerBase, PricerFromApi, PricerLST, PricerRedis, Protocols, type RedemptionInfo, type RequiredFields, type RequiredKeys, type RequiredStoreConfig, type RiskFactor, RiskType, type Route, type RouteNode, SIMPLE_SANITIZER, SIMPLE_SANITIZER_V2, SIMPLE_SANITIZER_VESU_V1_DELEGATIONS, SVK_SIMPLE_SANITIZER, type SecurityMetadata, SenseiStrategies, SenseiVault, type SenseiVaultSettings, type SingleActionAmount, type SingleTokenInfo, type SourceCodeInfo, SourceCodeType, StandardMerkleTree, type StandardMerkleTreeData, StarknetCallParser, type StarknetCallParserOptions, Store, type StoreConfig, type StrategyAlert, type StrategyApyHistoryUIConfig, type StrategyCapabilities, type StrategyFilterMetadata, type StrategyInputMode, StrategyLiveStatus, type StrategyMetadata, type StrategyRegistryEntry, type StrategySettings, StrategyTag, StrategyType, type SupportedPosition, SvkTrovesAdapter, type SvkTrovesAdapterConfig, type Swap, type SwapInfo, type SwapPriceInfo, TRANSFER_SANITIZER, TelegramGroupNotif, TelegramNotif, type TokenAmount, TokenIndexingType, type TokenInfo, TokenMarketData, TokenTransferAdapter, type TokenTransferAdapterConfig, UNIVERSAL_ADAPTER_IDS, UNIVERSAL_MANAGE_IDS, UniversalLstMultiplierStrategy, type UniversalManageCall, UniversalStrategies, UniversalStrategy, type UniversalStrategySettings, UnwrapLabsCurator, type UsdPriceResolver, type UserPositionCard, type UserPositionCardSubValueColor, type UserPositionCardsInput, type UserYoloInfo, VESU_SINGLETON, VESU_V2_MODIFY_POSITION_SANITIZER, type VaultPosition, VaultType, VesuAdapter, type VesuAdapterConfig, type VesuAmount, VesuAmountDenomination, VesuAmountType, type VesuDefiSpringRewardsCallParams, type VesuDepositParams, type VesuModifyDelegationCallParams, VesuModifyPositionAdapter, type VesuModifyPositionAdapterConfig, type VesuModifyPositionCallParams, type VesuModifyPositionDepositParams, type VesuModifyPositionWithdrawParams, VesuMultiplyAdapter, type VesuMultiplyAdapterConfig, type VesuMultiplyCallParams, VesuPoolMetadata, VesuPools, VesuRebalance, type VesuRebalanceSettings, VesuRebalanceStrategies, VesuSupplyOnlyAdapter, type VesuSupplyOnlyAdapterConfig, type VesuWithdrawParams, Web3Number, type WithdrawParams, YoLoVault, type YoloSettings, type YoloSpendingLevel, type YoloVaultSettings, type YoloVaultStatus, YoloVaultStrategies, ZkLend, _riskFactor, assert, buildStrategyRegistry, configureLogger, createBoostedXSTRKCarryStrategy, createEkuboCLStrategy, createHyperLSTStrategy, createSenseiStrategy, createStrategy, createUniversalStrategy, createVesuRebalanceStrategy, createYoloVaultStrategy, detectCapabilities, extensionMap, getAPIUsingHeadlessBrowser, getAllStrategyMetadata, getAllStrategyTags, getContractDetails, getDefaultStoreConfig, getFAQs, getFilterMetadata, getInvestmentSteps, getLiveStrategies, getMainnetConfig, getNoRiskTags, getRiskColor, getRiskExplaination, getStrategiesByType, getStrategyTagDesciption, getStrategyTypeFromMetadata, getTrovesEndpoint, getVesuSingletonAddress, highlightTextWithLinks, type i257, isDualTokenStrategy, logger, toAmountsInfo, toBigInt };