UNPKG

@0xsplits/splits-sdk

Version:

SDK for the 0xSplits protocol

287 lines (267 loc) 7.47 kB
import { gql } from '@urql/core' import { formatGqlContractEarnings, formatInternalTokenBalances, formatTokenBalances, } from './token' import { GqlOracle, GqlSwapBalance, GqlSwapper, IChainlinkPairDetails, IOracle, ISwapBalance, ISwapper, ISwapperScaledOfferFactorOverrides, IUniswapV3TWAPPairDetails, } from './types' import { getAddress, zeroAddress } from 'viem' import { ZERO } from '../constants' import { SupportedChainId } from './constants' import { getSwapBalanceId } from '../utils' import { Swapper } from '../types' const UNISWAP_V3_TWAP_ORACLE_FIELDS_FRAGMENT = gql` fragment UniswapV3TwapOracleFieldsFragment on UniswapV3TWAPOracle { paused defaultPeriod pairDetails { base { id } quote { id } pool fee period } } ` const CHAINLINK_ORACLE_FIELDS_FRAGMENT = gql` fragment ChainlinkOracleFieldsFragment on ChainlinkOracle { paused sequencerFeed chainlinkPairDetails { base { id } quote { id } inverted feeds { aggregatorV3 decimals staleAfter mul } } } ` export const ORACLE_FIELDS_FRAGMENT = gql` fragment OracleFieldsFragment on Oracle { id type ... on UniswapV3TWAPOracle { ...UniswapV3TwapOracleFieldsFragment } ... on ChainlinkOracle { ...ChainlinkOracleFieldsFragment } } ${UNISWAP_V3_TWAP_ORACLE_FIELDS_FRAGMENT} ${CHAINLINK_ORACLE_FIELDS_FRAGMENT} ` const SWAP_BALANCE_FIELDS_FRAGMENT = gql` fragment SwapBalanceFieldsFragment on SwapBalance { inputToken { id } inputAmount outputToken { id } outputAmount } ` export const SWAPPER_FIELDS_FRAGMENT = gql` fragment SwapperFieldsFragment on Swapper { owner { id } paused beneficiary { id } tokenToBeneficiary { id } oracle { ...OracleFieldsFragment } defaultScaledOfferFactor scaledOfferFactorPairOverrides { base { id } quote { id } scaledOfferFactor } swapperSwapBalances: swapBalances { ...SwapBalanceFieldsFragment } } ${ORACLE_FIELDS_FRAGMENT} ${SWAP_BALANCE_FIELDS_FRAGMENT} ` export const formatGqlOracle: (arg0: GqlOracle) => IOracle = (gqlOracle) => { if (gqlOracle.type === 'uniswapV3TWAP') return { address: getAddress(gqlOracle.id), type: gqlOracle.type, defaultPeriod: parseInt(gqlOracle.defaultPeriod), pairDetails: gqlOracle.pairDetails?.reduce((acc, pairDetail) => { const base = getAddress(pairDetail.base.id) const quote = getAddress(pairDetail.quote.id) const pairId = getSwapBalanceId(base, quote) acc[pairId] = { base, quote, pool: getAddress(pairDetail.pool), fee: pairDetail.fee, period: parseInt(pairDetail.period), } const reversePairId = getSwapBalanceId(quote, base) acc[reversePairId] = { base: quote, quote: base, pool: getAddress(pairDetail.pool), fee: pairDetail.fee, period: parseInt(pairDetail.period), } return acc }, {} as IUniswapV3TWAPPairDetails), } else if (gqlOracle.type === 'chainlink') return { address: getAddress(gqlOracle.id), type: gqlOracle.type, chainlinkPairDetails: gqlOracle.chainlinkPairDetails.reduce( (acc, pairDetail) => { const base = getAddress(pairDetail.base.id) const quote = getAddress(pairDetail.quote.id) const pairId = getSwapBalanceId(base, quote) acc[pairId] = { base, quote, } return acc }, {} as IChainlinkPairDetails, ), } return { address: getAddress(gqlOracle.id), type: gqlOracle.type, } } const formatSwapBalances: (arg0: GqlSwapBalance[]) => ISwapBalance = ( gqlSwapBalances, ) => { return gqlSwapBalances.reduce((acc, swapBalance) => { const inputToken = getAddress(swapBalance.inputToken.id) const outputToken = getAddress(swapBalance.outputToken.id) const inputAmount = BigInt(swapBalance.inputAmount) const outputAmount = BigInt(swapBalance.outputAmount) const swapBalanceId = getSwapBalanceId(inputToken, outputToken) acc[swapBalanceId] = acc[swapBalanceId] ?? { inputAmount: ZERO, outputAmount: ZERO, } acc[swapBalanceId].inputAmount = acc[swapBalanceId].inputAmount + inputAmount acc[swapBalanceId].outputAmount = acc[swapBalanceId].outputAmount + outputAmount return acc }, {} as ISwapBalance) } export const formatGqlSwapper: (arg0: GqlSwapper) => ISwapper = ( gqlSwapper, ) => { return { type: 'swapper', address: getAddress(gqlSwapper.id), chainId: parseInt(gqlSwapper.chainId) as SupportedChainId, distributions: formatTokenBalances(gqlSwapper.distributions), balances: {}, balanceQuoteAmounts: {}, splitmainBalances: formatInternalTokenBalances(gqlSwapper.internalBalances), warehouseBalances: formatInternalTokenBalances( gqlSwapper.warehouseBalances, ), latestBlock: gqlSwapper.latestBlock, latestActivity: parseInt(gqlSwapper.latestActivity), parentEntityType: gqlSwapper.parentEntityType, owner: getAddress(gqlSwapper.owner.id), beneficiary: getAddress(gqlSwapper.beneficiary.id), tokenToBeneficiary: getAddress(gqlSwapper.tokenToBeneficiary.id), oracle: formatGqlOracle(gqlSwapper.oracle), paused: gqlSwapper.paused, defaultScaledOfferFactor: parseInt(gqlSwapper.defaultScaledOfferFactor), scaledOfferFactorOverrides: gqlSwapper.scaledOfferFactorPairOverrides.reduce((acc, override) => { const base = getAddress(override.base.id) const quote = getAddress(override.quote.id) const pair = `${base}-${quote}` acc[pair] = { base, quote, scaledOfferFactor: parseInt(override.scaledOfferFactor), } return acc }, {} as ISwapperScaledOfferFactorOverrides), swapBalances: formatSwapBalances(gqlSwapper.swapperSwapBalances), contractEarnings: formatGqlContractEarnings(gqlSwapper.contractEarnings), } } export const protectedFormatSwapper = (gqlSwapper: ISwapper): Swapper => { return { type: 'Swapper', address: gqlSwapper.address, beneficiary: { address: gqlSwapper.beneficiary, }, tokenToBeneficiary: { address: gqlSwapper.tokenToBeneficiary, }, oracle: gqlSwapper.oracle, owner: gqlSwapper.owner !== zeroAddress ? { address: gqlSwapper.owner, } : null, paused: gqlSwapper.paused, defaultScaledOfferFactorPercent: (1e6 - gqlSwapper.defaultScaledOfferFactor) / 1e4, scaledOfferFactorOverrides: Object.values( gqlSwapper.scaledOfferFactorOverrides, ).map((scaleOfferFactorOverride) => { const baseToken = getAddress(scaleOfferFactorOverride.base) const quoteToken = getAddress(scaleOfferFactorOverride.quote) const scaledOfferFactorPercent = (1e6 - scaleOfferFactorOverride.scaledOfferFactor) / 1e4 return { baseToken: { address: baseToken, }, quoteToken: { address: quoteToken, }, scaledOfferFactorPercent, } }), } }