@augustdigital/pools
Version:
JS SDK for web3 interactions with the August Digital Lending Pools
431 lines • 21.8 kB
JavaScript
;
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