@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.
- package/dist/index.browser.global.js +118 -37
- package/dist/index.browser.mjs +118 -37
- package/dist/index.d.ts +7 -4
- package/dist/index.js +118 -37
- package/dist/index.mjs +118 -37
- package/package.json +1 -1
- package/src/global.ts +2 -1
- package/src/interfaces/common.tsx +1 -0
- package/src/modules/ekubo-pricer.ts +45 -26
- package/src/modules/pricer-from-api.ts +4 -1
- package/src/modules/pricer-quote-utils.ts +54 -0
- package/src/modules/pricer.ts +67 -30
|
@@ -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 =
|
|
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
|
-
|
|
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
|
|
80359
|
-
|
|
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
|
|
80362
|
-
|
|
80363
|
-
|
|
80364
|
-
|
|
80365
|
-
|
|
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
|
-
|
|
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
|
|
80378
|
-
|
|
80379
|
-
|
|
80380
|
-
|
|
80381
|
-
|
|
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
|
-
|
|
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
|
-
[
|
|
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 -
|
|
93311
|
-
const
|
|
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);
|
package/dist/index.browser.mjs
CHANGED
|
@@ -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 =
|
|
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
|
-
|
|
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
|
|
4144
|
-
|
|
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
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
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
|
-
|
|
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
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
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
|
-
|
|
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
|
-
[
|
|
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 -
|
|
4776
|
-
const
|
|
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
|
-
|
|
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 };
|