UNPKG

@admin-jigsaw/jigsaw-sdk

Version:

Returns predefined data for Jigsaw platform and exposes functionality to retrieve the necessary data

194 lines (193 loc) 9.73 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.JigsawClient = void 0; const viem_1 = require("viem"); const chains_1 = require("viem/chains"); const strategyManagerAbi_1 = require("./contracts/strategyManagerAbi"); const strategyAbi_1 = require("./contracts/strategyAbi"); const pendle_utils_1 = require("./utils/pendle.utils"); const pendle_1 = require("./lib/pendle"); const protocols_utils_1 = require("./utils/protocols.utils"); const chains_2 = require("./constants/chains"); const strategiesSharedConstants_1 = require("./constants/strategiesSharedConstants"); class JigsawClient { constructor(rpcUrl, chainId) { const chain = (0, viem_1.extractChain)({ chains: [chains_1.mainnet, chains_1.sonic], id: chainId, // Allow any chainId, will throw an error if unsupported }); const transport = rpcUrl ? (0, viem_1.http)(rpcUrl) : (0, viem_1.http)(); this.client = (0, viem_1.createPublicClient)({ chain, transport }); } /** * Fetches user strategies based on holding address and optional asset symbol. * @param holdingAddress The address of the user's holding contract. * @param assetSymbol Optional filter for asset symbol. * @returns A list of strategies. */ async getUserStrategies(holdingAddress, assetSymbol) { try { const chainConfig = (0, chains_2.getChainConfig)(this.client.chain?.id || chains_1.mainnet.id); const data = await this.client.readContract({ address: chainConfig.constants.strategyManagerAddress, abi: strategyManagerAbi_1.strategyManagerAbi, functionName: "getHoldingToStrategy", args: [holdingAddress], }); if (!Array.isArray(data)) return []; // If no asset symbol specified, return all strategy addresses if (!assetSymbol) { return data; } // Filter strategies based on the symbol return data.filter((strategyAddress) => { const lowerSymbol = assetSymbol.toLowerCase(); if (chainConfig.strategies === null) return false; // Check AAVE strategies if (chainConfig.strategies.aave?.aaveStrategies) { const aaveStrategy = Object.entries(chainConfig.strategies.aave.aaveStrategies).find(([symbol, strat]) => symbol.toLowerCase() === lowerSymbol && (0, viem_1.getAddress)(strat.stratAddress) === (0, viem_1.getAddress)(strategyAddress)); if (aaveStrategy) return true; } // Check DINERO strategies if (chainConfig.strategies.dinero) { const dineroStrategy = Object.entries(chainConfig.strategies.dinero).find(([symbol, strat]) => symbol.toLowerCase() === lowerSymbol && (0, viem_1.getAddress)(strat.stratAddress) === (0, viem_1.getAddress)(strategyAddress)); if (dineroStrategy) return true; } // Check RESERVOIR strategies if (chainConfig.strategies.reservoir) { const reservoirStrategy = Object.entries(chainConfig.strategies.reservoir).find(([symbol, strat]) => symbol.toLowerCase() === lowerSymbol && (0, viem_1.getAddress)(strat.stratAddress) === (0, viem_1.getAddress)(strategyAddress)); if (reservoirStrategy) return true; } // Check PENDLE strategies if (chainConfig.strategies.pendle?.strategies) { const pendleStrategy = Object.entries(chainConfig.strategies.pendle.strategies).find(([symbol, strategies]) => { if (symbol.toLowerCase() !== lowerSymbol) return false; return strategies.some((strategy) => (0, viem_1.getAddress)(strategy.stratAddress) === (0, viem_1.getAddress)(strategyAddress)); }); if (pendleStrategy) return true; } return false; }); } catch (error) { console.error("Failed to fetch user strategies:", error); return []; } } /** * Fetches liquidation call data for user strategies, optionally filtered by asset symbol. * @param holdingAddress User's holding contract address. * @param assetSymbol Optional filter for asset symbol. * @param pendleSlippage Optional slippage parameter for Pendle strategies. * @returns Object with arrays of strategy addresses and corresponding call data strings. */ async getUserLiquidationInfo(holdingAddress, assetSymbol, pendleSlippage) { try { // Get all strategies for this holding address const strategies = await this.getUserStrategies(holdingAddress, assetSymbol); if (!strategies.length) { return { strategies: [], strategiesData: [] }; } // Generate calldata for each strategy, maintaining array correspondence const callDataPromises = strategies.map(async (strategyAddress) => { try { const protocolName = (0, protocols_utils_1.getProtocolByStrategy)(strategyAddress, this.client.chain?.id || chains_1.mainnet.id); // Only generate callData for Pendle strategies if (protocolName === strategiesSharedConstants_1.PROTOCOLS_DATA.PENDLE.name) { const multicallResults = await this.client.multicall({ contracts: [ { address: strategyAddress, abi: strategyAbi_1.strategyAbi, functionName: "recipients", args: [holdingAddress], }, { address: strategyAddress, abi: strategyAbi_1.strategyAbi, functionName: "tokenIn", args: [], }, ], }); const totalSharesRaw = multicallResults[0]?.result ? (multicallResults[0].result[1] ?? BigInt(0)) : BigInt(0); const tokenAddress = multicallResults[1]?.result ?? null; const pendleMarket = (0, pendle_utils_1.getPendleMarketByStrategy)(strategyAddress, this.client.chain?.id || chains_1.mainnet.id); if (!pendleMarket || !tokenAddress) return ""; const resp = await (0, pendle_1.removeLiquiditySingleToken)(tokenAddress, totalSharesRaw.toString(), pendleMarket, holdingAddress, pendleSlippage, this.client.chain?.id || chains_1.mainnet.id); return await (0, pendle_utils_1.generatePendleRemoveLiquidityDataString)(resp); } // For non-Pendle strategies, return empty string but maintain array correspondence return viem_1.zeroAddress; } catch (error) { console.error(`Error processing strategy ${strategyAddress}:`, error); // Return empty string on error, but maintain array correspondence return viem_1.zeroAddress; } }); // Resolve all promises while maintaining strategy-callData correspondence const strategiesData = await Promise.all(callDataPromises); return { strategies, strategiesData, }; } catch (error) { console.error("Failed to fetch liquidation info:", error); return { strategies: [], strategiesData: [] }; } } /** * Fetches the current gas fee in Ether. * @returns The gas price as a formatted string. */ async getCurrentGasFee() { try { const gasPrice = await this.client.getGasPrice(); const priceInEth = (0, viem_1.formatEther)(gasPrice); console.log(`Current gas price is ${priceInEth}`); return priceInEth; } catch (error) { console.error("Failed to fetch gas price:", error); return "0"; } } /** * Retrieves information about a specific strategy. * @param strategyAddress Strategy contract address. * @returns StrategyInfo object or null. */ async getStrategyInfo(strategyAddress) { try { const chainConfig = (0, chains_2.getChainConfig)(this.client.chain?.id || chains_1.mainnet.id); const strategyInfo = (await this.client.readContract({ address: chainConfig.constants.strategyManagerAddress, abi: strategyManagerAbi_1.strategyManagerAbi, functionName: "strategyInfo", args: [strategyAddress], })); return strategyInfo ?? null; } catch (error) { console.error("Failed to fetch strategy info:", error); return null; } } } exports.JigsawClient = JigsawClient;