@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.
- package/dist/index.browser.global.js +231 -112
- package/dist/index.browser.mjs +125 -1
- package/dist/index.d.ts +50 -1
- package/dist/index.js +126 -1
- package/dist/index.mjs +125 -1
- package/package.json +1 -1
- package/src/modules/index.ts +2 -1
- package/src/modules/lst-apr.ts +140 -0
- package/src/strategies/universal-strategy.tsx +31 -2
package/dist/index.browser.mjs
CHANGED
|
@@ -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 =
|
|
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 =
|
|
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 =
|
|
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
package/src/modules/index.ts
CHANGED