import React, { ReactElement, useEffect, useState } from 'react' import { Logger } from '@oceanprotocol/lib' import styles from './index.module.css' import stylesActions from './Actions.module.css' import PriceUnit from '../../../atoms/Price/PriceUnit' import Button from '../../../atoms/Button' import Add from './Add' import Remove from './Remove' import Tooltip from '../../../atoms/Tooltip' import ExplorerLink from '../../../atoms/ExplorerLink' import Token from './Token' import TokenList from './TokenList' import { graphql, useStaticQuery } from 'gatsby' import { PoolBalance } from '../../../../@types/TokenBalance' import Transactions from './Transactions' import Graph from './Graph' import { useAsset } from '../../../../providers/Asset' import { gql, useQuery } from '@apollo/client' import { PoolLiquidity } from '../../../../@types/apollo/PoolLiquidity' import { useOcean } from '../../../../providers/Ocean' import { useWeb3 } from '../../../../providers/Web3' const contentQuery = graphql` query PoolQuery { content: allFile(filter: { relativePath: { eq: "price.json" } }) { edges { node { childContentJson { pool { tooltips { price liquidity } } } } } } } ` const poolLiquidityQuery = gql` query PoolLiquidity($id: ID!, $shareId: ID) { pool(id: $id) { id totalShares swapFee spotPrice tokens { tokenAddress balance denormWeight } shares(where: { id: $shareId }) { id balance } } } ` export default function Pool(): ReactElement { const data = useStaticQuery(contentQuery) const content = data.content.edges[0].node.childContentJson.pool const { accountId, networkId } = useWeb3() const { ocean } = useOcean() const { isInPurgatory, ddo, owner, price, refreshInterval } = useAsset() const dtSymbol = ddo?.dataTokenInfo.symbol const [poolTokens, setPoolTokens] = useState() const [totalPoolTokens, setTotalPoolTokens] = useState() const [userLiquidity, setUserLiquidity] = useState() const [swapFee, setSwapFee] = useState() const [weightOcean, setWeightOcean] = useState() const [weightDt, setWeightDt] = useState() const [showAdd, setShowAdd] = useState(false) const [showRemove, setShowRemove] = useState(false) const [isRemoveDisabled, setIsRemoveDisabled] = useState(false) const [hasAddedLiquidity, setHasAddedLiquidity] = useState(false) const [poolShare, setPoolShare] = useState() const [totalUserLiquidityInOcean, setTotalUserLiquidityInOcean] = useState(0) const [totalLiquidityInOcean, setTotalLiquidityInOcean] = useState(0) const [creatorTotalLiquidityInOcean, setCreatorTotalLiquidityInOcean] = useState(0) const [creatorLiquidity, setCreatorLiquidity] = useState() const [creatorPoolTokens, setCreatorPoolTokens] = useState() const [creatorPoolShare, setCreatorPoolShare] = useState() // the purpose of the value is just to trigger the effect const [refreshPool, setRefreshPool] = useState(false) const { data: dataLiquidity } = useQuery(poolLiquidityQuery, { variables: { id: price.address.toLowerCase(), shareId: `${price.address.toLowerCase()}-${ddo.publicKey[0].owner.toLowerCase()}` }, pollInterval: 5000 }) useEffect(() => { async function init() { if (!dataLiquidity || !dataLiquidity.pool) return // Total pool shares const totalPoolTokens = dataLiquidity.pool.totalShares setTotalPoolTokens(totalPoolTokens) // Get swap fee // swapFee is tricky: to get 0.1% you need to convert from 0.001 setSwapFee(`${Number(dataLiquidity.pool.swapFee) * 100}`) // Get weights const weightDt = dataLiquidity.pool.tokens.filter( (token: any) => token.tokenAddress === ddo.dataToken.toLowerCase() )[0].denormWeight setWeightDt(`${Number(weightDt) * 10}`) setWeightOcean(`${100 - Number(weightDt) * 10}`) // // Get everything the creator put into the pool // const creatorPoolTokens = dataLiquidity.pool.shares[0].balance setCreatorPoolTokens(creatorPoolTokens) // Calculate creator's provided liquidity based on pool tokens const creatorOceanBalance = (Number(creatorPoolTokens) / Number(totalPoolTokens)) * price.ocean const creatorDtBalance = (Number(creatorPoolTokens) / Number(totalPoolTokens)) * price.datatoken const creatorLiquidity = { ocean: creatorOceanBalance, datatoken: creatorDtBalance } setCreatorLiquidity(creatorLiquidity) const totalCreatorLiquidityInOcean = creatorLiquidity?.ocean + creatorLiquidity?.datatoken * dataLiquidity.pool.spotPrice setCreatorTotalLiquidityInOcean(totalCreatorLiquidityInOcean) const creatorPoolShare = price?.ocean && price?.datatoken && creatorLiquidity && ((Number(creatorPoolTokens) / Number(totalPoolTokens)) * 100).toFixed(2) setCreatorPoolShare(creatorPoolShare) } init() }, [dataLiquidity, ddo.dataToken, price.datatoken, price.ocean, price?.value]) useEffect(() => { setIsRemoveDisabled(isInPurgatory && owner === accountId) }, [isInPurgatory, owner, accountId]) useEffect(() => { const poolShare = price?.ocean && price?.datatoken && ((Number(poolTokens) / Number(totalPoolTokens)) * 100).toFixed(5) setPoolShare(poolShare) setHasAddedLiquidity(Number(poolShare) > 0) const totalUserLiquidityInOcean = userLiquidity?.ocean + userLiquidity?.datatoken * price?.value setTotalUserLiquidityInOcean(totalUserLiquidityInOcean) const totalLiquidityInOcean = Number(price?.ocean) + Number(price?.datatoken) * Number(price?.value) setTotalLiquidityInOcean(totalLiquidityInOcean) }, [userLiquidity, price, poolTokens, totalPoolTokens]) useEffect(() => { if (!ocean || !accountId || !price) return async function init() { try { // // Get everything the user has put into the pool // const poolTokens = await ocean.pool.sharesBalance( accountId, price.address ) setPoolTokens(poolTokens) // calculate user's provided liquidity based on pool tokens const userOceanBalance = (Number(poolTokens) / Number(totalPoolTokens)) * price.ocean const userDtBalance = (Number(poolTokens) / Number(totalPoolTokens)) * price.datatoken const userLiquidity = { ocean: userOceanBalance, datatoken: userDtBalance } setUserLiquidity(userLiquidity) } catch (error) { Logger.error(error.message) } } init() }, [ocean, accountId, price, ddo, refreshPool, owner, totalPoolTokens]) const refreshInfo = async () => { setRefreshPool(!refreshPool) // need some form of replacement or something. // await refreshPrice() } return ( <> {showAdd ? ( ) : showRemove ? ( ) : ( <>
={' '}
Pool Datatoken
Your Liquidity } ocean={`${userLiquidity?.ocean}`} dt={`${userLiquidity?.datatoken}`} dtSymbol={dtSymbol} poolShares={poolTokens} conversion={totalUserLiquidityInOcean} highlight > Pool Statistics {weightDt && ( {weightOcean}/{weightDt} )} } ocean={`${price?.ocean}`} dt={`${price?.datatoken}`} dtSymbol={dtSymbol} poolShares={totalPoolTokens} conversion={totalLiquidityInOcean} > {ocean && (
Fetching every {refreshInterval / 1000} sec.
)}
{!isInPurgatory && ( )} {hasAddedLiquidity && !isRemoveDisabled && ( )}
{accountId && } )} ) }