UNPKG

@cryptoalgebra/alm-sdk

Version:

Algebra ALM SDK

340 lines 18.7 kB
"use strict"; /* eslint-disable no-redeclare */ /* eslint-disable import/prefer-default-export */ 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()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getAllUserAmounts = exports.getUserAmounts = exports.getAllUserBalances = exports.sendUserBalancesQueryRequest = exports.getUserBalance = void 0; var ethers_1 = require("ethers"); // eslint-disable-next-line import/no-unresolved var graphql_request_1 = require("graphql-request"); var units_1 = require("@ethersproject/units"); var contracts_1 = require("../contracts"); var types_1 = require("../types"); var formatBigInt_1 = __importDefault(require("../utils/formatBigInt")); // eslint-disable-next-line import/no-cycle var vault_1 = require("./vault"); var queries_1 = require("../graphql/queries"); var parseBigInt_1 = __importDefault(require("../utils/parseBigInt")); var getGraphUrls_1 = __importDefault(require("../utils/getGraphUrls")); var multicallUtils_1 = require("../utils/multicallUtils"); var _totalBalances_1 = require("./_totalBalances"); var promises = {}; /** * Helper function to get token address regardless of naming convention (token0/1 or tokenA/B) * @param vault The vault object from API * @param index Token index (0 or 1) * @returns Token address */ function getTokenAddress(vault, index) { if (index === 0) { return vault.token0 || vault.tokenA || ''; } else { return vault.token1 || vault.tokenB || ''; } } // eslint-disable-next-line no-underscore-dangle function _getUserBalance(accountAddress, vaultAddress, jsonProvider, raw) { return __awaiter(this, void 0, void 0, function () { var vaultContract, shares; return __generator(this, function (_a) { switch (_a.label) { case 0: vaultContract = (0, contracts_1.getAlgebraVaultContract)(vaultAddress, jsonProvider); return [4 /*yield*/, vaultContract.balanceOf(accountAddress)]; case 1: shares = _a.sent(); return [2 /*return*/, raw ? shares : (0, formatBigInt_1.default)(shares, types_1.algebraVaultDecimals)]; } }); }); } function getUserBalance(accountAddress, vaultAddress, jsonProvider, dex, raw) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: // eslint-disable-next-line no-return-await return [4 /*yield*/, (0, vault_1.validateVaultData)(vaultAddress, jsonProvider, dex)]; case 1: // eslint-disable-next-line no-return-await _a.sent(); return [2 /*return*/, raw ? _getUserBalance(accountAddress, vaultAddress, jsonProvider, true) : _getUserBalance(accountAddress, vaultAddress, jsonProvider)]; } }); }); } exports.getUserBalance = getUserBalance; function sendUserBalancesQueryRequest(url, accountAddress, query) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, (0, graphql_request_1.request)(url, query, { accountAddress: accountAddress.toLowerCase(), }).then(function (_a) { var vaultShares = _a.vaultShares; return vaultShares; })]; }); }); } exports.sendUserBalancesQueryRequest = sendUserBalancesQueryRequest; function storeResult(key, result) { var cacheTtl = process.env.CACHE_TTL && !Number.isNaN(process.env.CACHE_TTL) ? Number(process.env.CACHE_TTL) : 120000; // 120000 = 2min promises[key] = Promise.resolve(result); setTimeout(function () { delete promises[key]; }, cacheTtl); } function getAllUserBalances(accountAddress, jsonProvider, dex, raw) { return __awaiter(this, void 0, void 0, function () { var chainId, _a, publishedUrl, url, shares, key, strUserBalancesQuery, result, error_1, result, error2_1, balances, userBalances; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, (0, vault_1.getChainByProvider)(jsonProvider)]; case 1: chainId = (_b.sent()).chainId; _a = (0, getGraphUrls_1.default)(chainId, dex, true), publishedUrl = _a.publishedUrl, url = _a.url; key = "".concat(chainId + accountAddress, "-balances"); if (!!Object.prototype.hasOwnProperty.call(promises, key)) return [3 /*break*/, 11]; strUserBalancesQuery = (0, queries_1.userBalancesQuery)(); _b.label = 2; case 2: _b.trys.push([2, 6, , 11]); if (!publishedUrl) return [3 /*break*/, 4]; return [4 /*yield*/, sendUserBalancesQueryRequest(publishedUrl, accountAddress, strUserBalancesQuery)]; case 3: result = _b.sent(); storeResult(key, result); return [3 /*break*/, 5]; case 4: throw new Error("Published URL is invalid for dex ".concat(dex, " on chain ").concat(chainId)); case 5: return [3 /*break*/, 11]; case 6: error_1 = _b.sent(); if (publishedUrl) { console.error('Request to published graph URL failed:', error_1); } _b.label = 7; case 7: _b.trys.push([7, 9, , 10]); return [4 /*yield*/, sendUserBalancesQueryRequest(url, accountAddress, strUserBalancesQuery)]; case 8: result = _b.sent(); storeResult(key, result); return [3 /*break*/, 10]; case 9: error2_1 = _b.sent(); console.error('Request to public graph URL failed:', error2_1); throw new Error("Could not get user balances for ".concat(accountAddress, " on chain ").concat(chainId)); case 10: return [3 /*break*/, 11]; case 11: return [4 /*yield*/, promises[key]]; case 12: balances = _b.sent(); if (balances) { userBalances = balances.vaultShares; shares = userBalances.map(function (balance) { return { vaultAddress: balance.vault.id, shares: balance.vaultShareBalance }; }); return [2 /*return*/, raw ? shares.map(function (s) { return { vaultAddress: s.vaultAddress, shares: (0, parseBigInt_1.default)(s.shares, types_1.algebraVaultDecimals) }; }) : shares]; } else { return [2 /*return*/, []]; } return [2 /*return*/]; } }); }); } exports.getAllUserBalances = getAllUserBalances; function getUserAmounts(accountAddress, vaultAddress, jsonProvider, dex, token0Decimals, token1Decimals, raw) { return __awaiter(this, void 0, void 0, function () { var vault, _a, totalAmounts, totalSupply, shares, userAmountsBN, formattedUserAmounts; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, (0, vault_1.validateVaultData)(vaultAddress, jsonProvider, dex)]; case 1: vault = (_b.sent()).vault; return [4 /*yield*/, Promise.all([ (0, _totalBalances_1._getTotalAmounts)(vault, jsonProvider, token0Decimals, token1Decimals, true), (0, _totalBalances_1._getTotalSupply)(vaultAddress, jsonProvider, true), _getUserBalance(accountAddress, vaultAddress, jsonProvider, true), ])]; case 2: _a = _b.sent(), totalAmounts = _a[0], totalSupply = _a[1], shares = _a[2]; userAmountsBN = [ shares.mul(totalAmounts[0]).div(totalSupply), shares.mul(totalAmounts[1]).div(totalSupply), shares, ]; formattedUserAmounts = [ (0, units_1.formatUnits)(userAmountsBN[0], token0Decimals), (0, units_1.formatUnits)(userAmountsBN[1], token1Decimals), (0, units_1.formatUnits)(shares, types_1.algebraVaultDecimals), ]; if (raw) { return [2 /*return*/, userAmountsBN]; } else { return [2 /*return*/, formattedUserAmounts]; } return [2 /*return*/]; } }); }); } exports.getUserAmounts = getUserAmounts; function getAllUserAmounts(accountAddress, jsonProvider, dex, raw) { var _a; return __awaiter(this, void 0, void 0, function () { var chainId, _b, publishedUrl, url, key, strUserBalancesQuery, result, error_2, result, error2_2, balances, calls, signer, results_1, processedResults, error_3; return __generator(this, function (_c) { switch (_c.label) { case 0: return [4 /*yield*/, (0, vault_1.getChainByProvider)(jsonProvider)]; case 1: chainId = (_c.sent()).chainId; _b = (0, getGraphUrls_1.default)(chainId, dex, true), publishedUrl = _b.publishedUrl, url = _b.url; key = "".concat(chainId + accountAddress, "-all-user-amounts"); if (!!Object.prototype.hasOwnProperty.call(promises, key)) return [3 /*break*/, 11]; strUserBalancesQuery = (0, queries_1.userBalancesQuery)(); _c.label = 2; case 2: _c.trys.push([2, 6, , 11]); if (!publishedUrl) return [3 /*break*/, 4]; return [4 /*yield*/, sendUserBalancesQueryRequest(publishedUrl, accountAddress, strUserBalancesQuery)]; case 3: result = _c.sent(); storeResult(key, result); return [3 /*break*/, 5]; case 4: throw new Error("Published URL is invalid for dex ".concat(dex, " on chain ").concat(chainId)); case 5: return [3 /*break*/, 11]; case 6: error_2 = _c.sent(); if (publishedUrl) { console.error('Request to published graph URL failed:', error_2); } _c.label = 7; case 7: _c.trys.push([7, 9, , 10]); return [4 /*yield*/, sendUserBalancesQueryRequest(url, accountAddress, strUserBalancesQuery)]; case 8: result = _c.sent(); storeResult(key, result); return [3 /*break*/, 10]; case 9: error2_2 = _c.sent(); console.error('Request to public graph URL failed:', error2_2); throw new Error("Could not get user balances for ".concat(accountAddress, " on chain ").concat(chainId)); case 10: return [3 /*break*/, 11]; case 11: _c.trys.push([11, 14, , 15]); return [4 /*yield*/, promises[key]]; case 12: balances = _c.sent(); if (!((_a = balances === null || balances === void 0 ? void 0 : balances.vaultShares) === null || _a === void 0 ? void 0 : _a.length)) { return [2 /*return*/, []]; } calls = balances.vaultShares.flatMap(function (share) { // Normalize token naming by checking which properties exist var token0Address = getTokenAddress(share.vault, 0); var token1Address = getTokenAddress(share.vault, 1); return [ (0, multicallUtils_1.encodeTotalAmountsCall)(share.vault.id), (0, multicallUtils_1.encodeTotalSupplyCall)(share.vault.id), (0, multicallUtils_1.encodeDecimalsCall)(token0Address), (0, multicallUtils_1.encodeDecimalsCall)(token1Address), ]; }); signer = jsonProvider.getSigner(accountAddress); return [4 /*yield*/, (0, multicallUtils_1.multicall)(calls, chainId, signer)]; case 13: results_1 = _c.sent(); processedResults = balances.vaultShares.map(function (share, index) { var baseIndex = index * 4; var totalAmounts = (0, multicallUtils_1.decodeTotalAmountsResult)(results_1[baseIndex], share.vault.id); var totalSupply = (0, multicallUtils_1.decodeTotalSupplyResult)(results_1[baseIndex + 1], share.vault.id); var token0Address = getTokenAddress(share.vault, 0); var token1Address = getTokenAddress(share.vault, 1); var token0Decimals = (0, multicallUtils_1.decodeDecimalsResult)(results_1[baseIndex + 2], token0Address); var token1Decimals = (0, multicallUtils_1.decodeDecimalsResult)(results_1[baseIndex + 3], token1Address); var userBalance = (0, parseBigInt_1.default)(share.vaultShareBalance, types_1.algebraVaultDecimals); if (!totalSupply.isZero()) { var amount0 = userBalance.mul(totalAmounts.total0).div(totalSupply); var amount1 = userBalance.mul(totalAmounts.total1).div(totalSupply); if (!raw) { var userAmounts = [(0, formatBigInt_1.default)(amount0, token0Decimals), (0, formatBigInt_1.default)(amount1, token1Decimals)]; return { vaultAddress: share.vault.id, userAmounts: userAmounts }; } else { var userAmountsBN = [amount0, amount1]; return { vaultAddress: share.vault.id, userAmounts: userAmountsBN }; } } else { return { vaultAddress: share.vault.id, userAmounts: !raw ? { amount0: '0', amount1: '0', 0: '0', 1: '0', } : [ethers_1.BigNumber.from(0), ethers_1.BigNumber.from(0), ethers_1.BigNumber.from(0)], }; } }); return [2 /*return*/, processedResults]; case 14: error_3 = _c.sent(); console.error('Could not get user amounts'); throw error_3; case 15: return [2 /*return*/]; } }); }); } exports.getAllUserAmounts = getAllUserAmounts; //# sourceMappingURL=userBalances.js.map