@strkfarm/sdk 1.1.25 → 1.1.27

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.
@@ -2279,6 +2279,108 @@ var PricerLST = class extends Pricer {
2279
2279
  }
2280
2280
  };
2281
2281
 
2282
+ // src/modules/lst-apr.ts
2283
+ var LSTAPRService = class {
2284
+ // 5 minutes
2285
+ /**
2286
+ * Fetches LST stats from Endur API with caching
2287
+ * @returns Promise<LSTStats[]> Array of LST statistics
2288
+ */
2289
+ static async getLSTStats() {
2290
+ const now = Date.now();
2291
+ if (this.cache && now - this.cacheTimestamp < this.CACHE_DURATION) {
2292
+ logger.verbose(`LSTAPRService: Returning cached LST stats`);
2293
+ return this.cache;
2294
+ }
2295
+ try {
2296
+ logger.verbose(`LSTAPRService: Fetching LST stats from Endur API`);
2297
+ const response = await fetch(this.ENDUR_API_URL);
2298
+ if (!response.ok) {
2299
+ throw new Error(`Failed to fetch LST stats: ${response.status} ${response.statusText}`);
2300
+ }
2301
+ const data = await response.json();
2302
+ if (!Array.isArray(data)) {
2303
+ throw new Error("Invalid response format: expected array");
2304
+ }
2305
+ this.cache = data;
2306
+ this.cacheTimestamp = now;
2307
+ logger.verbose(`LSTAPRService: Successfully fetched ${data.length} LST stats`);
2308
+ return data;
2309
+ } catch (error) {
2310
+ logger.error(`LSTAPRService: Error fetching LST stats: ${error}`);
2311
+ if (this.cache) {
2312
+ logger.warn(`LSTAPRService: Returning stale cached data due to API error`);
2313
+ return this.cache;
2314
+ }
2315
+ throw error;
2316
+ }
2317
+ }
2318
+ /**
2319
+ * Gets LST APR for a specific asset address
2320
+ * @param assetAddress - The contract address of the underlying asset
2321
+ * @returns Promise<number> The LST APR (not divided by 1e18)
2322
+ */
2323
+ static async getLSTAPR(assetAddress) {
2324
+ const stats = await this.getLSTStats();
2325
+ const lstStat = stats.find(
2326
+ (stat) => ContractAddr.eqString(stat.assetAddress, assetAddress.address)
2327
+ );
2328
+ if (!lstStat) {
2329
+ logger.warn(`LSTAPRService: No LST stats found for asset address ${assetAddress.address}`);
2330
+ return 0;
2331
+ }
2332
+ logger.verbose(`LSTAPRService: Found LST APR for ${lstStat.asset}: ${lstStat.apy} (${lstStat.apyInPercentage})`);
2333
+ return lstStat.apy;
2334
+ }
2335
+ /**
2336
+ * Gets LST APR for multiple asset addresses
2337
+ * @param assetAddresses - Array of contract addresses
2338
+ * @returns Promise<Map<string, number>> Map of asset address to LST APR
2339
+ */
2340
+ static async getLSTAPRs(assetAddresses) {
2341
+ const stats = await this.getLSTStats();
2342
+ const result = /* @__PURE__ */ new Map();
2343
+ for (const assetAddress of assetAddresses) {
2344
+ const lstStat = stats.find(
2345
+ (stat) => ContractAddr.eqString(stat.assetAddress, assetAddress.address)
2346
+ );
2347
+ if (lstStat) {
2348
+ result.set(assetAddress.address, lstStat.apy);
2349
+ logger.verbose(`LSTAPRService: Found LST APR for ${lstStat.asset}: ${lstStat.apy}`);
2350
+ } else {
2351
+ result.set(assetAddress.address, 0);
2352
+ logger.warn(`LSTAPRService: No LST stats found for asset address ${assetAddress.address}`);
2353
+ }
2354
+ }
2355
+ return result;
2356
+ }
2357
+ /**
2358
+ * Gets all available LST assets and their APRs
2359
+ * @returns Promise<Map<string, LSTStats>> Map of asset address to LST stats
2360
+ */
2361
+ static async getAllLSTStats() {
2362
+ const stats = await this.getLSTStats();
2363
+ const result = /* @__PURE__ */ new Map();
2364
+ for (const stat of stats) {
2365
+ console.log("stat", stat);
2366
+ result.set(stat.assetAddress, stat);
2367
+ }
2368
+ return result;
2369
+ }
2370
+ /**
2371
+ * Clears the cache (useful for testing or forcing refresh)
2372
+ */
2373
+ static clearCache() {
2374
+ this.cache = null;
2375
+ this.cacheTimestamp = 0;
2376
+ logger.verbose(`LSTAPRService: Cache cleared`);
2377
+ }
2378
+ };
2379
+ LSTAPRService.ENDUR_API_URL = "https://app.endur.fi/api/lst/stats";
2380
+ LSTAPRService.cache = null;
2381
+ LSTAPRService.cacheTimestamp = 0;
2382
+ LSTAPRService.CACHE_DURATION = 5 * 60 * 1e3;
2383
+
2282
2384
  // src/interfaces/common.tsx
