UNPKG

@parifi/sdk

Version:

Parifi SDK with common utility functions

1,577 lines (1,548 loc) 64.7 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/subgraph/index.ts var subgraph_exports = {}; __export(subgraph_exports, { Subgraph: () => Subgraph, getAllMarketsFromSubgraph: () => getAllMarketsFromSubgraph, getAllOpenPositionsWithTime: () => getAllOpenPositionsWithTime, getAllOrdersByUserAddress: () => getAllOrdersByUserAddress, getAllPositionHistoryWithTime: () => getAllPositionHistoryWithTime, getAllPositionsByUserAddress: () => getAllPositionsByUserAddress, getClosedPositionsByUserAddress: () => getClosedPositionsByUserAddress, getLiquidatedPositionsByUserAddress: () => getLiquidatedPositionsByUserAddress, getMarketById: () => getMarketById, getOpenPositionsByUserAddress: () => getOpenPositionsByUserAddress, getOrderById: () => getOrderById, getPositionById: () => getPositionById, getPublicSubgraphEndpoint: () => getPublicSubgraphEndpoint, getSettledOrdersCountBasedOnTimeStampByUserAddress: () => getSettledOrdersCountBasedOnTimeStampByUserAddress, getUserLiquidatedPositionsBySnxAccount: () => getUserLiquidatedPositionsBySnxAccount, getUserOpenPositionsWithTime: () => getUserOpenPositionsWithTime, getUserPositionHistoryWithTime: () => getUserPositionHistoryWithTime, getUserPositionsHistory: () => getUserPositionsHistory, publicSubgraphEndpoints: () => publicSubgraphEndpoints }); module.exports = __toCommonJS(subgraph_exports); // src/common/constants.ts var import_decimal = require("decimal.js"); var PRECISION_MULTIPLIER = new import_decimal.Decimal("10000"); var DEVIATION_PRECISION_MULTIPLIER = new import_decimal.Decimal(10).pow(12); var SECONDS_IN_A_YEAR = new import_decimal.Decimal(365 * 24 * 60 * 60); var MAX_FEE = new import_decimal.Decimal(1e7); var WAD = new import_decimal.Decimal(10).pow(18); var DECIMAL_10 = new import_decimal.Decimal(10); var DECIMAL_ZERO = new import_decimal.Decimal(0); var BIGINT_ZERO = BigInt(0); var ONE_GWEI = 1e9; var DEFAULT_GAS_PRICE = 2 * ONE_GWEI; var SYMBOL_TO_PYTH_FEED = /* @__PURE__ */ new Map([ // market ["BTC", "0xc9d8b075a5c69303365ae23633d4e085199bf5c520a3b90fed1322a0342ffc33"], ["SOL", "0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d"], ["WIF", "0x4ca4beeca86f0d164160323817a4e42b10010a724c2217c6ee41b54cd4cc61fc"], ["ETH", "0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace"], ["AAVE", "0x2b9ab1e972a281585084148ba1389800799bd4be63b957507db1349314e47445"], ["ADA", "0x2a01deaec9e51a579277b34b122399984d0bbf57e2458a7e42fecd2829867a0d"], ["ARB", "0x3fa4252848f9f0a1480be62745a4629d9eb1322aebab8a791e344b3b9c1adcf5"], ["AVAX", "0x93da3352f9f1d105fdfe4971cfa80e9dd777bfc5d0f683ebb6e1294b92137bb7"], ["BCH", "0x3dd2b63686a450ec7290df3a1e0b583c0481f651351edfa7636f39aed55cf8a3"], ["BNB", "0x2f95862b045670cd22bee3114c39763a4a08beeb663b145d283c31d7d1101c4f"], ["CRV", "0xa19d04ac696c7a6616d291c7e5d1377cc8be437c327b75adb5dc1bad745fcae8"], ["DOGE", "0xdcef50dd0a4cd2dcc17e45df1676dcb336a11a61c69df7a0299b0150c672d25c"], ["DYDX", "0x6489800bb8974169adfe35937bf6736507097d13c190d760c557108c7e93a81b"], ["GMX", "0xb962539d0fcb272a494d65ea56f94851c2bcf8823935da05bd628916e2e9edbf"], ["LINK", "0x8ac0c70fff57e9aefdf5edf44b51d62c2d433653cbb2cf5cc06bb115af04d221"], ["LTC", "0x6e3f3fa8253588df9326580180233eb791e03b443a3ba7a1d892e73874e19a54"], ["MKR", "0x9375299e31c0deb9c6bc378e6329aab44cb48ec655552a70d4b9050346a30378"], ["NEAR", "0xc415de8d2eba7db216527dff4b60e8f3a5311c740dadb233e13e12547e226750"], ["OP", "0x385f64d993f7b77d8182ed5003d97c60aa3361f3cecfe711544d2d59165e9bdf"], ["ORDI", "0x193c739db502aadcef37c2589738b1e37bdb257d58cf1ab3c7ebc8e6df4e3ec0"], ["PEPE", "0xd69731a2e74ac1ce884fc3890f7ee324b6deb66147055249568869ed700882e4"], ["POL", "0xffd11c5a1cfd42f80afb2df4d9f264c15f956d68153335374ec10722edd70472"], ["PYTH", "0x0bbf28e9a841a1cc788f6a361b17ca072d0ea3098a1e5df1c3922d06719579ff"], ["RUNE", "0x5fcf71143bb70d41af4fa9aa1287e2efd3c5911cee59f909f915c9f61baacb1e"], ["SHIB", "0xf0d57deca57b3da2fe63a493f4c25925fdfd8edf834b20f93e1f84dbd1504d4a"], ["STX", "0xec7a775f46379b5e943c3526b1c8d54cd49749176b0b98e02dde68d1bd335c17"], ["TIA", "0x09f7c1d7dfbb7df2b8fe3d3d87ee94a2259d212da4f30c1f0540d066dfa44723"], ["UNI", "0x78d185a741d07edb3412b09008b7c5cfb9bbbd7d568bf00ba737b456ba171501"], ["XLM", "0xb7a8eba68a997cd0210c2e1e4ee811ad2d174b3611c22d9ebf16f4cb7e9ba850"], ["XRP", "0xec5d399846a9209f3fe5881d70aae9268c94339ff9817e8d18ff19fa05eea1c8"], // collateral ["USDC", "0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a"], ["USDE", "0x6ec879b1e9963de5ee97e9c8710b742d6228252a5e2ca12d4ae81d7fe5ee8c5d"], ["DAI", "0xb0948a5e5313200c632b51bb5ca32f6de0d36e9950a942d19751e833f70dabfd"] ]); var collateralMappingWithRegularSymbol = /* @__PURE__ */ new Map([ ["seth", "eth"], ["wbtc", "btc"], ["fbtc", "btc"], ["wsteth", "eth"], ["fdai", "dai"], ["susdc", "usdc"], ["susde", "usde"], ["steth", "eth"], ["fsol", "sol"], ["fusdc", "usdc"], ["fusdt", "usdt"], ["ssol", "sol"], ["sdai", "dai"], ["usdx", "usdc"], ["stbtc", "btc"] ]); // src/common/helpers.ts var import_viem = require("viem"); var getUniqueValuesFromArray = (originalArray) => { const uniqueArray = []; const seenValues = /* @__PURE__ */ new Set(); originalArray.forEach((item) => { if (!seenValues.has(item)) { uniqueArray.push(item); seenValues.add(item); } }); return uniqueArray; }; function convertWeiToEther(amountInWei) { if (amountInWei == void 0) { throw new Error("Invalid amount received during conversion: undefined"); } if (typeof amountInWei == "bigint") { return Number((0, import_viem.formatEther)(amountInWei)); } else if (typeof amountInWei == "string") { return Number((0, import_viem.formatEther)(BigInt(amountInWei))); } else { throw new Error("Expected string or bigint for conversion"); } } // src/subgraph/positions/index.ts var import_graphql_request2 = require("graphql-request"); // src/subgraph/positions/subgraphQueries.ts var import_graphql_request = require("graphql-request"); var fetchPositionsByUserQuery = (userAddress, count = 20, skip = 0) => import_graphql_request.gql` { snxAccounts( first: ${count} skip: ${skip} where: { owner: "${userAddress}", type: PERP }) { id accountId owner { id } collateralDeposits { id collateralName collateralSymbol collateralDecimals collateralAddress currentDepositedAmount totalAmountDeposited totalAmountWithdrawn totalAmountLiquidated } positions(where: {status_in: [OPEN, CLOSED, LIQUIDATED]}) { id market { id marketName marketSymbol feedId } positionSize avgPrice avgPriceDec isLong createdTimestamp status txHash liquidationTxHash closingPrice realizedPositionPnl realizedPnlAfterFees totalFeesPaid createdTimestamp lastRefresh lastRefreshISO canBeLiquidated snapshotCollateralValueUsd } } }`; var fetchPositionsByUserQueryAndStatus = (userAddress, status, count = 20, skip = 0) => import_graphql_request.gql` { snxAccounts( first: ${count} skip: ${skip} where: { owner: "${userAddress}", type: PERP } ) { id accountId owner { id } collateralDeposits { id collateralName collateralSymbol collateralDecimals collateralAddress currentDepositedAmount totalAmountDeposited totalAmountWithdrawn totalAmountLiquidated } positions(where: {status: ${status} }) { id market { id marketName marketSymbol feedId } positionSize avgPrice avgPriceDec isLong createdTimestamp status txHash liquidationTxHash closingPrice realizedPositionPnl realizedPnlAfterFees totalFeesPaid createdTimestamp lastRefresh lastRefreshISO canBeLiquidated snapshotCollateralValueUsd } } }`; var fetchOpenPositionsByUser = (userAddress, count = 20, skip = 0) => import_graphql_request.gql` { snxAccounts( first: ${count} skip: ${skip} where: { owner: "${userAddress}", type: PERP, openPositionCount_gt: 0 } ) { id accountId owner { id } collateralDeposits { id collateralName collateralSymbol collateralDecimals collateralAddress currentDepositedAmount totalAmountDeposited totalAmountWithdrawn totalAmountLiquidated } positions(where: {status: OPEN }) { id market { id marketName marketSymbol feedId } positionSize avgPrice avgPriceDec isLong createdTimestamp status txHash liquidationTxHash closingPrice realizedPositionPnl realizedPnlAfterFees totalFeesPaid createdTimestamp lastRefresh lastRefreshISO canBeLiquidated snapshotCollateralValueUsd } } }`; var fetchUserPositionHistory = (userAddress, count = 20, skip = 0) => import_graphql_request.gql` { snxAccounts( first: ${count} skip: ${skip} where: { owner: "${userAddress}", type: PERP } ) { id accountId owner { id } collateralDeposits { id collateralName collateralSymbol collateralDecimals collateralAddress currentDepositedAmount totalAmountDeposited totalAmountWithdrawn totalAmountLiquidated } positions(where: {status_in: [CLOSED, LIQUIDATED]}) { id market { id marketName marketSymbol feedId } positionSize avgPrice avgPriceDec isLong createdTimestamp status txHash liquidationTxHash closingPrice realizedPositionPnl realizedPnlAfterFees totalFeesPaid createdTimestamp lastRefresh lastRefreshISO canBeLiquidated snapshotCollateralValueUsd } } }`; var fetchPositionByIdQuery = (positionId) => import_graphql_request.gql` { position( id: "${positionId}" ) { id market { id, marketName, marketSymbol, feedId } snxAccount{ id accountId } isLong positionSize avgPrice avgPriceDec status txHash liquidationTxHash closingPrice realizedPositionPnl realizedPnlAfterFees totalFeesPaid createdTimestamp lastRefresh lastRefreshISO canBeLiquidated snapshotCollateralValueUsd } }`; var fetchUserPositionHistoryWithTime = (userAddress, startTimestamp, endTimestamp, count = 20, skip = 0) => import_graphql_request.gql` { snxAccounts( first: ${count} skip: ${skip} where: { owner: "${userAddress}", type: PERP } ) { id accountId owner { id } collateralDeposits { id collateralName collateralSymbol collateralDecimals collateralAddress currentDepositedAmount totalAmountDeposited totalAmountWithdrawn totalAmountLiquidated } positions( where: { status_in: [CLOSED, LIQUIDATED], createdTimestamp_gte: ${startTimestamp} createdTimestamp_lte: ${endTimestamp} }) { id market { id marketName marketSymbol feedId } positionSize positionCollateral avgPrice avgPriceDec isLong createdTimestamp status txHash liquidationTxHash closingPrice realizedPositionPnl realizedPnlAfterFees totalFeesPaid createdTimestamp lastRefresh lastRefreshISO canBeLiquidated snapshotCollateralValueUsd } } }`; var fetchUserOpenPositionsWithTime = (userAddress, startTimestamp, endTimestamp, count = 20, skip = 0) => import_graphql_request.gql` { snxAccounts( first: ${count} skip: ${skip} where: { owner: "${userAddress}", type: PERP, positions_: { status: OPEN, createdTimestamp_gte: ${startTimestamp} createdTimestamp_lte: ${endTimestamp} } } ) { id accountId owner { id } collateralDeposits { id collateralName collateralSymbol collateralDecimals collateralAddress currentDepositedAmount totalAmountDeposited totalAmountWithdrawn totalAmountLiquidated } positions { id market { id marketName marketSymbol feedId } positionSize avgPrice avgPriceDec isLong createdTimestamp status txHash liquidationTxHash closingPrice realizedPositionPnl realizedPnlAfterFees totalFeesPaid createdTimestamp lastRefresh lastRefreshISO canBeLiquidated snapshotCollateralValueUsd } } }`; var fetchLiquidatedPositionsBySnxAccount = (snxAccountId, lastRefresh) => import_graphql_request.gql` { snxAccount(id: "${snxAccountId}" ) { id accountId owner { id } collateralDeposits { id collateralName collateralSymbol collateralDecimals collateralAddress currentDepositedAmount totalAmountDeposited totalAmountWithdrawn totalAmountLiquidated } positions(where: { status: LIQUIDATED, lastRefresh_gt: ${lastRefresh} }) { id market { id marketName marketSymbol feedId } positionSize avgPrice avgPriceDec isLong createdTimestamp status txHash liquidationTxHash closingPrice realizedPositionPnl realizedPnlAfterFees totalFeesPaid createdTimestamp lastRefresh lastRefreshISO canBeLiquidated snapshotCollateralValueUsd } } }`; var fetchAllOpenPositionsWithTime = (startTimestamp, endTimestamp, count = 20, skip = 0) => import_graphql_request.gql` { snxAccounts( first: ${count} skip: ${skip} where: { type: PERP openPositionCount_gt:0 } ) { id accountId owner { id } collateralDeposits { id collateralName collateralSymbol collateralDecimals collateralAddress currentDepositedAmount totalAmountDeposited totalAmountWithdrawn totalAmountLiquidated } positions(where: { status: OPEN, createdTimestamp_gte: ${startTimestamp} createdTimestamp_lte: ${endTimestamp} }) { id market { id marketName marketSymbol feedId } positionSize avgPrice avgPriceDec isLong createdTimestamp status txHash liquidationTxHash closingPrice realizedPositionPnl realizedPnlAfterFees totalFeesPaid createdTimestamp lastRefresh lastRefreshISO canBeLiquidated snapshotCollateralValueUsd } } }`; var fetchAllPositionHistoryWithTime = (startTimestamp, endTimestamp, count = 20, skip = 0) => import_graphql_request.gql` { snxAccounts( first: ${count} skip: ${skip} where: { type: PERP totalPositionsCount_gt :0 } ) { id accountId owner { id } collateralDeposits { id collateralName collateralSymbol collateralDecimals collateralAddress currentDepositedAmount totalAmountDeposited totalAmountWithdrawn totalAmountLiquidated } positions(where: { status_in: [CLOSED, LIQUIDATED], createdTimestamp_gte: ${startTimestamp} createdTimestamp_lte: ${endTimestamp} }) { id market { id marketName marketSymbol feedId } positionSize avgPrice avgPriceDec isLong createdTimestamp status txHash liquidationTxHash closingPrice realizedPositionPnl realizedPnlAfterFees totalFeesPaid createdTimestamp lastRefresh lastRefreshISO canBeLiquidated snapshotCollateralValueUsd } } }`; // src/error/not-found.error.ts var NotFoundError = class extends Error { constructor(message) { super(message); this.name = this.constructor.name; } }; // src/common/subgraphMapper.ts var mapResponseToWallet = (response) => { if (!response) return void 0; try { return { id: response?.id // snxAccounts: mapSnxAccountsArray(response.snxAccounts) }; } catch (error) { console.log("Error while mapping data", error); return void 0; } }; var mapResponseToSnxAccount = (response) => { if (!response) return void 0; try { return { id: response?.id, type: response?.type, accountId: response?.accountId, owner: response?.owner ?? mapResponseToWallet(response?.owner), totalOrdersCount: response?.totalOrdersCount, totalPositionsCount: response?.totalPositionsCount, openPositionCount: response?.openPositionCount, countProfitablePositions: response?.countProfitablePositions, countLossPositions: response?.countLossPositions, countLiquidatedPositions: response?.countLiquidatedPositions, realizedPnlFromPositions: response?.realizedPnlFromPositions, totalFeesPaid: response?.totalFeesPaid, finalPnlAfterFees: response?.finalPnlAfterFees, totalVolumeInUsd: response?.totalVolumeInUsd, totalAccruedBorrowingFeesInUsd: response?.totalAccruedBorrowingFeesInUsd, integratorFeesGenerated: response?.integratorFeesGenerated, orders: response?.orders ? mapResponseToOrderArray(response?.orders) : [], positions: response?.positions ? mapResponseToPositionArray(response?.positions) : [], collateralDeposits: response?.collateralDeposits ? mapResponseToCollateralDepositArray(response?.collateralDeposits) : [] }; } catch (error) { console.log("Error while mapping data", error); return void 0; } }; var mapResponseToSnxAccountArray = (response) => { if (!response) return void 0; try { return response.map((snxAccount) => { return mapResponseToSnxAccount(snxAccount); }); } catch (error) { console.log("Error while mapping data", error); return void 0; } }; var mapResponseToMarket = (response) => { if (!response) return void 0; if (response?.marketName === "" || response?.marketSymbol === "") return void 0; try { return { id: response?.id ?? "", marketName: response?.marketName ?? "", marketSymbol: response?.marketSymbol ?? "", feedId: response?.feedId ?? "", skew: response?.skew ?? "0", size: response?.size ?? "0", maxOpenInterest: response?.maxOpenInterest ?? "0", interestRate: response?.interestRate ?? "0", currentFundingRate: response?.currentFundingRate ?? "0", currentFundingVelocity: response?.currentFundingVelocity ?? "0", indexPrice: response?.indexPrice ?? "0", skewScale: response?.skewScale ?? "0", maxFundingVelocity: response?.maxFundingVelocity ?? "0", makerFee: response?.makerFee ?? "0", takerFee: response?.takerFee ?? "0", maxMarketValue: response?.maxMarketValue ?? "0", maxMarketSize: response?.maxMarketSize ?? "0", marketPrice: response?.marketPrice ?? "0", initialMarginRatioD18: response?.initialMarginRatioD18 ?? "0", maintenanceMarginRatioD18: response?.maintenanceMarginRatioD18 ?? "0", minimumInitialMarginRatioD18: response?.minimumInitialMarginRatioD18 ?? "0", flagRewardRatioD18: response?.flagRewardRatioD18 ?? "0", minimumPositionMargin: response?.minimumPositionMargin ?? "0", openInterestUsd: response?.openInterestUsd ?? "0" }; } catch (error) { console.log("Error while mapping data", error); return void 0; } }; var mapResponseToMarketArray = (response) => { if (!response) return void 0; try { return response.map((market) => { return mapResponseToMarket(market); }); } catch (error) { console.log("Error while mapping data", error); return void 0; } }; var mapResponseToOrder = (response) => { if (!response) return void 0; try { return { id: response?.id, market: response?.market ?? mapResponseToMarket(response?.market), snxAccountId: response?.snxAccount?.id, isLimitOrder: response?.isLimitOrder, acceptablePrice: response?.acceptablePrice, commitmentTime: response?.commitmentTime, expectedPriceTime: response?.expectedPriceTime, settlementTime: response?.settlementTime, expirationTime: response?.expirationTime, trackingCode: response?.trackingCode, deltaSize: response?.deltaSize, deltaSizeUsd: response?.deltaSizeUsd, executionPrice: response?.executionPrice, collectedFees: response?.collectedFees, settlementReward: response?.settlementReward, referralFees: response?.referralFees, partnerAddress: response?.partnerAddress, txHash: response?.txHash, createdTimestamp: response?.createdTimestamp, status: response?.status, settledTxHash: response?.settledTxHash, cancellationTxHash: response?.cancellationTxHash, settledTimestamp: response?.settledTimestamp, settledTimestampISO: response?.settledTimestampISO, settledBy: response?.settledBy ?? mapResponseToWallet(response?.settledBy), snapshotCollateralValueUsd: response?.snapshotCollateralValueUsd }; } catch (error) { console.log("Error while mapping data", error); return void 0; } }; var mapResponseToOrderArray = (response) => { if (!response) return void 0; try { return response.map((order) => { return mapResponseToOrder(order); }); } catch (error) { console.log("Error while mapping data", error); return void 0; } }; function mapResponseToCollateralDeposit(response) { if (!response) return void 0; try { return { id: response?.id, snxAccountId: response?.snxAccountId, collateralId: response?.collateralId, collateralName: response?.collateralName, collateralSymbol: response?.collateralSymbol, collateralDecimals: response?.collateralDecimals, collateralAddress: response?.collateralAddress, currentDepositedAmount: response?.currentDepositedAmount, totalAmountDeposited: response?.totalAmountDeposited, totalAmountWithdrawn: response?.totalAmountWithdrawn, totalAmountLiquidated: response?.totalAmountLiquidated }; } catch (error) { console.log("Error while mapping data", error); return void 0; } } var mapResponseToCollateralDepositArray = (response) => { if (!response) return void 0; try { return response.map((deposit) => { return mapResponseToCollateralDeposit(deposit); }); } catch (error) { console.log("Error while mapping data", error); return void 0; } }; var mapResponseToPosition = (response) => { if (!response) return void 0; try { return { id: response?.id, market: response?.market ?? mapResponseToMarket(response?.market), snxAccountId: response?.snxAccountId, isLong: response?.isLong, positionSize: response?.positionSize, avgPrice: response?.avgPrice, avgPriceDec: response?.avgPriceDec, status: response?.status, txHash: response?.txHash, liquidationTxHash: response?.liquidationTxHash, closingPrice: response?.closingPrice, realizedPositionPnl: response?.realizedPositionPnl, totalFeesPaid: response?.totalFeesPaid, realizedPnlAfterFees: response?.realizedPnlAfterFees, createdTimestamp: response?.createdTimestamp, lastRefresh: response?.lastRefresh, lastRefreshISO: response?.lastRefreshISO, accruedBorrowingFees: response?.accruedBorrowingFees, canBeLiquidated: response?.canBeLiquidated, snapshotCollateralValueUsd: response?.snapshotCollateralValueUsd }; } catch (error) { console.log("Error while mapping data", error); return void 0; } }; var mapResponseToPositionArray = (response) => { if (!response) return void 0; try { return response.map((position) => { return mapResponseToPosition(position); }); } catch (error) { console.log("Error while mapping data", error); return void 0; } }; // src/subgraph/positions/index.ts var getAllPositionsByUserAddress = async (subgraphEndpoint, userAddress, count = 10, skip = 0) => { try { const subgraphResponse = await (0, import_graphql_request2.request)(subgraphEndpoint, fetchPositionsByUserQuery(userAddress, count, skip)); const snxAccounts = mapResponseToSnxAccountArray(subgraphResponse?.snxAccounts); return snxAccounts ?? []; } catch (error) { console.error("Error fetching positions:", error); return []; } }; var getOpenPositionsByUserAddress = async (subgraphEndpoint, userAddress, count = 10, skip = 0) => { try { const subgraphResponse = await (0, import_graphql_request2.request)(subgraphEndpoint, fetchOpenPositionsByUser(userAddress, count, skip)); const snxAccounts = mapResponseToSnxAccountArray(subgraphResponse?.snxAccounts); return snxAccounts ?? []; } catch (error) { console.error("Error fetching positions:", error); return []; } }; var getClosedPositionsByUserAddress = async (subgraphEndpoint, userAddress, count = 10, skip = 0) => { try { const subgraphResponse = await (0, import_graphql_request2.request)( subgraphEndpoint, fetchPositionsByUserQueryAndStatus(userAddress, "CLOSED", count, skip) ); const snxAccounts = mapResponseToSnxAccountArray(subgraphResponse?.snxAccounts); return snxAccounts ?? []; } catch (error) { console.error("Error fetching positions:", error); return []; } }; var getLiquidatedPositionsByUserAddress = async (subgraphEndpoint, userAddress, count = 10, skip = 0) => { try { const subgraphResponse = await (0, import_graphql_request2.request)( subgraphEndpoint, fetchPositionsByUserQueryAndStatus(userAddress, "LIQUIDATED", count, skip) ); const snxAccounts = mapResponseToSnxAccountArray(subgraphResponse?.snxAccounts); return snxAccounts ?? []; } catch (error) { console.error("Error fetching positions:", error); return []; } }; var getPositionById = async (subgraphEndpoint, positionId) => { try { let subgraphResponse = await (0, import_graphql_request2.request)(subgraphEndpoint, fetchPositionByIdQuery(positionId)); console.log("subgraph response:", subgraphResponse); const position = mapResponseToPosition(subgraphResponse?.position); if (position) return position; throw new NotFoundError("Position id not found"); } catch (error) { console.error("Error fetching position:", error); throw new NotFoundError("Position id not found"); } }; var getUserPositionsHistory = async (subgraphEndpoint, userAddress, count = 100, skip = 0) => { try { const subgraphResponse = await (0, import_graphql_request2.request)(subgraphEndpoint, fetchUserPositionHistory(userAddress, count, skip)); const snxAccounts = mapResponseToSnxAccountArray(subgraphResponse?.snxAccounts); return snxAccounts ?? []; } catch (error) { console.error("Error fetching positions:", error); return []; } }; var getUserPositionHistoryWithTime = async (subgraphEndpoint, userAddress, startTime, endTime, count = 100, skip = 0) => { try { const subgraphResponse = await (0, import_graphql_request2.request)( subgraphEndpoint, fetchUserPositionHistoryWithTime(userAddress, startTime, endTime, count, skip) ); const snxAccounts = mapResponseToSnxAccountArray(subgraphResponse?.snxAccounts); return snxAccounts ?? []; } catch (error) { console.error("Error fetching positions:", error); return []; } }; var getUserOpenPositionsWithTime = async (subgraphEndpoint, userAddress, startTime, endTime, count = 10, skip = 0) => { try { const subgraphResponse = await (0, import_graphql_request2.request)( subgraphEndpoint, fetchUserOpenPositionsWithTime(userAddress, startTime, endTime, count, skip) ); const snxAccounts = mapResponseToSnxAccountArray(subgraphResponse?.snxAccounts); return snxAccounts ?? []; } catch (error) { console.error("Error fetching positions:", error); return []; } }; var getUserLiquidatedPositionsBySnxAccount = async (subgraphEndpoint, snxAccountId, lastRefresh) => { let formattedSnxAccountId = snxAccountId; try { if (!snxAccountId.includes("PERP")) { formattedSnxAccountId = "PERP-".concat(snxAccountId); } const subgraphResponse = await (0, import_graphql_request2.request)( subgraphEndpoint, fetchLiquidatedPositionsBySnxAccount(formattedSnxAccountId, lastRefresh) ); const snxAccount = mapResponseToSnxAccount(subgraphResponse?.snxAccount); return snxAccount; } catch (error) { console.error("Error fetching positions:", error); return void 0; } }; var getAllOpenPositionsWithTime = async (subgraphEndpoint, startTime, endTime, count = 10, skip = 0) => { try { const subgraphResponse = await (0, import_graphql_request2.request)( subgraphEndpoint, fetchAllOpenPositionsWithTime(startTime, endTime, count, skip) ); console.log("subgraphresponse", subgraphResponse); const snxAccounts = mapResponseToSnxAccountArray(subgraphResponse?.snxAccounts); return snxAccounts ?? []; } catch (error) { console.error("Error fetching positions:", error); return []; } }; var getAllPositionHistoryWithTime = async (subgraphEndpoint, startTime, endTime, count = 100, skip = 0) => { try { const subgraphResponse = await (0, import_graphql_request2.request)( subgraphEndpoint, fetchAllPositionHistoryWithTime(startTime, endTime, count, skip) ); const snxAccounts = mapResponseToSnxAccountArray(subgraphResponse?.snxAccounts); return snxAccounts ?? []; } catch (error) { console.error("Error fetching positions:", error); return []; } }; // src/perps/positions.ts var import_decimal2 = __toESM(require("decimal.js")); var getProfitOrLossInUsd = (marketPrice, avgPrice, positionSize) => { const profitOrLossPerToken = new import_decimal2.default(marketPrice).minus(avgPrice); return new import_decimal2.default(positionSize).times(profitOrLossPerToken); }; // src/perps/offchain.ts var calculateUnrealizedPnlForPositions = (positions, priceData) => { let totalUnrealizedPnl = DECIMAL_ZERO; positions.forEach((position) => { const currentPrice = getPriceFromPriceArray(priceData, position.market?.feedId); const unrealizedPnl = getProfitOrLossInUsd( currentPrice, convertWeiToEther(position.avgPrice), convertWeiToEther(position.positionSize) ); totalUnrealizedPnl = totalUnrealizedPnl.add(unrealizedPnl); }); return totalUnrealizedPnl; }; var calculateUsdValueOfCollateralDeposits = (collateralDeposits, priceData) => { let totalCollateralValueInUsd = DECIMAL_ZERO; collateralDeposits.forEach((deposit) => { const price = getPriceFromPriceArray(priceData, void 0, deposit.collateralSymbol); const usdValue = convertWeiToEther(deposit.currentDepositedAmount) * price; totalCollateralValueInUsd = totalCollateralValueInUsd.add(usdValue); }); return totalCollateralValueInUsd; }; var getPriceFromPriceArray = (priceData, priceId, tokenSymbol) => { if (!priceId && !tokenSymbol) return 0; if (!priceId) { const formattedSymbol = collateralMappingWithRegularSymbol.get(tokenSymbol?.toLowerCase() || "") || tokenSymbol?.toLowerCase(); priceId = SYMBOL_TO_PYTH_FEED.get(formattedSymbol?.toUpperCase() || ""); } const price = priceId ? priceData.find((p) => p.id === priceId.slice(2))?.price || 0 : 0; console.log("price: ", priceId, price); return price; }; // src/subgraph/portfolio/index.ts var getPortfolioStats = async (subgraphEndpoint, userAddress, priceData) => { const snxAccountPositionData = await getAllPositionsByUserAddress(subgraphEndpoint, userAddress, 100); let collateralDeposits = []; let positionsArray = []; let realizedPnl = DECIMAL_ZERO; snxAccountPositionData.forEach((snxAccount) => { if (snxAccount.collateralDeposits) { collateralDeposits = collateralDeposits.concat(snxAccount.collateralDeposits); } if (snxAccount.positions) { positionsArray = positionsArray.concat(snxAccount.positions); } }); const { openPositions, otherPositions } = splitPositionsByStatus(positionsArray); const unrealizedPnl = calculateUnrealizedPnlForPositions(openPositions, priceData); const collateralValueInUsd = calculateUsdValueOfCollateralDeposits(collateralDeposits, priceData); return { collateralValueInUsd, unrealizedPnl, realizedPnl }; }; var splitPositionsByStatus = (positions) => { const openPositions = []; const otherPositions = []; positions.forEach((position) => { if (position.status === "OPEN") { openPositions.push(position); } else { otherPositions.push(position); } }); return { openPositions, otherPositions }; }; function transformPriceArray(priceArray) { return priceArray.map((obj) => ({ id: obj.id, price: Number(obj.price.price) / 10 ** Math.abs(obj.price.expo) })); } // src/subgraph/markets/index.ts var import_graphql_request4 = require("graphql-request"); // src/subgraph/markets/subgraphQueries.ts var import_graphql_request3 = require("graphql-request"); var fetchAllMarketsDataQuery = import_graphql_request3.gql` { markets { id marketName marketSymbol marketPrice feedId skew size maxOpenInterest maxMarketValue interestRate currentFundingRate currentFundingVelocity indexPrice skewScale maxFundingVelocity makerFee takerFee marketPrice initialMarginRatioD18 minimumPositionMargin maintenanceMarginRatioD18 minimumInitialMarginRatioD18 } } `; var fetchMarketByIdQuery = (marketId) => import_graphql_request3.gql` { market(id: "${marketId}") { id marketName marketSymbol marketPrice feedId skew size maxOpenInterest maxMarketValue interestRate currentFundingRate currentFundingVelocity indexPrice skewScale maxFundingVelocity makerFee takerFee marketPrice initialMarginRatioD18 minimumPositionMargin maintenanceMarginRatioD18 minimumInitialMarginRatioD18 } } `; // src/subgraph/markets/index.ts var getAllMarketsFromSubgraph = async (subgraphEndpoint) => { try { const subgraphResponse = await (0, import_graphql_request4.request)(subgraphEndpoint, fetchAllMarketsDataQuery); if (!subgraphResponse) throw Error(`Error while fetching markets`); const markets = mapResponseToMarketArray(subgraphResponse.markets)?.filter((market) => !!market); if (markets) return markets; throw new NotFoundError("Markets not found"); } catch (error) { console.log("Markets not found. Subgraph request failed", error); return []; } }; var getMarketById = async (subgraphEndpoint, marketId) => { try { const subgraphResponse = await (0, import_graphql_request4.request)(subgraphEndpoint, fetchMarketByIdQuery(marketId)); if (!subgraphResponse) throw Error(`Error while fetching markets`); if (subgraphResponse) { const market = mapResponseToMarket(subgraphResponse.market); if (market && market.id === marketId) { return market; } } throw Error(`Market with Market Id ${marketId} Not Found`); } catch (error) { console.log(`Market with Market Id ${marketId} Not Found`, error); throw error; } }; // src/subgraph/index.ts var import_graphql_request13 = __toESM(require("graphql-request")); // src/subgraph/common/index.ts var import_references = require("@parifi/references"); var import_dotenv = __toESM(require("dotenv")); import_dotenv.default.config(); var publicSubgraphEndpoints = { [import_references.Chain.ARBITRUM_SEPOLIA]: process.env.SUBGRAPH_ENDPOINT || "", [import_references.Chain.ARBITRUM_MAINNET]: "https://api.studio.thegraph.com/query/68480/parifi-arbitrum/version/latest" }; var getPublicSubgraphEndpoint = (chainId) => { return publicSubgraphEndpoints[chainId]; }; // src/pyth/pyth.ts var import_axios = __toESM(require("axios")); var import_decimal3 = __toESM(require("decimal.js")); // src/pyth/pythMapper.ts var mapPythPriceResponseToInterface = (response) => { return response.map((item) => ({ id: item.id || "", price: { price: item.price.price || "0", conf: item.price.conf || "0", expo: item.price.expo || 0, publish_time: item.price.publish_time || 0 }, ema_price: { price: item.ema_price.price || "0", conf: item.ema_price.conf || "0", expo: item.ema_price.expo || 0, publish_time: item.ema_price.publish_time || 0 } })); }; // src/pyth/pyth.ts var getPythClient = async (pythServiceEndpoint, pythServiceUsername, pythServicePassword, isStable = true) => { try { const config = { baseURL: pythServiceEndpoint || (isStable ? "https://hermes.pyth.network" : "https://hermes-beta.pyth.network"), auth: pythServiceUsername && pythServicePassword ? { username: pythServiceUsername, password: pythServicePassword } : void 0 }; return import_axios.default.create(config); } catch (error) { console.log("Error when creating Pyth instance:", error); throw error; } }; var getVaaPriceUpdateData = async (priceIds, pythClient) => { const uniquePriceIds = getUniqueValuesFromArray(priceIds); let priceUpdateData = []; if (pythClient) { try { const response = await pythClient.get("/api/latest_vaas", { params: { ids: uniquePriceIds } }); priceUpdateData = response.data; } catch (error) { console.log("Error fetching data from Pyth", error); throw error; } } return priceUpdateData.map((vaa) => "0x" + Buffer.from(vaa, "base64").toString("hex")); }; var formatPythPrice = (pythPrice, pythExponent) => { const adjustedFactor = new import_decimal3.default(10).pow(pythExponent); return new import_decimal3.default(pythPrice).mul(adjustedFactor); }; var getLatestFormattedPrice = async (priceIds, pythClient) => { let formattedPrices = []; const priceData = await getLatestPricesFromPyth(priceIds, pythClient); priceData.map((pythPrice) => { const formattedPrice = formatPythPrice(Number(pythPrice.price.price), pythPrice.price.expo); formattedPrices.push({ priceId: `0x${pythPrice.id}`, formattedPrice }); }); return formattedPrices; }; var getLatestPricesFromPyth = async (priceIds, pythClient) => { const uniquePriceIds = getUniqueValuesFromArray(priceIds); const pythPriceResponses = []; if (pythClient) { try { const response = await pythClient.get("/api/latest_price_feeds", { params: { ids: uniquePriceIds, verbose: false, binary: false } }); return mapPythPriceResponseToInterface(response.data); } catch (error) { console.log("Error fetching latest prices from Pyth", error); throw error; } } return pythPriceResponses; }; // src/pyth/index.ts var Pyth = class { constructor(pythConfig) { this.pythConfig = pythConfig; this.pythClient = {}; } async initPyth() { this.pythClient = await getPythClient( this.pythConfig.pythEndpoint, this.pythConfig.username, this.pythConfig.password, this.pythConfig.isStable ); } async getVaaPriceUpdateData(priceIds) { return await getVaaPriceUpdateData(priceIds, this.pythClient); } formatPythPrice(pythPrice, pythExponent) { return formatPythPrice(pythPrice, pythExponent); } async getLatestPricesFromPyth(priceIds) { return await getLatestPricesFromPyth(priceIds, this.pythClient); } async getLatestFormattedPrice(priceIds) { return await getLatestFormattedPrice(priceIds, this.pythClient); } }; // src/subgraph/accounts/index.ts var import_decimal4 = __toESM(require("decimal.js")); var import_graphql_request6 = require("graphql-request"); // src/subgraph/accounts/subgraphQueries.ts var import_graphql_request5 = require("graphql-request"); var fetchRealizedPnlData = (userAddress) => import_graphql_request5.gql` { account(id: "${userAddress.toLowerCase()}") { id totalRealizedPnlPositions totalRealizedPnlVaults } } `; var fetchAccountByWalletAddress = (walletAddress) => import_graphql_request5.gql` { wallet(id: "${walletAddress}") { id } } `; var fetchLeaderboardUserData = (userAddresses) => import_graphql_request5.gql` { accounts( where: {id_in: [${userAddresses.map((id) => `"${id}"`).join(", ")}]} ) { id totalOrdersCount totalPositionsCount countProfitablePositions countLossPositions countLiquidatedPositions totalVolumeInUsd totalVolumeInUsdLongs totalVolumeInUsdShorts totalRealizedPnlPositions totalAccruedBorrowingFeesInUsd } }`; var fetchIntegratorFees = (userAddresses) => import_graphql_request5.gql` { snxAccounts(where: { owner_in: [${userAddresses.map((id) => `"${id}"`).join(", ")}], type: PERP }) { id accountId owner { id } integratorFeesGenerated } } `; var checkExistingUser = (userAddress) => import_graphql_request5.gql` { snxAccounts( where: { owner: "${userAddress}", type: PERP, } ) { id accountId totalOrdersCount } } `; var depositedCollateralForSnxAccountsQuery = (accountIds) => import_graphql_request5.gql` { snxAccounts (where :{ accountId_in : [${accountIds.map((id) => `"${id}"`).join(", ")}] }) { owner{ id } accountId collateralDeposits { totalAmountDeposited totalAmountWithdrawn totalAmountLiquidated currentDepositedAmount collateralName collateralSymbol collateralDecimals } } } `; // src/subgraph/accounts/index.ts var getRealizedPnlForUser = async (subgraphEndpoint, userAddress) => { try { const query = fetchRealizedPnlData(userAddress); const subgraphResponse = await (0, import_graphql_request6.request)(subgraphEndpoint, query); const realizedPnlResponse = subgraphResponse; if (realizedPnlResponse === null || realizedPnlResponse.account === null) { console.log("Users Realized Pnl data not found"); return { totalRealizedPnlPositions: DECIMAL_ZERO, totalRealizedPnlVaults: DECIMAL_ZERO }; } const totalRealizedPnlPositions = new import_decimal4.default(realizedPnlResponse.account.totalRealizedPnlPositions); const totalRealizedPnlVaults = new import_decimal4.default(realizedPnlResponse.account.totalRealizedPnlVaults); return { totalRealizedPnlPositions, totalRealizedPnlVaults }; } catch (error) { throw error; } }; var getLeaderboardUserData = async (subgraphEndpoint, userAddresses) => { const subgraphResponse = await (0, import_graphql_request6.request)(subgraphEndpoint, fetchLeaderboardUserData(userAddresses)); const leaderboardUserData = subgraphResponse.accounts; return leaderboardUserData; }; var getAccountByAddress = async (subgraphEndpoint, userAddresses) => { const subgraphResponse = await (0, import_graphql_request6.request)(subgraphEndpoint, fetchAccountByWalletAddress(userAddresses)); if (!subgraphResponse) throw new Error("Error while fetching account data"); return subgraphResponse?.wallet; }; var getFeesByAddress = async (subgraphEndpoint, userAddresses) => { const feesByAddress = /* @__PURE__ */ new Map(); const subgraphResponse = await (0, import_graphql_request6.request)(subgraphEndpoint, fetchIntegratorFees(userAddresses)); if (!subgraphResponse) throw new Error("Error while fetching account data"); const snxAccounts = subgraphResponse?.snxAccounts; snxAccounts.forEach((account) => { const userFees = feesByAddress.get(account.owner.id); if (userFees) { const totalFees = userFees + convertWeiToEther(account.integratorFeesGenerated); feesByAddress.set(account.owner.id, totalFees); } else { feesByAddress.set(account.owner.id, convertWeiToEther(account.integratorFeesGenerated)); } }); return feesByAddress; }; var checkIfExistingUser = async (subgraphEndpoint, userAddress) => { const subgraphResponse = await (0, import_graphql_request6.request)(subgraphEndpoint, checkExistingUser(userAddress)); if (!subgraphResponse) throw new Error("Error while fetching account data"); const snxAccounts = subgraphResponse?.snxAccounts; let isExisting = false; for (let index = 0; index < snxAccounts.length; index++) { if (Number(snxAccounts[index].totalOrdersCount) > 0) { isExisting = true; break; } } return isExisting; }; var depositedCollateralForSnxAccounts = async (subgraphEndpoint, accountIds) => { const subgraphResponse = await (0, import_graphql_request6.request)(subgraphEndpoint, depositedCollateralForSnxAccountsQuery(accountIds)); if (!subgraphResponse) throw new Error("Error while fetching account data"); const snxAccounts = subgraphResponse?.snxAccounts; return snxAccounts; }; // src/subgraph/protocol/index.ts var import_graphql_request8 = __toESM(require("graphql-request")); // src/subgraph/protocol/subgraphQueries.ts var import_graphql_request7 = require("graphql-request"); var fetchProtocolTradeInfo = () => import_graphql_request7.gql` { protocolData(id: "1") { userCount activeUsersCount orderCount settledCount positionCount totalActivePositions referralFeesReceived totalVolume orderTotalFees } } `; // src/subgraph/protocol/index.ts var getProtocolStats = async (subgraphEndpoint) => { const subgraphResponse = await (0, import_graphql_request8.default)(subgraphEndpoint, fetchProtocolTradeInfo()); return subgraphResponse.protocolData; }; // src/subgraph/orders/index.ts var import_graphql_request10 = require("graphql-request"); // src/subgraph/orders/subgraphQueries.ts var import_graphql_request9 = require("graphql-request"); var fetchOrdersByUserQuery = (userAddress, count = 50, skip = 0) => import_graphql_request9.gql`{ snxAccounts( first: ${count} skip: ${skip} where: { owner: "${userAddress}", type: PERP }) { id accountId owner { id } collateralDeposits { id collateralName collateralSymbol collateralDecimals collateralAddress currentDepositedAmount totalAmountDeposited totalAmountWithdrawn totalAmountLiquidated } orders { id market { id marketName marketSymbol feedId } expirationTime