UNPKG

@augustdigital/pools

Version:

JS SDK for web3 interactions with the August Digital Lending Pools

431 lines 21.8 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getLendingPools = getLendingPools; exports.getLendingPool = getLendingPool; exports.getLendingPoolAvailableRedemptions = getLendingPoolAvailableRedemptions; exports.getLendingPoolRedemptionHistory = getLendingPoolRedemptionHistory; exports.getAllLendingPoolPositions = getAllLendingPoolPositions; exports.getLendingPoolApr = getLendingPoolApr; exports.getLendingPoolTvl = getLendingPoolTvl; exports.getLendingPoolLoans = getLendingPoolLoans; exports.getHealthFactorOfBorrowersByPool = getHealthFactorOfBorrowersByPool; const utils_1 = require("@augustdigital/utils"); const helpers_1 = require("./helpers"); const ethers_1 = require("ethers"); const abis_1 = require("@augustdigital/abis"); const EthDater = require('ethereum-block-by-date'); function getLendingPools(_a) { return __awaiter(this, arguments, void 0, function* ({ rpcUrl, optionalFields, env, apiKey, pools, }) { let lendingPools; if (Array.isArray(pools) && (pools === null || pools === void 0 ? void 0 : pools.length) > 0) { lendingPools = pools; } else { const provider = (0, utils_1.createProvider)(rpcUrl); const chainId = Number((yield provider.getNetwork()).chainId); const tokenizedVaults = yield (0, utils_1.fetchTokenizedVaults)(); const poolAddresses = tokenizedVaults .filter((vault) => vault.chain === chainId) .map((vault) => vault.address); if (!(poolAddresses === null || poolAddresses === void 0 ? void 0 : poolAddresses.length)) return []; lendingPools = yield (0, helpers_1.getPoolsData)({ pools: poolAddresses, rpcUrl, tokenizedVaults, }); } if (optionalFields === null || optionalFields === void 0 ? void 0 : optionalFields.loans) { try { lendingPools = yield Promise.all(lendingPools === null || lendingPools === void 0 ? void 0 : lendingPools.map((p) => __awaiter(this, void 0, void 0, function* () { if ((0, helpers_1.isBadVault)(p.address)) return p; const _rpcUrl = (p === null || p === void 0 ? void 0 : p.rpcUrl) ? p.rpcUrl : rpcUrl; const loans = yield (0, helpers_1.getPoolLoans)({ pool: p, rpcUrl: _rpcUrl, env }); const loanData = yield (0, helpers_1.getPoolLoansData)({ pool: p, loans, rpcUrl: _rpcUrl, env, apiKey, }); return Object.assign(Object.assign({}, p), loanData); }))); } catch (e) { console.error('#getLendingPools::loans_or_aprs:', e); } } if (env === 'DEV') console.log('#getLendingPools:', lendingPools); return lendingPools; }); } function getLendingPool(_a) { return __awaiter(this, arguments, void 0, function* ({ pool, rpcUrl, optionalFields, env, apiKey, }) { var _b; let returnedPool; try { if (typeof pool === 'string') { const tokenizedVault = (_b = (yield (0, utils_1.fetchTokenizedVaults)(pool))) === null || _b === void 0 ? void 0 : _b[0]; [returnedPool] = yield (0, helpers_1.getPoolsData)({ pools: [pool], rpcUrl, tokenizedVaults: [tokenizedVault], }); } else { returnedPool = pool; } if ((optionalFields === null || optionalFields === void 0 ? void 0 : optionalFields.loans) && !(0, helpers_1.isBadVault)(returnedPool.address)) { const loans = yield (0, helpers_1.getPoolLoans)({ pool: returnedPool, rpcUrl }); const loanData = yield (0, helpers_1.getPoolLoansData)({ pool: returnedPool, loans, rpcUrl, apiKey, }); returnedPool = Object.assign(Object.assign({}, returnedPool), loanData); } } catch (e) { console.error('#getLendingPool::loans_or_aprs:', e); } if (env === 'DEV') console.log('#getLendingPool:', returnedPool); return returnedPool; }); } function getLendingPoolAvailableRedemptions(_a) { return __awaiter(this, arguments, void 0, function* ({ pool, address, rpcUrl, env, apiKey, }) { }); } function getLendingPoolRedemptionHistory(_a) { return __awaiter(this, arguments, void 0, function* ({ pool, address, rpcUrl, env, }) { var _b; try { const provider = (0, utils_1.createProvider)(rpcUrl); const chainId = Number((yield provider.getNetwork()).chainId); const poolContract = (0, utils_1.createContract)({ address: pool, abi: abis_1.ABI_LENDING_POOLS, provider, }); let logPromises = []; const currentBlock = yield provider.getBlockNumber(); let startingBlock = currentBlock - (0, helpers_1.determineBlockSkipInternal)(chainId); let endBlock = currentBlock; const cutoffBlock = currentBlock - (0, helpers_1.determineBlockCutoff)(chainId); while (endBlock >= cutoffBlock) { const logBloomsPromises = poolContract.queryFilter('WithdrawalProcessed', BigInt(startingBlock), BigInt(endBlock)); logPromises.push(logBloomsPromises); startingBlock -= (0, helpers_1.determineBlockSkipInternal)(chainId); endBlock -= (0, helpers_1.determineBlockSkipInternal)(chainId); } const logs = (yield Promise.all(logPromises.flat())).flat(); const iface = new ethers_1.ethers.Interface([ 'event WithdrawalProcessed (uint256 assetsAmount, uint256 processedOn, address receiverAddr, uint256 requestedOn)', ]); const events = logs.map((log) => iface.parseLog(log)); const decimals = yield ((_b = poolContract === null || poolContract === void 0 ? void 0 : poolContract.decimals) === null || _b === void 0 ? void 0 : _b.call(poolContract)); const redemptions = []; events === null || events === void 0 ? void 0 : events.forEach((ev) => { if (!(ev === null || ev === void 0 ? void 0 : ev.args)) return; const [assetsAmount, processedOn, receiverAddr, requestedOn] = ev.args; if (address) { if (receiverAddr === address) { redemptions.push({ receiver: receiverAddr, amount: (0, utils_1.toNormalizedBn)(assetsAmount, decimals), processed: new Date(Number(processedOn) * 1000), requested: new Date(Number(requestedOn) * 1000), pool, }); } } else { redemptions.push({ receiver: receiverAddr, amount: (0, utils_1.toNormalizedBn)(assetsAmount, decimals), processed: new Date(Number(processedOn) * 1000), requested: new Date(Number(requestedOn) * 1000), pool, }); } }); if (env === 'DEV') console.log('#getLendingPoolRedemptionHistory:', redemptions); return redemptions; } catch (e) { console.error('#getLendingPoolRedemptionHistory:', e); } }); } function getAllLendingPoolPositions(_a) { return __awaiter(this, arguments, void 0, function* ({ pools, rpcUrl, address, env, apiKey, }) { let _pools = []; if (pools && (pools === null || pools === void 0 ? void 0 : pools.length)) _pools = pools; else _pools = yield getLendingPools({ rpcUrl, env, optionalFields: { loanAllocations: false, loans: false }, }); if (!(_pools === null || _pools === void 0 ? void 0 : _pools.length)) { console.error('#getAllLendingPoolPositions: error fetching pools'); return []; } return yield Promise.all(_pools === null || _pools === void 0 ? void 0 : _pools.map((pool) => __awaiter(this, void 0, void 0, function* () { var _a, _b; const _rpcUrl = (pool === null || pool === void 0 ? void 0 : pool.rpcUrl) ? pool.rpcUrl : rpcUrl; const poolContract = (0, utils_1.createContract)({ provider: (0, utils_1.createProvider)(_rpcUrl), abi: abis_1.ABI_LENDING_POOLS, address: pool.address, }); const bal = yield poolContract.balanceOf(address); const balance = (0, utils_1.toNormalizedBn)(bal || 0, pool.decimals); const availableRedemptions = []; function renderStatus() { if (availableRedemptions === null || availableRedemptions === void 0 ? void 0 : availableRedemptions.length) return 'REDEEM'; if (BigInt(balance.raw) > BigInt(0)) return 'STAKED'; return 'PENDING'; } const apy = (pool === null || pool === void 0 ? void 0 : pool.apy) ? pool === null || pool === void 0 ? void 0 : pool.apy : (_a = ((yield getLendingPoolApr({ pool: pool.address, rpcUrl: _rpcUrl, })))) === null || _a === void 0 ? void 0 : _a.value; const aggregateAvailableRedemptions = availableRedemptions === null || availableRedemptions === void 0 ? void 0 : availableRedemptions.reduce((acc, curr) => acc + BigInt(curr.amount.raw), BigInt(0)); const underlyingSymbol = (_b = pool === null || pool === void 0 ? void 0 : pool.underlying) === null || _b === void 0 ? void 0 : _b.symbol; return Object.assign(Object.assign({}, pool), { token: underlyingSymbol, position: pool === null || pool === void 0 ? void 0 : pool.name, apy, status: renderStatus(), availableRedemptions, redeemable: (0, utils_1.toNormalizedBn)(aggregateAvailableRedemptions, pool.decimals), walletBalance: balance.normalized, walletBalanceUsd: Number(balance.normalized) * (yield (0, utils_1.fetchTokenPrice)(underlyingSymbol)) }); }))) .then((data) => { const filtered = data.filter((promise) => promise.status !== 'PENDING'); if (env === 'DEV') { console.log('#getAllLendingPoolPositions:', filtered); } return filtered; }) .catch((e) => { console.error('#getAllLendingPoolPositions:', e); return []; }); }); } function getLendingPoolApr(_a) { return __awaiter(this, arguments, void 0, function* ({ pool, rpcUrl, inputParams, env, optionalFields, apiKey, }) { var _b; try { const tokenizedVault = (_b = (yield (0, utils_1.fetchTokenizedVaults)(pool))) === null || _b === void 0 ? void 0 : _b[0]; if (typeof inputParams === 'undefined') { let [returnedPool] = yield (0, helpers_1.getPoolsData)({ pools: [pool], rpcUrl, tokenizedVaults: [tokenizedVault], }); const loans = yield (0, helpers_1.getPoolLoans)({ pool: returnedPool, rpcUrl }); const loanData = yield (0, helpers_1.getPoolLoansData)({ pool: returnedPool, loans, rpcUrl, apiKey, }); returnedPool = Object.assign(Object.assign({}, returnedPool), loanData); return { timestamp: Math.floor(new Date().getTime() / 1000), value: (loanData === null || loanData === void 0 ? void 0 : loanData.apy) || 0, }; } if (typeof inputParams !== 'undefined' && !inputParams.order) inputParams.order = 'desc'; if (typeof inputParams !== 'undefined' && !inputParams.interval) inputParams.interval = 'days'; const provider = (0, utils_1.createProvider)(rpcUrl); let [returnedPool] = yield (0, helpers_1.getPoolsData)({ pools: [pool], rpcUrl, tokenizedVaults: [tokenizedVault], }); const allLoans = yield (0, helpers_1.getPoolLoans)({ pool: returnedPool, rpcUrl }); const dater = new EthDater(provider); const blocks = yield dater.getEvery(inputParams.interval, inputParams.start.toUTCString(), new Date().toUTCString()); const orderedBlocks = inputParams.order === 'desc' ? (0, utils_1.orderObjArrByDate)(blocks) : blocks; const minAbi = [ 'function currentApr() view returns (uint256)', 'function principalAmount() view returns (uint256)', ]; const loanAprsHistorical = yield Promise.all(orderedBlocks === null || orderedBlocks === void 0 ? void 0 : orderedBlocks.map((_a) => __awaiter(this, [_a], void 0, function* ({ block, date }) { let aggregateApr = BigInt(0); const amountOfLoans = BigInt(allLoans.length || 0); const loansApr = yield Promise.all(allLoans.map((l) => __awaiter(this, void 0, void 0, function* () { const loanContract = (0, utils_1.createContract)({ address: l, abi: abis_1.ABI_LOAN, provider, }); const loanAprAtBlock = yield provider.call({ to: loanContract, data: new ethers_1.Interface(minAbi).encodeFunctionData('currentApr', []), blockTag: block, }); if (loanAprAtBlock === '0x') return { timestamp: (0, utils_1.dateToUnix)(new Date(date)), value: (0, utils_1.toNormalizedBn)(0, 0), }; const readableLoanAprAtBlock = new ethers_1.Interface(minAbi).decodeFunctionResult('currentApr', loanAprAtBlock); aggregateApr += readableLoanAprAtBlock === null || readableLoanAprAtBlock === void 0 ? void 0 : readableLoanAprAtBlock[0]; return { timestamp: (0, utils_1.dateToUnix)(new Date(date)), value: (0, utils_1.toNormalizedBn)(readableLoanAprAtBlock === null || readableLoanAprAtBlock === void 0 ? void 0 : readableLoanAprAtBlock[0], helpers_1.LOANS_APR_DECIMALS), }; }))); return { timestamp: (0, utils_1.dateToUnix)(new Date(date)), value: (0, utils_1.toNormalizedBn)(aggregateApr / amountOfLoans, helpers_1.LOANS_APR_DECIMALS), }; }))); if (env === 'DEV') { console.log('#getLendingPoolApr:', loanAprsHistorical); } return loanAprsHistorical; } catch (e) { console.error('#getLendingPoolApr:', e); } }); } function getLendingPoolTvl(_a) { return __awaiter(this, arguments, void 0, function* ({ pool, rpcUrl, inputParams, env, }) { var _b; try { if (typeof inputParams === 'undefined') { const tokenizedVault = (_b = (yield (0, utils_1.fetchTokenizedVaults)(pool))) === null || _b === void 0 ? void 0 : _b[0]; let [returnedPool] = yield (0, helpers_1.getPoolsData)({ pools: [pool], rpcUrl, tokenizedVaults: [tokenizedVault], }); const returnObj = { timestamp: (0, utils_1.dateToUnix)(new Date()), value: returnedPool.totalAssets, }; if (env === 'DEV') console.log('#getLendingPoolTvl:', returnObj); return [returnObj]; } if (typeof inputParams !== 'undefined' && !inputParams.order) inputParams.order = 'desc'; if (typeof inputParams !== 'undefined' && !inputParams.interval) inputParams.interval = 'days'; const provider = (0, utils_1.createProvider)(rpcUrl); const poolContract = (0, utils_1.createContract)({ address: pool, abi: abis_1.ABI_LENDING_POOLS, provider, }); const poolDecimals = yield (0, utils_1.getDecimals)(provider, pool); const dater = new EthDater(provider); const blocks = yield dater.getEvery(inputParams.interval, inputParams.start.toUTCString(), new Date().toUTCString()); const orderedBlocks = inputParams.order === 'desc' ? (0, utils_1.orderObjArrByDate)(blocks) : blocks; const minAbi = ['function totalAssets() view returns (uint256)']; const totalAssetsHistorical = yield Promise.all(orderedBlocks === null || orderedBlocks === void 0 ? void 0 : orderedBlocks.map((_a) => __awaiter(this, [_a], void 0, function* ({ block, date }) { const totalAssetsAtBlock = yield provider.call({ to: poolContract, data: new ethers_1.Interface(minAbi).encodeFunctionData('totalAssets', []), blockTag: block, }); if (totalAssetsAtBlock === '0x') return { timestamp: (0, utils_1.dateToUnix)(new Date(date)), value: (0, utils_1.toNormalizedBn)(0, 0), }; const readableTotalAssetsAtBlock = new ethers_1.Interface(minAbi).decodeFunctionResult('totalAssets', totalAssetsAtBlock); return { timestamp: (0, utils_1.dateToUnix)(new Date(date)), value: (0, utils_1.toNormalizedBn)(readableTotalAssetsAtBlock === null || readableTotalAssetsAtBlock === void 0 ? void 0 : readableTotalAssetsAtBlock[0], poolDecimals), }; }))); if (env === 'DEV') { console.log('#getLendingPoolTvl:', totalAssetsHistorical); } return totalAssetsHistorical; } catch (e) { console.error('#getLendingPoolTvl:', e); } }); } function getLendingPoolLoans(_a) { return __awaiter(this, arguments, void 0, function* ({ pool, rpcUrl, env, optionalFields, apiKey, }) { var _b; try { let returnedPool; if (typeof pool === 'string') { const tokenizedVault = (_b = (yield (0, utils_1.fetchTokenizedVaults)(pool))) === null || _b === void 0 ? void 0 : _b[0]; [returnedPool] = yield (0, helpers_1.getPoolsData)({ pools: [pool], rpcUrl, tokenizedVaults: [tokenizedVault], }); } else { returnedPool = pool; } const loans = yield (0, helpers_1.getPoolLoans)({ pool: returnedPool, rpcUrl }); const loansData = yield (0, helpers_1.getPoolLoansData)({ pool: returnedPool, loans, rpcUrl, apiKey, }); if (typeof pool === 'string') return loansData; return loansData; } catch (e) { console.error('#getLendingPoolLoans:', e); } }); } function getHealthFactorOfBorrowersByPool(_a) { return __awaiter(this, arguments, void 0, function* ({ rpcUrl, optionalFields, env, apiKey, }) { const pools = yield getLendingPools({ rpcUrl, optionalFields, env, apiKey, }); const healthFactors = yield Promise.all(pools.map((pool) => __awaiter(this, void 0, void 0, function* () { return (0, helpers_1.getPoolBorrowerHealthFactor)({ pool, rpcUrl, env, apiKey, }); }))); const healthFactorsByPool = {}; pools.map((pool, index) => { healthFactorsByPool[pool.address] = healthFactors[index]; }); return healthFactorsByPool; }); } //# sourceMappingURL=getters.js.map