2283
2385
  import { BlockTag, RpcProvider as RpcProvider2 } from "starknet";
2284
2386
  import { Fragment, jsx } from "react/jsx-runtime";
@@ -26705,12 +26807,21 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
26705
26807
  logger.verbose(`${this.metadata.name}::netAPY: positions: ${JSON.stringify(positions)}`);
26706
26808
  const baseAPYs = [];
26707
26809
  const rewardAPYs = [];
26810
+ const underlyingAddresses = vesuAdapters.map((adapter) => adapter.config.debt.address);
26811
+ let lstAPRs;
26812
+ try {
26813
+ lstAPRs = await LSTAPRService.getLSTAPRs(underlyingAddresses);
26814
+ } catch (error) {
26815
+ logger.warn(`${this.metadata.name}::netAPY: Failed to fetch LST APRs from Endur API, using fallback: ${error}`);
26816
+ lstAPRs = /* @__PURE__ */ new Map();
26817
+ }
26708
26818
  for (const [index, pool] of pools.entries()) {
26709
26819
  const vesuAdapter = vesuAdapters[index];
26710
26820
  const collateralAsset = pool.assets.find((a) => a.symbol.toLowerCase() === vesuAdapter.config.collateral.symbol.toLowerCase())?.stats;
26711
26821
  const debtAsset = pool.assets.find((a) => a.symbol.toLowerCase() === vesuAdapter.config.debt.symbol.toLowerCase())?.stats;
26712
26822
  const supplyApy = Number(collateralAsset.supplyApy.value || 0) / 1e18;
26713
- const lstAPY = Number(collateralAsset.lstApr?.value || 0) / 1e18;
26823
+ const lstAPY = lstAPRs.get(vesuAdapter.config.debt.address.address) || 0;
26824
+ logger.verbose(`${this.metadata.name}::netAPY: ${vesuAdapter.config.collateral.symbol} LST APR from Endur: ${lstAPY}`);
26714
26825
  baseAPYs.push(...[supplyApy + lstAPY, Number(debtAsset.borrowApr.value) / 1e18]);
26715
26826
  rewardAPYs.push(...[Number(collateralAsset.defiSpringSupplyApr?.value || "0") / 1e18, 0]);
26716
26827
  }
@@ -26934,6 +27045,18 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
26934
27045
  getTag() {
26935
27046
  return `${_UniversalStrategy.name}:${this.metadata.name}`;
26936
27047
  }
27048
+ /**
27049
+ * Gets LST APR for the strategy's underlying asset from Endur API
27050
+ * @returns Promise<number> The LST APR (not divided by 1e18)
27051
+ */
27052
+ async getLSTAPR() {
27053
+ try {
27054
+ return await LSTAPRService.getLSTAPR(this.asset().address);
27055
+ } catch (error) {
27056
+ logger.warn(`${this.getTag()}: Failed to get LST APR: ${error}`);
27057
+ return 0;
27058
+ }
27059
+ }
26937
27060
  async getVesuHealthFactors() {
26938
27061
  return await Promise.all(this.getVesuAdapters().map((v) => v.getHealthFactor()));
26939
27062
  }
@@ -27982,6 +28105,7 @@ export {
27982
28105
  HyperLSTStrategies,
27983
28106
  ILending,
27984
28107
  Initializable,
28108
+ LSTAPRService,
27985
28109
  MarginType,
27986
28110
  Network,
27987
28111
  PRICE_ROUTER,
package/dist/index.d.ts CHANGED
@@ -1225,6 +1225,11 @@ declare class UniversalStrategy<S extends UniversalStrategySettings> extends Bas
1225
1225
  debtAmount: Web3Number;
1226
1226
  }): UniversalManageCall[];
1227
1227
  getTag(): string;
