@parifi/sdk
Version:
Parifi SDK with common utility functions
1 lines • 123 kB
Source Map (JSON)
{"version":3,"sources":["../../src/common/constants.ts","../../src/common/helpers.ts","../../src/subgraph/positions/index.ts","../../src/subgraph/positions/subgraphQueries.ts","../../src/error/not-found.error.ts","../../src/common/subgraphMapper.ts","../../src/perps/positions.ts","../../src/perps/offchain.ts","../../src/subgraph/portfolio/index.ts","../../src/subgraph/markets/index.ts","../../src/subgraph/markets/subgraphQueries.ts","../../src/subgraph/index.ts","../../src/subgraph/common/index.ts","../../src/pyth/pyth.ts","../../src/pyth/pythMapper.ts","../../src/pyth/index.ts","../../src/subgraph/accounts/index.ts","../../src/subgraph/accounts/subgraphQueries.ts","../../src/subgraph/protocol/index.ts","../../src/subgraph/protocol/subgraphQueries.ts","../../src/subgraph/orders/index.ts","../../src/subgraph/orders/subgraphQueries.ts","../../src/subgraph/scripts/index.ts","../../src/subgraph/scripts/subgraphQueries.ts"],"sourcesContent":["import { Decimal } from 'decimal.js';\nimport { Address } from 'viem';\n\nexport const PRECISION_MULTIPLIER = new Decimal('10000');\nexport const DEVIATION_PRECISION_MULTIPLIER = new Decimal(10).pow(12);\nexport const SECONDS_IN_A_YEAR = new Decimal(365 * 24 * 60 * 60);\nexport const MAX_FEE = new Decimal(10000000); // 1% = 100_000\nexport const WAD = new Decimal(10).pow(18); // 10^18\nexport const EMPTY_BYTES32 = '0x0000000000000000000000000000000000000000000000000000000000000000';\n// export const PRICE_FEED_DECIMALS = 18;\n// export const PRICE_FEED_PRECISION = new Decimal(10).pow(PRICE_FEED_DECIMALS);\nexport const DECIMAL_10 = new Decimal(10);\nexport const DECIMAL_ZERO = new Decimal(0);\nexport const DEFAULT_BATCH_COUNT = 10;\nexport const BIGINT_ZERO = BigInt(0);\n\nexport const GAS_LIMIT_SETTLEMENT = 10000000; // 10M gas\nexport const GAS_LIMIT_LIQUIDATION = 15000000; // 15M gas\n\nexport const ONE_GWEI = 1000000000; // 10^9\nexport const DEFAULT_GAS_PRICE = 2 * ONE_GWEI; // 1 gwei\n\n// Constants for Pyth price ids of collaterals\nexport const PYTH_ETH_USD_PRICE_ID_BETA = '0xca80ba6dc32e08d06f1aa886011eed1d77c77be9eb761cc10d72b7d0a2fd57a6';\nexport const PYTH_ETH_USD_PRICE_ID_STABLE = '0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace';\n\nexport const PYTH_USDC_USD_PRICE_ID_BETA = '0x41f3625971ca2ed2263e78573fe5ce23e13d2558ed3f2e47ab0f84fb9e7ae722';\nexport const PYTH_USDC_USD_PRICE_ID_STABLE = '0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a';\n\n// Constants for Pimlico relayer\nexport const FACTORY_ADDRESS_SIMPLE_ACCOUNT = '0x91E60e0613810449d098b0b5Ec8b51A0FE8c8985';\n\n// Temporary constants\nexport const SUBGRAPH_HELPER_ADDRESS = '0xf012d32505df6853187170F00C7b789A8ecC41c2';\n\nexport const SYMBOL_TO_PYTH_FEED = new Map<string, string>([\n // market\n ['BTC', '0xc9d8b075a5c69303365ae23633d4e085199bf5c520a3b90fed1322a0342ffc33'],\n ['SOL', '0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d'],\n ['WIF', '0x4ca4beeca86f0d164160323817a4e42b10010a724c2217c6ee41b54cd4cc61fc'],\n ['ETH', '0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace'],\n ['AAVE', '0x2b9ab1e972a281585084148ba1389800799bd4be63b957507db1349314e47445'],\n ['ADA', '0x2a01deaec9e51a579277b34b122399984d0bbf57e2458a7e42fecd2829867a0d'],\n ['ARB', '0x3fa4252848f9f0a1480be62745a4629d9eb1322aebab8a791e344b3b9c1adcf5'],\n ['AVAX', '0x93da3352f9f1d105fdfe4971cfa80e9dd777bfc5d0f683ebb6e1294b92137bb7'],\n ['BCH', '0x3dd2b63686a450ec7290df3a1e0b583c0481f651351edfa7636f39aed55cf8a3'],\n ['BNB', '0x2f95862b045670cd22bee3114c39763a4a08beeb663b145d283c31d7d1101c4f'],\n ['CRV', '0xa19d04ac696c7a6616d291c7e5d1377cc8be437c327b75adb5dc1bad745fcae8'],\n ['DOGE', '0xdcef50dd0a4cd2dcc17e45df1676dcb336a11a61c69df7a0299b0150c672d25c'],\n ['DYDX', '0x6489800bb8974169adfe35937bf6736507097d13c190d760c557108c7e93a81b'],\n ['GMX', '0xb962539d0fcb272a494d65ea56f94851c2bcf8823935da05bd628916e2e9edbf'],\n ['LINK', '0x8ac0c70fff57e9aefdf5edf44b51d62c2d433653cbb2cf5cc06bb115af04d221'],\n ['LTC', '0x6e3f3fa8253588df9326580180233eb791e03b443a3ba7a1d892e73874e19a54'],\n ['MKR', '0x9375299e31c0deb9c6bc378e6329aab44cb48ec655552a70d4b9050346a30378'],\n ['NEAR', '0xc415de8d2eba7db216527dff4b60e8f3a5311c740dadb233e13e12547e226750'],\n ['OP', '0x385f64d993f7b77d8182ed5003d97c60aa3361f3cecfe711544d2d59165e9bdf'],\n ['ORDI', '0x193c739db502aadcef37c2589738b1e37bdb257d58cf1ab3c7ebc8e6df4e3ec0'],\n ['PEPE', '0xd69731a2e74ac1ce884fc3890f7ee324b6deb66147055249568869ed700882e4'],\n ['POL', '0xffd11c5a1cfd42f80afb2df4d9f264c15f956d68153335374ec10722edd70472'],\n ['PYTH', '0x0bbf28e9a841a1cc788f6a361b17ca072d0ea3098a1e5df1c3922d06719579ff'],\n ['RUNE', '0x5fcf71143bb70d41af4fa9aa1287e2efd3c5911cee59f909f915c9f61baacb1e'],\n ['SHIB', '0xf0d57deca57b3da2fe63a493f4c25925fdfd8edf834b20f93e1f84dbd1504d4a'],\n ['STX', '0xec7a775f46379b5e943c3526b1c8d54cd49749176b0b98e02dde68d1bd335c17'],\n ['TIA', '0x09f7c1d7dfbb7df2b8fe3d3d87ee94a2259d212da4f30c1f0540d066dfa44723'],\n ['UNI', '0x78d185a741d07edb3412b09008b7c5cfb9bbbd7d568bf00ba737b456ba171501'],\n ['XLM', '0xb7a8eba68a997cd0210c2e1e4ee811ad2d174b3611c22d9ebf16f4cb7e9ba850'],\n ['XRP', '0xec5d399846a9209f3fe5881d70aae9268c94339ff9817e8d18ff19fa05eea1c8'],\n // collateral\n ['USDC', '0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a'],\n ['USDE', '0x6ec879b1e9963de5ee97e9c8710b742d6228252a5e2ca12d4ae81d7fe5ee8c5d'],\n ['DAI', '0xb0948a5e5313200c632b51bb5ca32f6de0d36e9950a942d19751e833f70dabfd'],\n]);\n\nexport const collateralMappingWithRegularSymbol = new Map<string, string>([\n ['seth', 'eth'],\n ['wbtc', 'btc'],\n ['fbtc', 'btc'],\n ['wsteth', 'eth'],\n ['fdai', 'dai'],\n ['susdc', 'usdc'],\n ['susde', 'usde'],\n ['steth', 'eth'],\n ['fsol', 'sol'],\n ['fusdc', 'usdc'],\n ['fusdt', 'usdt'],\n ['ssol', 'sol'],\n ['sdai', 'dai'],\n ['usdx', 'usdc'],\n ['stbtc', 'btc'],\n]);\n// === TOKEN DISTRIBUTION ===\n\nexport enum SUPPORTED_CHAINS {\n BASE = 8453,\n}\n\nexport const REWARD_DISTRIBUTOR_ADDRESSES: Record<number, Record<string, Address>> = {\n [SUPPORTED_CHAINS.BASE]: {\n esprf: '0x6511718804180CC57833fEA036389A24604Dfc69',\n prf: '0x0000000000000000000000000000000000000000',\n rt: '0x648d6D711860699A11aBa192E9daBAfb6408af18',\n },\n};\n\nexport const REWARD_DISTRIBUTOR_ABI = [\n {\n inputs: [{ internalType: 'contract IERC20', name: '_rewardToken', type: 'address' }],\n stateMutability: 'nonpayable',\n type: 'constructor',\n },\n { inputs: [], name: 'AccessControlBadConfirmation', type: 'error' },\n {\n inputs: [\n { internalType: 'address', name: 'account', type: 'address' },\n { internalType: 'bytes32', name: 'neededRole', type: 'bytes32' },\n ],\n name: 'AccessControlUnauthorizedAccount',\n type: 'error',\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: 'address', name: 'user', type: 'address' },\n { indexed: false, internalType: 'uint256', name: 'amount', type: 'uint256' },\n ],\n name: 'RewardClaimed',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: 'bytes32', name: 'role', type: 'bytes32' },\n { indexed: true, internalType: 'bytes32', name: 'previousAdminRole', type: 'bytes32' },\n { indexed: true, internalType: 'bytes32', name: 'newAdminRole', type: 'bytes32' },\n ],\n name: 'RoleAdminChanged',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: 'bytes32', name: 'role', type: 'bytes32' },\n { indexed: true, internalType: 'address', name: 'account', type: 'address' },\n { indexed: true, internalType: 'address', name: 'sender', type: 'address' },\n ],\n name: 'RoleGranted',\n type: 'event',\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: 'bytes32', name: 'role', type: 'bytes32' },\n { indexed: true, internalType: 'address', name: 'account', type: 'address' },\n { indexed: true, internalType: 'address', name: 'sender', type: 'address' },\n ],\n name: 'RoleRevoked',\n type: 'event',\n },\n {\n inputs: [],\n name: 'DEFAULT_ADMIN_ROLE',\n outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [],\n name: 'actualRound',\n outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n { internalType: 'uint256', name: '_round', type: 'uint256' },\n { internalType: 'uint256', name: 'amount', type: 'uint256' },\n { internalType: 'bytes32[]', name: 'proof', type: 'bytes32[]' },\n ],\n name: 'claimReward',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n { internalType: 'uint256[]', name: '_rounds', type: 'uint256[]' },\n { internalType: 'uint256[]', name: 'amounts', type: 'uint256[]' },\n { internalType: 'bytes32[][]', name: 'proofs', type: 'bytes32[][]' },\n ],\n name: 'claimRewards',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n { internalType: 'uint256', name: '', type: 'uint256' },\n { internalType: 'address', name: '', type: 'address' },\n ],\n name: 'claimed',\n outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [{ internalType: 'bytes32', name: 'role', type: 'bytes32' }],\n name: 'getRoleAdmin',\n outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n { internalType: 'bytes32', name: 'role', type: 'bytes32' },\n { internalType: 'address', name: 'account', type: 'address' },\n ],\n name: 'grantRole',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n { internalType: 'bytes32', name: 'role', type: 'bytes32' },\n { internalType: 'address', name: 'account', type: 'address' },\n ],\n name: 'hasRole',\n outputs: [{ internalType: 'bool', name: '', type: 'bool' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n { internalType: 'bytes32', name: 'role', type: 'bytes32' },\n { internalType: 'address', name: 'callerConfirmation', type: 'address' },\n ],\n name: 'renounceRole',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n { internalType: 'bytes32', name: 'role', type: 'bytes32' },\n { internalType: 'address', name: 'account', type: 'address' },\n ],\n name: 'revokeRole',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [],\n name: 'rewardToken',\n outputs: [{ internalType: 'contract IERC20', name: '', type: 'address' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [{ internalType: 'uint256', name: '_round', type: 'uint256' }],\n name: 'setActualRound',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [\n { internalType: 'uint256', name: '_round', type: 'uint256' },\n { internalType: 'bytes32', name: '_root', type: 'bytes32' },\n ],\n name: 'setRootPerRound',\n outputs: [],\n stateMutability: 'nonpayable',\n type: 'function',\n },\n {\n inputs: [{ internalType: 'bytes4', name: 'interfaceId', type: 'bytes4' }],\n name: 'supportsInterface',\n outputs: [{ internalType: 'bool', name: '', type: 'bool' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],\n name: 'verifiersPerRound',\n outputs: [{ internalType: 'contract Verifier', name: '', type: 'address' }],\n stateMutability: 'view',\n type: 'function',\n },\n];\n","import { Decimal } from 'decimal.js';\nimport { formatEther, parseEther } from 'viem';\n\nexport const getDiff = (a: Decimal, b: Decimal): Decimal => {\n return a.gt(b) ? a.minus(b) : b.minus(a);\n};\n\nexport const addDelay = async (ms: number): Promise<void> => {\n return new Promise((resolve) => setTimeout(resolve, ms));\n};\n\nexport const getCurrentTimestampInSeconds = (): number => {\n return Math.floor(Date.now() / 1000);\n};\n\nexport const getUniqueValuesFromArray = (originalArray: string[]): string[] => {\n const uniqueArray: string[] = [];\n const seenValues = new Set<string>();\n\n originalArray.forEach((item) => {\n // Check if the value is not already seen\n if (!seenValues.has(item)) {\n // Add the value to the uniqueArray\n uniqueArray.push(item);\n // Mark the value as seen in the set\n seenValues.add(item);\n }\n });\n return uniqueArray;\n};\n\nexport function convertWeiToEther(amountInWei: string | bigint | undefined): number {\n if (amountInWei == undefined) {\n throw new Error('Invalid amount received during conversion: undefined');\n }\n if (typeof amountInWei == 'bigint') {\n return Number(formatEther(amountInWei));\n } else if (typeof amountInWei == 'string') {\n return Number(formatEther(BigInt(amountInWei)));\n } else {\n throw new Error('Expected string or bigint for conversion');\n }\n}\n\nexport function convertEtherToWei(amount: string | number | undefined): bigint {\n if (amount == undefined) {\n throw new Error('Invalid amount received during conversion: undefined');\n }\n if (typeof amount == 'number') {\n return parseEther(amount.toString());\n } else if (typeof amount == 'string') {\n return parseEther(amount);\n } else {\n throw new Error('Expected string or bigint for conversion');\n }\n}\n","import { request } from 'graphql-request';\nimport {\n fetchAllOpenPositionsWithTime,\n fetchAllPositionHistoryWithTime,\n fetchLiquidatedPositionsBySnxAccount,\n fetchOpenPositionsByUser,\n fetchPositionByIdQuery,\n fetchPositionsByUserQuery,\n fetchPositionsByUserQueryAndStatus,\n fetchUserOpenPositionsWithTime,\n fetchUserPositionHistory,\n fetchUserPositionHistoryWithTime,\n} from './subgraphQueries';\n\nimport { NotFoundError } from '../../error/not-found.error';\nimport { Position, SnxAccount } from '../../interfaces/sdkTypes';\nimport {\n mapResponseToPosition,\n mapResponseToSnxAccount,\n mapResponseToSnxAccountArray,\n} from '../../common/subgraphMapper';\n\n// Get all positions by user address\nexport const getAllPositionsByUserAddress = async (\n subgraphEndpoint: string,\n userAddress: string,\n count: number = 10,\n skip: number = 0,\n): Promise<SnxAccount[]> => {\n try {\n const subgraphResponse: any = await request(subgraphEndpoint, fetchPositionsByUserQuery(userAddress, count, skip));\n const snxAccounts = mapResponseToSnxAccountArray(subgraphResponse?.snxAccounts);\n return snxAccounts ?? [];\n } catch (error) {\n console.error('Error fetching positions:', error);\n return [];\n }\n};\n\n// Get open positions by user address\nexport const getOpenPositionsByUserAddress = async (\n subgraphEndpoint: string,\n userAddress: string,\n count: number = 10,\n skip: number = 0,\n): Promise<SnxAccount[]> => {\n try {\n const subgraphResponse: any = await request(subgraphEndpoint, fetchOpenPositionsByUser(userAddress, count, skip));\n const snxAccounts = mapResponseToSnxAccountArray(subgraphResponse?.snxAccounts);\n return snxAccounts ?? [];\n } catch (error) {\n console.error('Error fetching positions:', error);\n return [];\n }\n};\n\n// Get open positions by user address\nexport const getClosedPositionsByUserAddress = async (\n subgraphEndpoint: string,\n userAddress: string,\n count: number = 10,\n skip: number = 0,\n): Promise<SnxAccount[]> => {\n try {\n const subgraphResponse: any = await request(\n subgraphEndpoint,\n fetchPositionsByUserQueryAndStatus(userAddress, 'CLOSED', count, skip),\n );\n const snxAccounts = mapResponseToSnxAccountArray(subgraphResponse?.snxAccounts);\n return snxAccounts ?? [];\n } catch (error) {\n console.error('Error fetching positions:', error);\n return [];\n }\n};\n\n// Get LIQUIDATED positions by user address\nexport const getLiquidatedPositionsByUserAddress = async (\n subgraphEndpoint: string,\n userAddress: string,\n count: number = 10,\n skip: number = 0,\n): Promise<SnxAccount[]> => {\n try {\n const subgraphResponse: any = await request(\n subgraphEndpoint,\n fetchPositionsByUserQueryAndStatus(userAddress, 'LIQUIDATED', count, skip),\n );\n const snxAccounts = mapResponseToSnxAccountArray(subgraphResponse?.snxAccounts);\n return snxAccounts ?? [];\n } catch (error) {\n console.error('Error fetching positions:', error);\n return [];\n }\n};\n\n// Get position from subgraph by position ID\nexport const getPositionById = async (subgraphEndpoint: string, positionId: string): Promise<Position> => {\n try {\n let subgraphResponse: any = await request(subgraphEndpoint, fetchPositionByIdQuery(positionId));\n\n console.log('subgraph response:', subgraphResponse);\n const position = mapResponseToPosition(subgraphResponse?.position);\n if (position) return position;\n throw new NotFoundError('Position id not found');\n } catch (error) {\n console.error('Error fetching position:', error);\n throw new NotFoundError('Position id not found');\n }\n};\n\n// Get all positions by user address\nexport const getUserPositionsHistory = async (\n subgraphEndpoint: string,\n userAddress: string,\n count: number = 100,\n skip: number = 0,\n): Promise<SnxAccount[]> => {\n try {\n const subgraphResponse: any = await request(subgraphEndpoint, fetchUserPositionHistory(userAddress, count, skip));\n const snxAccounts = mapResponseToSnxAccountArray(subgraphResponse?.snxAccounts);\n return snxAccounts ?? [];\n } catch (error) {\n console.error('Error fetching positions:', error);\n return [];\n }\n};\n\n// Get positions history by user address\nexport const getUserPositionHistoryWithTime = async (\n subgraphEndpoint: string,\n userAddress: string,\n startTime: number,\n endTime: number,\n count: number = 100,\n skip: number = 0,\n): Promise<SnxAccount[]> => {\n try {\n const subgraphResponse: any = await request(\n subgraphEndpoint,\n fetchUserPositionHistoryWithTime(userAddress, startTime, endTime, count, skip),\n );\n const snxAccounts = mapResponseToSnxAccountArray(subgraphResponse?.snxAccounts);\n return snxAccounts ?? [];\n } catch (error) {\n console.error('Error fetching positions:', error);\n return [];\n }\n};\n\n// Get all open positions by user address\nexport const getUserOpenPositionsWithTime = async (\n subgraphEndpoint: string,\n userAddress: string,\n startTime: number,\n endTime: number,\n count: number = 10,\n skip: number = 0,\n): Promise<SnxAccount[]> => {\n try {\n const subgraphResponse: any = await request(\n subgraphEndpoint,\n fetchUserOpenPositionsWithTime(userAddress, startTime, endTime, count, skip),\n );\n const snxAccounts = mapResponseToSnxAccountArray(subgraphResponse?.snxAccounts);\n return snxAccounts ?? [];\n } catch (error) {\n console.error('Error fetching positions:', error);\n return [];\n }\n};\n\n// Get positions by SNX Account id\nexport const getUserLiquidatedPositionsBySnxAccount = async (\n subgraphEndpoint: string,\n snxAccountId: string,\n lastRefresh: number,\n): Promise<SnxAccount | undefined> => {\n let formattedSnxAccountId = snxAccountId;\n try {\n if (!snxAccountId.includes('PERP')) {\n formattedSnxAccountId = 'PERP-'.concat(snxAccountId);\n }\n const subgraphResponse: any = await request(\n subgraphEndpoint,\n fetchLiquidatedPositionsBySnxAccount(formattedSnxAccountId, lastRefresh),\n );\n const snxAccount = mapResponseToSnxAccount(subgraphResponse?.snxAccount);\n return snxAccount;\n } catch (error) {\n console.error('Error fetching positions:', error);\n return undefined;\n }\n};\n\n// Get all open positions for all users\nexport const getAllOpenPositionsWithTime = async (\n subgraphEndpoint: string,\n startTime: number,\n endTime: number,\n count: number = 10,\n skip: number = 0,\n): Promise<SnxAccount[]> => {\n try {\n const subgraphResponse: any = await request(\n subgraphEndpoint,\n fetchAllOpenPositionsWithTime(startTime, endTime, count, skip),\n );\n console.log('subgraphresponse', subgraphResponse);\n const snxAccounts = mapResponseToSnxAccountArray(subgraphResponse?.snxAccounts);\n return snxAccounts ?? [];\n } catch (error) {\n console.error('Error fetching positions:', error);\n return [];\n }\n};\n\n// Get positions history by user address\nexport const getAllPositionHistoryWithTime = async (\n subgraphEndpoint: string,\n startTime: number,\n endTime: number,\n count: number = 100,\n skip: number = 0,\n): Promise<SnxAccount[]> => {\n try {\n const subgraphResponse: any = await request(\n subgraphEndpoint,\n fetchAllPositionHistoryWithTime(startTime, endTime, count, skip),\n );\n const snxAccounts = mapResponseToSnxAccountArray(subgraphResponse?.snxAccounts);\n return snxAccounts ?? [];\n } catch (error) {\n console.error('Error fetching positions:', error);\n return [];\n }\n};\n","import { gql } from 'graphql-request';\n\n// Fetches all positions by a user (Both open and closed)\nexport const fetchPositionsByUserQuery = (userAddress: string, count: number = 20, skip: number = 0) =>\n gql`\n {\n snxAccounts(\n first: ${count}\n skip: ${skip}\n where: { owner: \"${userAddress}\", type: PERP }) {\n id\n accountId\n owner {\n id\n }\n collateralDeposits {\n id\n collateralName\n collateralSymbol\n collateralDecimals\n collateralAddress\n currentDepositedAmount\n totalAmountDeposited\n totalAmountWithdrawn\n totalAmountLiquidated\n }\n positions(where: {status_in: [OPEN, CLOSED, LIQUIDATED]}) {\n id\n market {\n id\n marketName\n marketSymbol\n feedId\n }\n positionSize\n avgPrice\n avgPriceDec\n isLong\n createdTimestamp\n status\n txHash\n liquidationTxHash\n closingPrice\n realizedPositionPnl\n realizedPnlAfterFees\n totalFeesPaid\n createdTimestamp\n lastRefresh\n lastRefreshISO\n canBeLiquidated\n snapshotCollateralValueUsd\n }\n }\n }`;\n\n// Fetches positions for a user address by status\nexport const fetchPositionsByUserQueryAndStatus = (\n userAddress: string,\n status: string,\n count: number = 20,\n skip: number = 0,\n) =>\n gql`\n {\n snxAccounts(\n first: ${count}\n skip: ${skip}\n where: { owner: \"${userAddress}\", type: PERP }\n ) {\n id\n accountId\n owner {\n id\n }\n collateralDeposits {\n id\n collateralName\n collateralSymbol\n collateralDecimals\n collateralAddress\n currentDepositedAmount\n totalAmountDeposited\n totalAmountWithdrawn\n totalAmountLiquidated\n }\n positions(where: {status: ${status} }) {\n id\n market {\n id\n marketName\n marketSymbol\n feedId\n }\n positionSize\n avgPrice\n avgPriceDec\n isLong\n createdTimestamp\n status\n txHash\n liquidationTxHash\n closingPrice\n realizedPositionPnl\n realizedPnlAfterFees\n totalFeesPaid\n createdTimestamp\n lastRefresh\n lastRefreshISO\n canBeLiquidated\n snapshotCollateralValueUsd\n }\n }\n }`;\n\n// Fetches open positions for a user address\nexport const fetchOpenPositionsByUser = (userAddress: string, count: number = 20, skip: number = 0) =>\n gql`\n {\n snxAccounts(\n first: ${count}\n skip: ${skip}\n where: {\n owner: \"${userAddress}\",\n type: PERP,\n openPositionCount_gt: 0\n }\n ) {\n id\n accountId\n owner {\n id\n }\n collateralDeposits {\n id\n collateralName\n collateralSymbol\n collateralDecimals\n collateralAddress\n currentDepositedAmount\n totalAmountDeposited\n totalAmountWithdrawn\n totalAmountLiquidated\n }\n positions(where: {status: OPEN }) {\n id\n market {\n id\n marketName\n marketSymbol\n feedId\n }\n positionSize\n avgPrice\n avgPriceDec\n isLong\n createdTimestamp\n status\n txHash\n liquidationTxHash\n closingPrice\n realizedPositionPnl\n realizedPnlAfterFees\n totalFeesPaid\n createdTimestamp\n lastRefresh\n lastRefreshISO\n canBeLiquidated\n snapshotCollateralValueUsd\n }\n }\n }`;\n\n// Fetches positions for a user address by status\nexport const fetchUserPositionHistory = (userAddress: string, count: number = 20, skip: number = 0) =>\n gql`\n {\n snxAccounts(\n first: ${count}\n skip: ${skip}\n where: { owner: \"${userAddress}\", type: PERP }\n ) {\n id\n accountId\n owner {\n id\n }\n collateralDeposits {\n id\n collateralName\n collateralSymbol\n collateralDecimals\n collateralAddress\n currentDepositedAmount\n totalAmountDeposited\n totalAmountWithdrawn\n totalAmountLiquidated\n }\n positions(where: {status_in: [CLOSED, LIQUIDATED]}) {\n id\n market {\n id\n marketName\n marketSymbol\n feedId\n }\n positionSize\n avgPrice\n avgPriceDec\n isLong\n createdTimestamp\n status\n txHash\n liquidationTxHash\n closingPrice\n realizedPositionPnl\n realizedPnlAfterFees\n totalFeesPaid\n createdTimestamp\n lastRefresh\n lastRefreshISO\n canBeLiquidated\n snapshotCollateralValueUsd\n }\n }\n }`;\n\nexport const fetchPositionByIdQuery = (positionId: string) =>\n gql`\n {\n position(\n id: \"${positionId}\"\n ) {\n id\n market {\n id,\n marketName,\n marketSymbol,\n feedId \n }\n snxAccount{\n id\n accountId\n }\n isLong\n positionSize\n avgPrice\n avgPriceDec\n status\n txHash\n liquidationTxHash\n closingPrice\n realizedPositionPnl\n realizedPnlAfterFees\n totalFeesPaid\n createdTimestamp\n lastRefresh\n lastRefreshISO\n canBeLiquidated\n snapshotCollateralValueUsd\n }\n }`;\n\nexport const fetchPositionsToLiquidateQuery = (count: number) => gql`\n {\n positions(where: { status: OPEN, canBeLiquidated: true }, first: ${count}, orderBy: positionSize, orderDirection: desc) {\n id\n }\n }\n`;\n\n// Fetches positions for a user address by status\nexport const fetchUserPositionHistoryWithTime = (\n userAddress: string,\n startTimestamp: number,\n endTimestamp: number,\n count: number = 20,\n skip: number = 0,\n) =>\n gql`\n {\n snxAccounts(\n first: ${count}\n skip: ${skip}\n where: {\n owner: \"${userAddress}\",\n type: PERP\n }\n ) {\n id\n accountId\n owner {\n id\n }\n collateralDeposits {\n id\n collateralName\n collateralSymbol\n collateralDecimals\n collateralAddress\n currentDepositedAmount\n totalAmountDeposited\n totalAmountWithdrawn\n totalAmountLiquidated\n }\n positions( where: {\n status_in: [CLOSED, LIQUIDATED],\n createdTimestamp_gte: ${startTimestamp}\n createdTimestamp_lte: ${endTimestamp}\n }) {\n id\n market {\n id\n marketName\n marketSymbol\n feedId\n }\n positionSize\n positionCollateral\n avgPrice\n avgPriceDec\n isLong\n createdTimestamp\n status\n txHash\n liquidationTxHash\n closingPrice\n realizedPositionPnl\n realizedPnlAfterFees\n totalFeesPaid\n createdTimestamp\n lastRefresh\n lastRefreshISO\n canBeLiquidated\n snapshotCollateralValueUsd\n }\n }\n }`;\n\n// Fetches positions for a user address by status\nexport const fetchUserOpenPositionsWithTime = (\n userAddress: string,\n startTimestamp: number,\n endTimestamp: number,\n count: number = 20,\n skip: number = 0,\n) =>\n gql`\n {\n snxAccounts(\n first: ${count}\n skip: ${skip}\n where: {\n owner: \"${userAddress}\",\n type: PERP,\n positions_: {\n status: OPEN,\n createdTimestamp_gte: ${startTimestamp}\n createdTimestamp_lte: ${endTimestamp}\n }\n }\n ) {\n id\n accountId\n owner {\n id\n }\n collateralDeposits {\n id\n collateralName\n collateralSymbol\n collateralDecimals\n collateralAddress\n currentDepositedAmount\n totalAmountDeposited\n totalAmountWithdrawn\n totalAmountLiquidated\n }\n positions {\n id\n market {\n id\n marketName\n marketSymbol\n feedId\n }\n positionSize\n avgPrice\n avgPriceDec\n isLong\n createdTimestamp\n status\n txHash\n liquidationTxHash\n closingPrice\n realizedPositionPnl\n realizedPnlAfterFees\n totalFeesPaid\n createdTimestamp\n lastRefresh\n lastRefreshISO\n canBeLiquidated\n snapshotCollateralValueUsd\n }\n }\n }`;\n\nexport const fetchLiquidatedPositionsBySnxAccount = (snxAccountId: string, lastRefresh: number) =>\n gql`\n {\n snxAccount(id: \"${snxAccountId}\"\n ) {\n id\n accountId\n owner {\n id\n }\n collateralDeposits {\n id\n collateralName\n collateralSymbol\n collateralDecimals\n collateralAddress\n currentDepositedAmount\n totalAmountDeposited\n totalAmountWithdrawn\n totalAmountLiquidated\n }\n positions(where: { status: LIQUIDATED, lastRefresh_gt: ${lastRefresh} }) {\n id\n market {\n id\n marketName\n marketSymbol\n feedId\n }\n positionSize\n avgPrice\n avgPriceDec\n isLong\n createdTimestamp\n status\n txHash\n liquidationTxHash\n closingPrice\n realizedPositionPnl\n realizedPnlAfterFees\n totalFeesPaid\n createdTimestamp\n lastRefresh\n lastRefreshISO\n canBeLiquidated\n snapshotCollateralValueUsd\n }\n }\n }`;\n\nexport const fetchCrossMarginPositionsBySnxAccount = (snxAccountId: string, lastRefresh: number) => gql`\n {\n snxAccount(id: \"${snxAccountId}\") {\n accountId\n collateralDeposits {\n totalAmountLiquidated\n }\n positions(where: { status: LIQUIDATED, lastRefresh_gt: ${lastRefresh} }) {\n lastRefresh\n }\n }\n }\n`;\n\n// Fetches positions for a user address by status\nexport const fetchAllOpenPositionsWithTime = (\n startTimestamp: number,\n endTimestamp: number,\n count: number = 20,\n skip: number = 0,\n) =>\n gql`\n {\n snxAccounts(\n first: ${count}\n skip: ${skip}\n where: { \n type: PERP\n openPositionCount_gt:0\n }\n ) {\n id\n accountId\n owner {\n id\n }\n collateralDeposits {\n id\n collateralName\n collateralSymbol\n collateralDecimals\n collateralAddress\n currentDepositedAmount\n totalAmountDeposited\n totalAmountWithdrawn\n totalAmountLiquidated\n }\n positions(where: {\n status: OPEN,\n createdTimestamp_gte: ${startTimestamp}\n createdTimestamp_lte: ${endTimestamp}\n }) \n {\n id\n market {\n id\n marketName\n marketSymbol\n feedId\n }\n positionSize\n avgPrice\n avgPriceDec\n isLong\n createdTimestamp\n status\n txHash\n liquidationTxHash\n closingPrice\n realizedPositionPnl\n realizedPnlAfterFees\n totalFeesPaid\n createdTimestamp\n lastRefresh\n lastRefreshISO\n canBeLiquidated\n snapshotCollateralValueUsd\n }\n }\n }`;\n\n// Fetches positions for a user address by status\nexport const fetchAllPositionHistoryWithTime = (\n startTimestamp: number,\n endTimestamp: number,\n count: number = 20,\n skip: number = 0,\n) =>\n gql`\n {\n snxAccounts(\n first: ${count}\n skip: ${skip}\n where: {\n type: PERP\n totalPositionsCount_gt :0\n }\n ) {\n id\n accountId\n owner {\n id\n }\n collateralDeposits {\n id\n collateralName\n collateralSymbol\n collateralDecimals\n collateralAddress\n currentDepositedAmount\n totalAmountDeposited\n totalAmountWithdrawn\n totalAmountLiquidated\n }\n positions(where: {\n status_in: [CLOSED, LIQUIDATED],\n createdTimestamp_gte: ${startTimestamp}\n createdTimestamp_lte: ${endTimestamp}\n }) {\n id\n market {\n id\n marketName\n marketSymbol\n feedId\n }\n positionSize\n avgPrice\n avgPriceDec\n isLong\n createdTimestamp\n status\n txHash\n liquidationTxHash\n closingPrice\n realizedPositionPnl\n realizedPnlAfterFees\n totalFeesPaid\n createdTimestamp\n lastRefresh\n lastRefreshISO\n canBeLiquidated\n snapshotCollateralValueUsd\n }\n }\n }`;\n","export class NotFoundError extends Error {\n constructor(message: string) {\n super(message);\n this.name = this.constructor.name;\n }\n}","import { PriceFeedSnapshot, PythData } from '../interfaces/subgraphTypes';\nimport { CollateralDeposit, Market, Order, Position, SnxAccount, Token, Wallet } from '../interfaces/sdkTypes';\n\n////////////////////////////////////////////////////////////////\n////////////////////// Wallet ////////////////////////////\n////////////////////////////////////////////////////////////////\n\nexport const mapResponseToWallet = (response: any): Wallet | undefined => {\n if (!response) return undefined;\n try {\n return {\n id: response?.id,\n // snxAccounts: mapSnxAccountsArray(response.snxAccounts)\n };\n } catch (error) {\n console.log('Error while mapping data', error);\n return undefined;\n }\n};\n\nexport const mapResponseToWalletArray = (response: any): Wallet[] | undefined => {\n if (!response) return undefined;\n try {\n return response.map((account: any) => {\n return mapResponseToWallet(account);\n });\n } catch (error) {\n console.log('Error while mapping data', error);\n return undefined;\n }\n};\n\n////////////////////////////////////////////////////////////////\n////////////////////// SNX Account ////////////////////////\n////////////////////////////////////////////////////////////////\n\nexport const mapResponseToSnxAccount = (response: any): SnxAccount | undefined => {\n if (!response) return undefined;\n\n try {\n return {\n id: response?.id,\n type: response?.type,\n accountId: response?.accountId,\n owner: response?.owner ?? mapResponseToWallet(response?.owner),\n totalOrdersCount: response?.totalOrdersCount,\n totalPositionsCount: response?.totalPositionsCount,\n openPositionCount: response?.openPositionCount,\n countProfitablePositions: response?.countProfitablePositions,\n countLossPositions: response?.countLossPositions,\n countLiquidatedPositions: response?.countLiquidatedPositions,\n realizedPnlFromPositions: response?.realizedPnlFromPositions,\n totalFeesPaid: response?.totalFeesPaid,\n finalPnlAfterFees: response?.finalPnlAfterFees,\n totalVolumeInUsd: response?.totalVolumeInUsd,\n totalAccruedBorrowingFeesInUsd: response?.totalAccruedBorrowingFeesInUsd,\n integratorFeesGenerated: response?.integratorFeesGenerated,\n orders: response?.orders ? mapResponseToOrderArray(response?.orders) : [],\n positions: response?.positions ? mapResponseToPositionArray(response?.positions) : [],\n collateralDeposits: response?.collateralDeposits\n ? mapResponseToCollateralDepositArray(response?.collateralDeposits)\n : [],\n };\n } catch (error) {\n console.log('Error while mapping data', error);\n return undefined;\n }\n};\n\nexport const mapResponseToSnxAccountArray = (response: any): SnxAccount[] | undefined => {\n if (!response) return undefined;\n try {\n return response.map((snxAccount: any) => {\n return mapResponseToSnxAccount(snxAccount);\n });\n } catch (error) {\n console.log('Error while mapping data', error);\n return undefined;\n }\n};\n\n////////////////////////////////////////////////////////////////\n////////////////////// MARKET ////////////////////////////\n////////////////////////////////////////////////////////////////\n\nexport const mapResponseToMarket = (response: any): Market | undefined => {\n if (!response) return undefined;\n if (response?.marketName === '' || response?.marketSymbol === '') return undefined;\n try {\n return {\n id: response?.id ?? '',\n marketName: response?.marketName ?? '',\n marketSymbol: response?.marketSymbol ?? '',\n feedId: response?.feedId ?? '',\n skew: response?.skew ?? '0',\n size: response?.size ?? '0',\n maxOpenInterest: response?.maxOpenInterest ?? '0',\n interestRate: response?.interestRate ?? '0',\n currentFundingRate: response?.currentFundingRate ?? '0',\n currentFundingVelocity: response?.currentFundingVelocity ?? '0',\n indexPrice: response?.indexPrice ?? '0',\n skewScale: response?.skewScale ?? '0',\n maxFundingVelocity: response?.maxFundingVelocity ?? '0',\n makerFee: response?.makerFee ?? '0',\n takerFee: response?.takerFee ?? '0',\n maxMarketValue: response?.maxMarketValue ?? '0',\n maxMarketSize: response?.maxMarketSize ?? '0',\n marketPrice: response?.marketPrice ?? '0',\n initialMarginRatioD18: response?.initialMarginRatioD18 ?? '0',\n maintenanceMarginRatioD18: response?.maintenanceMarginRatioD18 ?? '0',\n minimumInitialMarginRatioD18: response?.minimumInitialMarginRatioD18 ?? '0',\n flagRewardRatioD18: response?.flagRewardRatioD18 ?? '0',\n minimumPositionMargin: response?.minimumPositionMargin ?? '0',\n openInterestUsd: response?.openInterestUsd ?? '0',\n };\n } catch (error) {\n console.log('Error while mapping data', error);\n return undefined;\n }\n};\n\nexport const mapResponseToMarketArray = (response: any): (Market | undefined)[] | undefined => {\n if (!response) return undefined;\n try {\n return response.map((market: any) => {\n return mapResponseToMarket(market);\n });\n } catch (error) {\n console.log('Error while mapping data', error);\n return undefined;\n }\n};\n\n////////////////////////////////////////////////////////////////\n////////////////////// ORDERS ////////////////////////////\n////////////////////////////////////////////////////////////////\n\nexport const mapResponseToOrder = (response: any): Order | undefined => {\n if (!response) return undefined;\n try {\n return {\n id: response?.id,\n market: response?.market ?? mapResponseToMarket(response?.market),\n snxAccountId: response?.snxAccount?.id,\n isLimitOrder: response?.isLimitOrder,\n acceptablePrice: response?.acceptablePrice,\n commitmentTime: response?.commitmentTime,\n expectedPriceTime: response?.expectedPriceTime,\n settlementTime: response?.settlementTime,\n expirationTime: response?.expirationTime,\n trackingCode: response?.trackingCode,\n deltaSize: response?.deltaSize,\n deltaSizeUsd: response?.deltaSizeUsd,\n executionPrice: response?.executionPrice,\n collectedFees: response?.collectedFees,\n settlementReward: response?.settlementReward,\n referralFees: response?.referralFees,\n partnerAddress: response?.partnerAddress,\n txHash: response?.txHash,\n createdTimestamp: response?.createdTimestamp,\n status: response?.status,\n settledTxHash: response?.settledTxHash,\n cancellationTxHash: response?.cancellationTxHash,\n settledTimestamp: response?.settledTimestamp,\n settledTimestampISO: response?.settledTimestampISO,\n settledBy: response?.settledBy ?? mapResponseToWallet(response?.settledBy),\n snapshotCollateralValueUsd: response?.snapshotCollateralValueUsd,\n };\n } catch (error) {\n console.log('Error while mapping data', error);\n return undefined;\n }\n};\n\nexport const mapResponseToOrderArray = (response: any): Order[] | undefined => {\n if (!response) return undefined;\n try {\n return response.map((order: any) => {\n return mapResponseToOrder(order);\n });\n } catch (error) {\n console.log('Error while mapping data', error);\n return undefined;\n }\n};\n\n////////////////////////////////////////////////////////////////\n//////////////////// Collaterals //////////////////////////\n////////////////////////////////////////////////////////////////\n\nfunction mapResponseToCollateralDeposit(response: any): CollateralDeposit | undefined {\n if (!response) return undefined;\n try {\n return {\n id: response?.id,\n snxAccountId: response?.snxAccountId,\n collateralId: response?.collateralId,\n collateralName: response?.collateralName,\n collateralSymbol: response?.collateralSymbol,\n collateralDecimals: response?.collateralDecimals,\n collateralAddress: response?.collateralAddress,\n currentDepositedAmount: response?.currentDepositedAmount,\n totalAmountDeposited: response?.totalAmountDeposited,\n totalAmountWithdrawn: response?.totalAmountWithdrawn,\n totalAmountLiquidated: response?.totalAmountLiquidated,\n };\n } catch (error) {\n console.log('Error while mapping data', error);\n return undefined;\n }\n}\n\nexport const mapResponseToCollateralDepositArray = (response: any): CollateralDeposit[] | undefined => {\n if (!response) return undefined;\n try {\n return response.map((deposit: any) => {\n return mapResponseToCollateralDeposit(deposit);\n });\n } catch (error) {\n console.log('Error while mapping data', error);\n return undefined;\n }\n};\n\n////////////////////////////////////////////////////////////////\n////////////////////// POSITION //////////////////////////\n////////////////////////////////////////////////////////////////\n\nexport const mapResponseToPosition = (response: any): Position | undefined => {\n if (!response) return undefined;\n try {\n return {\n id: response?.id,\n market: response?.market ?? mapResponseToMarket(response?.market),\n snxAccountId: response?.snxAccountId,\n isLong: response?.isLong,\n positionSize: response?.positionSize,\n avgPrice: response?.avgPrice,\n avgPriceDec: response?.avgPriceDec,\n status: response?.status,\n txHash: response?.txHash,\n liquidationTxHash: response?.liquidationTxHash,\n closingPrice: response?.closingPrice,\n realizedPositionPnl: response?.realizedPositionPnl,\n totalFeesPaid: response?.totalFeesPaid,\n realizedPnlAfterFees: response?.realizedPnlAfterFees,\n createdTimestamp: response?.createdTimestamp,\n lastRefresh: response?.lastRefresh,\n lastRefreshISO: response?.lastRefreshISO,\n accruedBorrowingFees: response?.accruedBorrowingFees,\n canBeLiquidated: response?.canBeLiquidated,\n snapshotCollateralValueUsd: response?.snapshotCollateralValueUsd,\n };\n } catch (error) {\n console.log('Error while mapping data', error);\n return undefined;\n }\n};\n\nexport const mapResponseToPositionArray = (response: any): Position[] | undefined => {\n if (!response) return undefined;\n\n try {\n return response.map((position: any) => {\n return mapResponseToPosition(position);\n });\n } catch (error) {\n console.log('Error while mapping data', error);\n return undefined;\n }\n};\n\n////////////////////////////////////////////////////////////////\n////////////////////// TOKEN /////////////////////////////\n////////////////////////////////////////////////////////////////\n\nexport const mapResponseToToken = (response: any): Token | undefined => {\n if (!response) return undefined;\n\n try {\n return {\n id: response?.id,\n name: response?.name,\n symbol: response?.symbol,\n decimals: response?.decimals,\n lastPriceUSD: response?.lastPriceUSD,\n lastPriceTimestamp: response?.lastPriceTimestamp,\n };\n } catch (error) {\n console.log('Error while mapping data', error);\n return undefined;\n }\n};\n\n////////////////////////////////////////////////////////////////\n//////////////////////// PYTH ////////////////////////////\n////////////////////////////////////////////////////////////////\n\nexport const mapResponseToPriceFeedSnapshot = (response: any): PriceFeedSnapshot | undefined => {\n if (!response) return undefined;\n\n try {\n return {\n id: response?.id,\n priceId: response?.priceId,\n publishTime: response?.publishTime,\n price: response?.price,\n confidence: response?.confidence,\n };\n } catch (error) {\n console.log('Error while mapping data', error);\n return undefined;\n }\n};\n\nexport const mapResponseToPythData = (response: any): PythData | undefined => {\n if (!response) return undefined;\n\n try {\n return {\n id: response?.id,\n marketId: response?.marketId,\n tokenAddress: response?.tokenAddress,\n price: response?.price,\n lastUpdatedTimestamp: response?.lastUpdatedTimestamp,\n };\n } catch (error) {\n console.log('Error while mapping data', error);\n return undefined;\n }\n};\n","import Decimal from 'decimal.js';\n\n// Calculates the Profit/Loss of the position given marketPrice and avgPrice\n// @param positionSize is negative for a short position and positive for Long position\nexport const getProfitOrLossInUsd = (marketPrice: number, avgPrice: number, positionSize: number): Decimal => {\n const profitOrLossPerToken = new Decimal(marketPrice).minus(avgPrice);\n return new Decimal(positionSize).times(profitOrLossPerToken);\n};\n\n// Calculates the formatted position size using collateral and leverage\n// using equation: Size = Collateral * Leverage\nexport const calculateSizeFromCollateralAndLeverage = (\n collateralValueInUsd: number,\n leverage: number,\n marketPrice: number,\n): Decimal => {\n const sizeInUsd = new Decimal(collateralValueInUsd).times(leverage);\n return sizeInUsd.div(marketPrice);\n};\n\n// Calculates the Collateral amount using size and leverage values\n// using equation: Collateral = Size / Leverage\nexport const calculateCollateralFromSizeAndLeverage = (\n sizeInUsd: number,\n leverage: number,\n collateralPrice: number,\n): Decimal => {\n const collateralInUsd = new Decimal(sizeInUsd).div(leverage);\n return collateralInUsd.div(collateralPrice);\n};\n\n// Calculates the leverage value of a position using size and collateral values\n// using equation: Leverage = Size / Collateral\nexport const calculateLeverageFromCollateralAndSize = (collateralValueInUsd: number, sizeInUsd: number): number => {\n return sizeInUsd / collateralValueInUsd;\n};\n","import Decimal from 'decimal.js';\nimport { CollateralDeposit, Position } from '../interfaces';\nimport { collateralMappingWithRegularSymbol, convertWeiToEther, DECIMAL_ZERO, SYMBOL_TO_PYTH_FEED } from '../common';\nimport { getProfitOrLossInUsd } from './positions';\n\n// Calculates the unrealized pnl in USD for an array of positions off-chain\n// using the provided position array and price data\nexport const calculateUnrealizedPnlForPositions = (\n positions: Position[],\n priceData: { id: string; price: number }[],\n): Decimal => {\n let totalUnrealizedPnl = DECIMAL_ZERO;\n positions.forEach((position) => {\n const currentPrice = getPriceFromPriceArray(priceData, position.market?.feedId);\n const unrealizedPnl = getProfitOrLossInUsd(\n currentPrice,\n convertWeiToEther(position.avgPrice),\n convertWeiToEther(position.positionSize),\n );\n totalUnrealizedPnl = totalUnrealizedPnl.add(unreali