UNPKG

@moonwell-fi/moonwell-sdk

Version:

TypeScript Interface for Moonwell

210 lines 9.69 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.transformVaultFromIndexer = transformVaultFromIndexer; exports.transformVaultsFromIndexer = transformVaultsFromIndexer; exports.fetchTokenMap = fetchTokenMap; exports.fetchVaultsFromIndexer = fetchVaultsFromIndexer; exports.fetchVaultFromIndexer = fetchVaultFromIndexer; exports.fetchVaultSnapshotsFromIndexer = fetchVaultSnapshotsFromIndexer; exports.getV1VaultKey = getV1VaultKey; exports.transformVaultSnapshotsFromIndexer = transformVaultSnapshotsFromIndexer; const amount_js_1 = require("../../../common/amount.js"); function buildTokenConfig(token) { return { address: token.address, symbol: token.symbol, name: token.name, decimals: token.decimals, }; } function buildVaultTokenConfig(vault) { return { address: vault.address, symbol: vault.symbol, name: vault.name, decimals: vault.decimals, }; } function transformMarket(market, underlyingDecimals, totalAssets, tokenMap) { const collateralToken = tokenMap.get(market.marketCollateral.toLowerCase()); const vaultSupplied = Number.parseFloat(market.vaultSupplied); const allocation = totalAssets > 0 ? vaultSupplied / totalAssets : 0; return { marketId: market.marketId, allocation, marketApy: Number.parseFloat(market.marketApy), marketLoanToValue: Number.parseFloat(market.marketLltv), marketCollateral: collateralToken ? buildTokenConfig(collateralToken) : { address: market.marketCollateral, symbol: market.marketCollateralSymbol, name: market.marketCollateralName, decimals: 18, }, marketLiquidity: new amount_js_1.Amount(Number.parseFloat(market.marketLiquidity), underlyingDecimals), marketLiquidityUsd: Number.parseFloat(market.marketLiquidityUsd), totalSupplied: new amount_js_1.Amount(vaultSupplied, underlyingDecimals), totalSuppliedUsd: Number.parseFloat(market.vaultSuppliedUsd), rewards: [], }; } function transformRewards(rewards, tokenMap) { return rewards.map((reward) => { const token = tokenMap.get(reward.token.toLowerCase()); return { asset: token ? buildTokenConfig(token) : { address: reward.token, symbol: reward.tokenSymbol, name: reward.tokenSymbol, decimals: 18, }, supplyApr: Number.parseFloat(reward.apr), supplyAmount: 0, borrowApr: 0, borrowAmount: 0, }; }); } function findVaultConfigByAddress(environment, address) { const vaultKey = Object.keys(environment.config.vaults).find((key) => environment.config.tokens[key]?.address.toLowerCase() === address.toLowerCase()); return { key: vaultKey, config: vaultKey ? environment.config.vaults[vaultKey] : undefined, }; } function transformVaultFromIndexer(indexerVault, environment, tokenMap) { const underlyingToken = indexerVault.underlyingToken || tokenMap.get(indexerVault.underlyingTokenAddress.toLowerCase()); if (!underlyingToken) { throw new Error(`Underlying token not found: ${indexerVault.underlyingTokenAddress}`); } const underlyingDecimals = underlyingToken.decimals; const { key: vaultKey, config: vaultConfig } = findVaultConfigByAddress(environment, indexerVault.address); const sdkVaultTokenConfig = vaultConfig ? environment.config.tokens[vaultConfig.vaultToken] : undefined; const sdkUnderlyingTokenConfig = vaultConfig ? environment.config.tokens[vaultConfig.underlyingToken] : undefined; const version = vaultConfig?.version ?? 1; const totalAssetsValue = Number.parseFloat(indexerVault.totalAssets); const totalLiquidityValue = Number.parseFloat(indexerVault.totalLiquidity); const vaultSupplyValue = Math.max(0, totalAssetsValue - totalLiquidityValue); const markets = indexerVault.markets.map((market) => transformMarket(market, underlyingDecimals, totalAssetsValue, tokenMap)); const rewards = transformRewards(indexerVault.rewards, tokenMap); const vault = { chainId: indexerVault.chainId, vaultKey: vaultKey || `unknown_${indexerVault.address}`, version, deprecated: vaultConfig?.deprecated ?? false, vaultToken: sdkVaultTokenConfig ?? buildVaultTokenConfig(indexerVault), underlyingToken: sdkUnderlyingTokenConfig ?? buildTokenConfig(underlyingToken), totalSupply: new amount_js_1.Amount(totalAssetsValue, underlyingDecimals), totalLiquidity: new amount_js_1.Amount(totalLiquidityValue, underlyingDecimals), vaultSupply: new amount_js_1.Amount(vaultSupplyValue, underlyingDecimals), totalSupplyUsd: Number.parseFloat(indexerVault.totalAssetsUsd), totalLiquidityUsd: Number.parseFloat(indexerVault.totalLiquidityUsd), underlyingPrice: Number.parseFloat(indexerVault.underlyingPrice), baseApy: Number.parseFloat(indexerVault.baseApy), rewardsApy: Number.parseFloat(indexerVault.rewardsApy), totalApy: Number.parseFloat(indexerVault.totalApy), performanceFee: Number.parseFloat(indexerVault.performanceFee) / 100, timelock: Number.parseInt(indexerVault.timelock) / (60 * 60), curators: indexerVault.curators || [], markets, rewards, totalStaked: new amount_js_1.Amount(0n, underlyingDecimals), totalStakedUsd: 0, stakingRewardsApr: 0, totalStakingApr: Number.parseFloat(indexerVault.baseApy), stakingRewards: [], }; return vault; } function transformVaultsFromIndexer(indexerVaults, environment, tokenMap) { return indexerVaults.map((vault) => transformVaultFromIndexer(vault, environment, tokenMap)); } async function fetchTokenMap(lunarIndexerUrl, chainId) { const url = `${lunarIndexerUrl}/api/v1/vaults/tokens/${chainId}`; const response = await fetch(url, { signal: AbortSignal.timeout(10_000) }); if (!response.ok) { throw new Error(`Failed to fetch tokens from Lunar Indexer: ${response.status} ${response.statusText}`); } const data = await response.json(); const tokenMap = new Map(); for (const token of data.results) { tokenMap.set(token.address.toLowerCase(), token); } return tokenMap; } async function fetchVaultsFromIndexer(lunarIndexerUrl, chainId, options) { const params = new URLSearchParams(); if (options?.limit) params.set("limit", options.limit.toString()); if (options?.cursor) params.set("cursor", options.cursor); if (options?.includeRewards) params.set("includeRewards", "true"); const url = `${lunarIndexerUrl}/api/v1/vaults/vaults/${chainId}${params.toString() ? `?${params.toString()}` : ""}`; const response = await fetch(url, { signal: AbortSignal.timeout(10_000) }); if (!response.ok) { throw new Error(`Failed to fetch vaults from Lunar Indexer: ${response.status} ${response.statusText}`); } return response.json(); } async function fetchVaultFromIndexer(lunarIndexerUrl, vaultId) { const url = `${lunarIndexerUrl}/api/v1/vaults/vault/${vaultId}`; const response = await fetch(url, { signal: AbortSignal.timeout(10_000) }); if (!response.ok) { throw new Error(`Failed to fetch vault from Lunar Indexer: ${response.status} ${response.statusText}`); } return response.json(); } async function fetchVaultSnapshotsFromIndexer(lunarIndexerUrl, vaultId, options) { const params = new URLSearchParams(); if (options?.cursor) params.set("cursor", options.cursor); if (options?.limit) params.set("limit", options.limit.toString()); if (options?.granularity) params.set("granularity", options.granularity); if (options?.startTime) params.set("startTime", options.startTime.toString()); if (options?.endTime) params.set("endTime", options.endTime.toString()); const queryString = params.toString(); const url = `${lunarIndexerUrl}/api/v1/vaults/vault/${vaultId}/snapshots${queryString ? `?${queryString}` : ""}`; const response = await fetch(url, { signal: AbortSignal.timeout(10_000) }); if (!response.ok) { throw new Error(`Failed to fetch vault snapshots from Lunar Indexer: ${response.status} ${response.statusText}`); } return response.json(); } function getV1VaultKey(environment, vaultKey) { const rawKey = environment.config.vaults[vaultKey]?.v1VaultKey; return typeof rawKey === "string" ? rawKey : undefined; } function transformVaultSnapshotsFromIndexer(snapshots, chainId) { return snapshots.map((snapshot) => { const totalAssets = Number.parseFloat(snapshot.totalAssets); const totalAssetsUsd = Number.parseFloat(snapshot.totalAssetsUsd); const totalLiquidity = Number.parseFloat(snapshot.totalLiquidity); const totalLiquidityUsd = Number.parseFloat(snapshot.totalLiquidityUsd); return { chainId, vaultAddress: snapshot.vaultAddress.toLowerCase(), totalSupply: totalAssets, totalSupplyUsd: totalAssetsUsd, totalBorrows: totalAssets - totalLiquidity, totalBorrowsUsd: totalAssetsUsd - totalLiquidityUsd, totalLiquidity, totalLiquidityUsd, timestamp: snapshot.timestamp * 1000, }; }); } //# sourceMappingURL=lunarIndexerTransform.js.map