@cryptoalgebra/alm-sdk
Version:
Algebra ALM SDK
340 lines • 18.7 kB
JavaScript
"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