1228
+ /**
1229
+ * Gets LST APR for the strategy's underlying asset from Endur API
1230
+ * @returns Promise<number> The LST APR (not divided by 1e18)
1231
+ */
1232
+ getLSTAPR(): Promise<number>;
1228
1233
  getVesuHealthFactors(): Promise<number[]>;
1229
1234
  computeRebalanceConditionAndReturnCalls(): Promise<Call[]>;
1230
1235
  private getNewHealthFactor;
@@ -1385,6 +1390,50 @@ declare class PricerLST extends Pricer {
1385
1390
  _getPriceEkubo(token: TokenInfo, amountIn?: Web3Number, retry?: number): Promise<number>;
1386
1391
  }
1387
1392
 
1393
+ interface LSTStats {
1394
+ asset: string;
1395
+ assetAddress: string;
1396
+ lstAddress: string;
1397
+ tvlUsd: number;
1398
+ tvlAsset: number;
1399
+ apy: number;
1400
+ apyInPercentage: string;
1401
+ exchangeRate: number;
1402
+ preciseExchangeRate: string;
1403
+ }
1404
+ declare class LSTAPRService {
1405
+ private static readonly ENDUR_API_URL;
1406
+ private static cache;
1407
+ private static cacheTimestamp;
1408
+ private static readonly CACHE_DURATION;
1409
+ /**
1410
+ * Fetches LST stats from Endur API with caching
1411
+ * @returns Promise<LSTStats[]> Array of LST statistics
1412
+ */
1413
+ static getLSTStats(): Promise<LSTStats[]>;
1414
+ /**
1415
+ * Gets LST APR for a specific asset address
1416
+ * @param assetAddress - The contract address of the underlying asset
1417
+ * @returns Promise<number> The LST APR (not divided by 1e18)
1418
+ */
1419
+ static getLSTAPR(assetAddress: ContractAddr): Promise<number>;
1420
+ /**
1421
+ * Gets LST APR for multiple asset addresses
1422
+ * @param assetAddresses - Array of contract addresses
1423
+ * @returns Promise<Map<string, number>> Map of asset address to LST APR
1424
+ */
1425
+ static getLSTAPRs(assetAddresses: ContractAddr[]): Promise<Map<string, number>>;
1426
+ /**
1427
+ * Gets all available LST assets and their APRs
1428
+ * @returns Promise<Map<string, LSTStats>> Map of asset address to LST stats
1429
+ */
1430
+ static getAllLSTStats(): Promise<Map<string, LSTStats>>;
1431
+ /**
1432
+ * Clears the cache (useful for testing or forcing refresh)
1433
+ */
1434
+ static clearCache(): void;
1435
+ }
1436
+
1388
1437
  declare class TelegramNotif {
1389
1438
  private subscribers;
1390
1439
  readonly bot: TelegramBot;
@@ -1535,4 +1584,4 @@ declare class PasswordJsonCryptoUtil {
1535
1584
  decrypt(encryptedData: string, password: string): any;
1536
1585
  }
1537
1586
 
1538
- export { AUMTypes, AVNU_MIDDLEWARE, type AccountInfo, type AdapterLeafType, type AllAccountsStore, type ApproveCallParams, AutoCompounderSTRK, type AvnuSwapCallParams, AvnuWrapper, BaseAdapter, BaseStrategy, type CLVaultStrategySettings, CommonAdapter, type CommonAdapterConfig, ContractAddr, type DecreaseLeverParams, Deployer, type DualActionAmount, type DualTokenInfo, ERC20, type EkuboBounds, EkuboCLVault, EkuboCLVaultStrategies, type EkuboPoolKey, type EkuboQuote, EkuboQuoter, type EkuboRouteNode, type EkuboSplit, type FAQ, FatalError, type FlashloanCallParams, FlowChartColors, type GenerateCallFn, Global, HyperLSTStrategies, type IConfig, type IInvestmentFlow, ILending, type ILendingMetadata, type ILendingPosition, type IProtocol, type IStrategyMetadata, type IncreaseLeverParams, Initializable, type LeafAdapterFn, type LeafData, type LendingToken, type ManageCall, MarginType, Network, PRICE_ROUTER, PasswordJsonCryptoUtil, Pragma, type PriceInfo, Pricer, PricerFromApi, PricerLST, PricerRedis, Protocols, type RequiredFields, type RequiredKeys, type RequiredStoreConfig, type RiskFactor, RiskType, type Route, type RouteNode, SIMPLE_SANITIZER, SIMPLE_SANITIZER_V2, SIMPLE_SANITIZER_VESU_V1_DELEGATIONS, SenseiStrategies, SenseiVault, type SenseiVaultSettings, type SingleActionAmount, type SingleTokenInfo, StandardMerkleTree, type StandardMerkleTreeData, Store, type StoreConfig, type Swap, type SwapInfo, TelegramGroupNotif, TelegramNotif, type TokenAmount, type TokenInfo, UNIVERSAL_ADAPTERS, UNIVERSAL_MANAGE_IDS, UniversalLstMultiplierStrategy, type UniversalManageCall, UniversalStrategies, UniversalStrategy, type UniversalStrategySettings, VESU_SINGLETON, type VaultPosition, VesuAdapter, type VesuAdapterConfig, type VesuAmount, VesuAmountDenomination, VesuAmountType, type VesuDefiSpringRewardsCallParams, type VesuModifyDelegationCallParams, type VesuModifyPositionCallParams, type VesuMultiplyCallParams, VesuPools, VesuRebalance, type VesuRebalanceSettings, VesuRebalanceStrategies, Web3Number, ZkLend, assert, getAPIUsingHeadlessBrowser, getContractDetails, getDefaultStoreConfig, getMainnetConfig, getNoRiskTags, getRiskColor, getRiskExplaination, getTrovesEndpoint, getVesuSingletonAddress, highlightTextWithLinks, type i257, logger, toBigInt };
1587
+ export { AUMTypes, AVNU_MIDDLEWARE, type AccountInfo, type AdapterLeafType, type AllAccountsStore, type ApproveCallParams, AutoCompounderSTRK, type AvnuSwapCallParams, AvnuWrapper, BaseAdapter, BaseStrategy, type CLVaultStrategySettings, CommonAdapter, type CommonAdapterConfig, ContractAddr, type DecreaseLeverParams, Deployer, type DualActionAmount, type DualTokenInfo, ERC20, type EkuboBounds, EkuboCLVault, EkuboCLVaultStrategies, type EkuboPoolKey, type EkuboQuote, EkuboQuoter, type EkuboRouteNode, type EkuboSplit, type FAQ, FatalError, type FlashloanCallParams, FlowChartColors, type GenerateCallFn, Global, HyperLSTStrategies, type IConfig, type IInvestmentFlow, ILending, type ILendingMetadata, type ILendingPosition, type IProtocol, type IStrategyMetadata, type IncreaseLeverParams, Initializable, LSTAPRService, type LSTStats, type LeafAdapterFn, type LeafData, type LendingToken, type ManageCall, MarginType, Network, PRICE_ROUTER, PasswordJsonCryptoUtil, Pragma, type PriceInfo, Pricer, PricerFromApi, PricerLST, PricerRedis, Protocols, type RequiredFields, type RequiredKeys, type RequiredStoreConfig, type RiskFactor, RiskType, type Route, type RouteNode, SIMPLE_SANITIZER, SIMPLE_SANITIZER_V2, SIMPLE_SANITIZER_VESU_V1_DELEGATIONS, SenseiStrategies, SenseiVault, type SenseiVaultSettings, type SingleActionAmount, type SingleTokenInfo, StandardMerkleTree, type StandardMerkleTreeData, Store, type StoreConfig, type Swap, type SwapInfo, TelegramGroupNotif, TelegramNotif, type TokenAmount, type TokenInfo, UNIVERSAL_ADAPTERS, UNIVERSAL_MANAGE_IDS, UniversalLstMultiplierStrategy, type UniversalManageCall, UniversalStrategies, UniversalStrategy, type UniversalStrategySettings, VESU_SINGLETON, type VaultPosition, VesuAdapter, type VesuAdapterConfig, type VesuAmount, VesuAmountDenomination, VesuAmountType, type VesuDefiSpringRewardsCallParams, type VesuModifyDelegationCallParams, type VesuModifyPositionCallParams, type VesuMultiplyCallParams, VesuPools, VesuRebalance, type VesuRebalanceSettings, VesuRebalanceStrategies, Web3Number, ZkLend, assert, getAPIUsingHeadlessBrowser, getContractDetails, getDefaultStoreConfig, getMainnetConfig, getNoRiskTags, getRiskColor, getRiskExplaination, getTrovesEndpoint, getVesuSingletonAddress, highlightTextWithLinks, type i257, logger, toBigInt };
package/dist/index.js CHANGED
@@ -49,6 +49,7 @@ __export(index_exports, {
49
49
  HyperLSTStrategies: () => HyperLSTStrategies,
50
50
  ILending: () => ILending,
51
51
  Initializable: () => Initializable,
52
+ LSTAPRService: () => LSTAPRService,
52
53
  MarginType: () => MarginType,
53
54
  Network: () => Network,
54
55
  PRICE_ROUTER: () => PRICE_ROUTER,
@@ -26801,12 +26802,21 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
26801
26802
  logger.verbose(`${this.metadata.name}::netAPY: positions: ${JSON.stringify(positions)}`);
26802
26803
  const baseAPYs = [];
26803
26804
  const rewardAPYs = [];
26805
+ const underlyingAddresses = vesuAdapters.map((adapter) => adapter.config.debt.address);
26806
+ let lstAPRs;
26807
+ try {
26808
+ lstAPRs = await LSTAPRService.getLSTAPRs(underlyingAddresses);
26809
+ } catch (error) {
26810
+ logger.warn(`${this.metadata.name}::netAPY: Failed to fetch LST APRs from Endur API, using fallback: ${error}`);
26811
+ lstAPRs = /* @__PURE__ */ new Map();
26812
+ }
26804
26813
  for (const [index, pool] of pools.entries()) {
26805
26814
  const vesuAdapter = vesuAdapters[index];
26806
26815
  const collateralAsset = pool.assets.find((a) => a.symbol.toLowerCase() === vesuAdapter.config.collateral.symbol.toLowerCase())?.stats;
26807
26816
  const debtAsset = pool.assets.find((a) => a.symbol.toLowerCase() === vesuAdapter.config.debt.symbol.toLowerCase())?.stats;
26808
26817
  const supplyApy = Number(collateralAsset.supplyApy.value || 0) / 1e18;
26809
- const lstAPY = Number(collateralAsset.lstApr?.value || 0) / 1e18;
26818
+ const lstAPY = lstAPRs.get(vesuAdapter.config.debt.address.address) || 0;
26819
+ logger.verbose(`${this.metadata.name}::netAPY: ${vesuAdapter.config.collateral.symbol} LST APR from Endur: ${lstAPY}`);
26810
26820
  baseAPYs.push(...[supplyApy + lstAPY, Number(debtAsset.borrowApr.value) / 1e18]);
26811
26821
  rewardAPYs.push(...[Number(collateralAsset.defiSpringSupplyApr?.value || "0") / 1e18, 0]);
26812
26822
  }
@@ -27030,6 +27040,18 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
27030
27040
  getTag() {
27031
27041
  return `${_UniversalStrategy.name}:${this.metadata.name}`;
27032
27042
  }
27043
+ /**
27044
+ * Gets LST APR for the strategy's underlying asset from Endur API
27045
+ * @returns Promise<number> The LST APR (not divided by 1e18)
27046
+ */
27047
+ async getLSTAPR() {
27048
+ try {
27049
+ return await LSTAPRService.getLSTAPR(this.asset().address);
27050
+ } catch (error) {
27051
+ logger.warn(`${this.getTag()}: Failed to get LST APR: ${error}`);
27052
+ return 0;
27053
+ }
27054
+ }
27033
27055
  async getVesuHealthFactors() {
27034
27056
  return await Promise.all(this.getVesuAdapters().map((v) => v.getHealthFactor()));
27035
27057
  }
@@ -28110,6 +28132,108 @@ var PricerLST2 = class extends Pricer {
28110
28132
  }
28111
28133
  };
28112
28134
 
28135
+ // src/modules/lst-apr.ts
28136
+ var LSTAPRService = class {
28137
+ // 5 minutes
28138
+ /**
28139
+ * Fetches LST stats from Endur API with caching
28140
+ * @returns Promise<LSTStats[]> Array of LST statistics
28141
+ */
28142
+ static async getLSTStats() {
28143
+ const now = Date.now();
28144
+ if (this.cache && now - this.cacheTimestamp < this.CACHE_DURATION) {
28145
+ logger.verbose(`LSTAPRService: Returning cached LST stats`);
28146
+ return this.cache;
28147
+ }
28148
+ try {
28149
+ logger.verbose(`LSTAPRService: Fetching LST stats from Endur API`);
28150
+ const response = await fetch(this.ENDUR_API_URL);
28151
+ if (!response.ok) {
28152
+ throw new Error(`Failed to fetch LST stats: ${response.status} ${response.statusText}`);
28153
+ }
28154
+ const data = await response.json();
28155
+ if (!Array.isArray(data)) {
28156
+ throw new Error("Invalid response format: expected array");
28157
+ }
28158
+ this.cache = data;
28159
+ this.cacheTimestamp = now;
28160
+ logger.verbose(`LSTAPRService: Successfully fetched ${data.length} LST stats`);
28161
+ return data;
28162
+ } catch (error) {
28163
+ logger.error(`LSTAPRService: Error fetching LST stats: ${error}`);
28164
+ if (this.cache) {
28165
+ logger.warn(`LSTAPRService: Returning stale cached data due to API error`);
28166
+ return this.cache;
28167
+ }
28168
+ throw error;
28169
+ }
28170
+ }
28171
+ /**
28172
+ * Gets LST APR for a specific asset address
28173
+ * @param assetAddress - The contract address of the underlying asset
28174
+ * @returns Promise<number> The LST APR (not divided by 1e18)
28175
+ */
28176
+ static async getLSTAPR(assetAddress) {
28177
+ const stats = await this.getLSTStats();
28178
+ const lstStat = stats.find(
28179
+ (stat) => ContractAddr.eqString(stat.assetAddress, assetAddress.address)
28180
+ );
28181
+ if (!lstStat) {
28182
+ logger.warn(`LSTAPRService: No LST stats found for asset address ${assetAddress.address}`);
28183
+ return 0;
28184
+ }
28185
+ logger.verbose(`LSTAPRService: Found LST APR for ${lstStat.asset}: ${lstStat.apy} (${lstStat.apyInPercentage})`);
28186
+ return lstStat.apy;
28187
+ }
28188
+ /**
28189
+ * Gets LST APR for multiple asset addresses
28190
+ * @param assetAddresses - Array of contract addresses
28191
+ * @returns Promise<Map<string, number>> Map of asset address to LST APR
28192
+ */
28193
+ static async getLSTAPRs(assetAddresses) {
28194
+ const stats = await this.getLSTStats();
28195
+ const result = /* @__PURE__ */ new Map();
28196
+ for (const assetAddress of assetAddresses) {
28197
+ const lstStat = stats.find(
28198
+ (stat) => ContractAddr.eqString(stat.assetAddress, assetAddress.address)
28199
+ );
28200
+ if (lstStat) {
28201
+ result.set(assetAddress.address, lstStat.apy);
28202
+ logger.verbose(`LSTAPRService: Found LST APR for ${lstStat.asset}: ${lstStat.apy}`);
28203
+ } else {
28204
+ result.set(assetAddress.address, 0);
28205
+ logger.warn(`LSTAPRService: No LST stats found for asset address ${assetAddress.address}`);
28206
+ }
28207
+ }
28208
+ return result;
28209
+ }
28210
+ /**
28211
+ * Gets all available LST assets and their APRs
28212
+ * @returns Promise<Map<string, LSTStats>> Map of asset address to LST stats
28213
+ */
28214
+ static async getAllLSTStats() {
28215
+ const stats = await this.getLSTStats();
28216
+ const result = /* @__PURE__ */ new Map();
28217
+ for (const stat of stats) {
28218
+ console.log("stat", stat);
28219
+ result.set(stat.assetAddress, stat);
28220
+ }
28221
+ return result;
28222
+ }
28223
+ /**
28224
+ * Clears the cache (useful for testing or forcing refresh)
28225
+ */
28226
+ static clearCache() {
28227
+ this.cache = null;
28228
+ this.cacheTimestamp = 0;
28229
+ logger.verbose(`LSTAPRService: Cache cleared`);
28230
+ }
28231
+ };
28232
+ LSTAPRService.ENDUR_API_URL = "https://app.endur.fi/api/lst/stats";
28233
+ LSTAPRService.cache = null;
28234
+ LSTAPRService.cacheTimestamp = 0;
28235
+ LSTAPRService.CACHE_DURATION = 5 * 60 * 1e3;
28236
+
28113
28237
  // src/notifs/telegram.ts
28114
28238
  var import_node_telegram_bot_api = __toESM(require("node-telegram-bot-api"));
28115
28239
  var TelegramNotif = class {
@@ -28638,6 +28762,7 @@ var deployer_default = Deployer;
28638
28762
  HyperLSTStrategies,
28639
28763
  ILending,
28640
28764
  Initializable,
28765
+ LSTAPRService,
28641
28766
  MarginType,
28642
28767
  Network,
28643
28768
  PRICE_ROUTER,
package/dist/index.mjs CHANGED
@@ -26704,12 +26704,21 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
26704
26704
  logger.verbose(`${this.metadata.name}::netAPY: positions: ${JSON.stringify(positions)}`);
26705
26705
  const baseAPYs = [];
26706
26706
  const rewardAPYs = [];
26707
+ const underlyingAddresses = vesuAdapters.map((adapter) => adapter.config.debt.address);
26708
+ let lstAPRs;
26709
+ try {
26710
+ lstAPRs = await LSTAPRService.getLSTAPRs(underlyingAddresses);
26711
+ } catch (error) {
26712
+ logger.warn(`${this.metadata.name}::netAPY: Failed to fetch LST APRs from Endur API, using fallback: ${error}`);
26713
+ lstAPRs = /* @__PURE__ */ new Map();
26714
+ }
26707
26715
  for (const [index, pool] of pools.entries()) {
26708
26716
  const vesuAdapter = vesuAdapters[index];
26709
26717
  const collateralAsset = pool.assets.find((a) => a.symbol.toLowerCase() === vesuAdapter.config.collateral.symbol.toLowerCase())?.stats;
26710
26718
  const debtAsset = pool.assets.find((a) => a.symbol.toLowerCase() === vesuAdapter.config.debt.symbol.toLowerCase())?.stats;
26711
26719
  const supplyApy = Number(collateralAsset.supplyApy.value || 0) / 1e18;
26712
- const lstAPY = Number(collateralAsset.lstApr?.value || 0) / 1e18;
26720
+ const lstAPY = lstAPRs.get(vesuAdapter.config.debt.address.address) || 0;
26721
+ logger.verbose(`${this.metadata.name}::netAPY: ${vesuAdapter.config.collateral.symbol} LST APR from Endur: ${lstAPY}`);
26713
26722
  baseAPYs.push(...[supplyApy + lstAPY, Number(debtAsset.borrowApr.value) / 1e18]);
26714
26723
  rewardAPYs.push(...[Number(collateralAsset.defiSpringSupplyApr?.value || "0") / 1e18, 0]);
26715
26724
  }
@@ -26933,6 +26942,18 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
26933
26942
  getTag() {
26934
26943
  return `${_UniversalStrategy.name}:${this.metadata.name}`;
26935
26944
  }
26945
+ /**
26946
+ * Gets LST APR for the strategy's underlying asset from Endur API
26947
+ * @returns Promise<number> The LST APR (not divided by 1e18)
26948
+ */
26949
+ async getLSTAPR() {
26950
+ try {
26951
+ return await LSTAPRService.getLSTAPR(this.asset().address);
26952
+ } catch (error) {
26953
+ logger.warn(`${this.getTag()}: Failed to get LST APR: ${error}`);
26954
+ return 0;
26955
+ }
26956
+ }
26936
26957
  async getVesuHealthFactors() {
26937
26958
  return await Promise.all(this.getVesuAdapters().map((v) => v.getHealthFactor()));
26938
26959
  }
@@ -28013,6 +28034,108 @@ var PricerLST2 = class extends Pricer {
28013
28034
  }
28014
28035
  };
28015
28036
 
28037
+ // src/modules/lst-apr.ts
28038
+ var LSTAPRService = class {
28039
+ // 5 minutes
28040
+ /**
28041
+ * Fetches LST stats from Endur API with caching
28042
+ * @returns Promise<LSTStats[]> Array of LST statistics
28043
+ */
28044
+ static async getLSTStats() {
28045
+ const now = Date.now();
28046
+ if (this.cache && now - this.cacheTimestamp < this.CACHE_DURATION) {
28047
+ logger.verbose(`LSTAPRService: Returning cached LST stats`);
28048
+ return this.cache;
28049
+ }
28050
+ try {
28051
+ logger.verbose(`LSTAPRService: Fetching LST stats from Endur API`);
28052
+ const response = await fetch(this.ENDUR_API_URL);
28053
+ if (!response.ok) {
28054
+ throw new Error(`Failed to fetch LST stats: ${response.status} ${response.statusText}`);
28055
+ }
28056
+ const data = await response.json();
28057
+ if (!Array.isArray(data)) {
28058
+ throw new Error("Invalid response format: expected array");
28059
+ }
28060
+ this.cache = data;
28061
+ this.cacheTimestamp = now;
28062
+ logger.verbose(`LSTAPRService: Successfully fetched ${data.length} LST stats`);
28063
+ return data;
28064
+ } catch (error) {
28065
+ logger.error(`LSTAPRService: Error fetching LST stats: ${error}`);
28066
+ if (this.cache) {
28067
+ logger.warn(`LSTAPRService: Returning stale cached data due to API error`);
28068
+ return this.cache;
28069
+ }
28070
+ throw error;
28071
+ }
28072
+ }
28073
+ /**
28074
+ * Gets LST APR for a specific asset address
28075
+ * @param assetAddress - The contract address of the underlying asset
28076
+ * @returns Promise<number> The LST APR (not divided by 1e18)
28077
+ */
28078
+ static async getLSTAPR(assetAddress) {
28079
+ const stats = await this.getLSTStats();
28080
+ const lstStat = stats.find(
28081
+ (stat) => ContractAddr.eqString(stat.assetAddress, assetAddress.address)
28082
+ );
28083
+ if (!lstStat) {
28084
+ logger.warn(`LSTAPRService: No LST stats found for asset address ${assetAddress.address}`);
28085
+ return 0;
28086
+ }
28087
+ logger.verbose(`LSTAPRService: Found LST APR for ${lstStat.asset}: ${lstStat.apy} (${lstStat.apyInPercentage})`);
28088
+ return lstStat.apy;
28089
+ }
28090
+ /**
28091
+ * Gets LST APR for multiple asset addresses
28092
+ * @param assetAddresses - Array of contract addresses
28093
+ * @returns Promise<Map<string, number>> Map of asset address to LST APR
28094
+ */
28095
+ static async getLSTAPRs(assetAddresses) {
28096
+ const stats = await this.getLSTStats();
28097
+ const result = /* @__PURE__ */ new Map();
28098
+ for (const assetAddress of assetAddresses) {
28099
+ const lstStat = stats.find(
28100
+ (stat) => ContractAddr.eqString(stat.assetAddress, assetAddress.address)
28101
+ );
28102
+ if (lstStat) {
28103
+ result.set(assetAddress.address, lstStat.apy);
28104
+ logger.verbose(`LSTAPRService: Found LST APR for ${lstStat.asset}: ${lstStat.apy}`);
28105
+ } else {
28106
+ result.set(assetAddress.address, 0);
28107
+ logger.warn(`LSTAPRService: No LST stats found for asset address ${assetAddress.address}`);
28108
+ }
28109
+ }
28110
+ return result;
28111
+ }
28112
+ /**
28113
+ * Gets all available LST assets and their APRs
28114
+ * @returns Promise<Map<string, LSTStats>> Map of asset address to LST stats
28115
+ */
28116
+ static async getAllLSTStats() {
28117
+ const stats = await this.getLSTStats();
28118
+ const result = /* @__PURE__ */ new Map();
28119
+ for (const stat of stats) {
28120
+ console.log("stat", stat);
28121
+ result.set(stat.assetAddress, stat);
28122
+ }
28123
+ return result;
28124
+ }
28125
+ /**
28126
+ * Clears the cache (useful for testing or forcing refresh)
28127
+ */
28128
+ static clearCache() {
28129
+ this.cache = null;
28130
+ this.cacheTimestamp = 0;
28131
+ logger.verbose(`LSTAPRService: Cache cleared`);
28132
+ }
28133
+ };
28134
+ LSTAPRService.ENDUR_API_URL = "https://app.endur.fi/api/lst/stats";
28135
+ LSTAPRService.cache = null;
28136
+ LSTAPRService.cacheTimestamp = 0;
28137
+ LSTAPRService.CACHE_DURATION = 5 * 60 * 1e3;
28138
+
28016
28139
  // src/notifs/telegram.ts
28017
28140
  import TelegramBot from "node-telegram-bot-api";
28018
28141
  var TelegramNotif = class {
@@ -28540,6 +28663,7 @@ export {
28540
28663
  HyperLSTStrategies,
28541
28664
  ILending,
28542
28665
  Initializable,
28666
+ LSTAPRService,
28543
28667
  MarginType,
28544
28668
  Network,
28545
28669
  PRICE_ROUTER,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strkfarm/sdk",
3
- "version": "1.1.25",
3
+ "version": "1.1.27",
4
4
  "description": "STRKFarm TS SDK (Meant for our internal use, but feel free to use it)",
5
5
  "typings": "dist/index.d.ts",
6
6
  "types": "dist/index.d.ts",
@@ -5,4 +5,5 @@ export * from './pricer-from-api';
5
5
  export * from './erc20';
6
6
  export * from './avnu';
7
7
  export * from './ekubo-quoter';
8
- export * from './pricer-lst';
8
+ export * from './pricer-lst';
9
+ export * from './lst-apr';