mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
Pool components UI refactor (#1295)
* reorder UI * refactor with new PoolSection component * move all the things * layout tweaks * fix pool data without wallet * fix undefined user pool share * fix max remove calculation * make conversion use our decimals definition
This commit is contained in:
parent
d64fe4e32c
commit
f2e7db0260
@ -1,6 +1,5 @@
|
||||
.token {
|
||||
font-weight: var(--font-weight-bold);
|
||||
margin-bottom: calc(var(--spacer) / 4);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@ -26,6 +25,21 @@
|
||||
height: var(--font-size-base);
|
||||
}
|
||||
|
||||
.conversion {
|
||||
composes: token;
|
||||
margin-bottom: 0;
|
||||
font-weight: var(--font-weight-base) !important;
|
||||
font-size: var(--font-size-small);
|
||||
padding-left: var(--font-size-base);
|
||||
padding-top: calc(var(--spacer) / 10);
|
||||
}
|
||||
|
||||
.conversion strong {
|
||||
font-size: var(--font-size-base);
|
||||
color: var(--font-color-heading);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* Data Token Icon Style */
|
||||
.icon:not([class*='OCEAN']) path {
|
||||
fill: var(--brand-violet);
|
40
src/components/@shared/Token/index.tsx
Normal file
40
src/components/@shared/Token/index.tsx
Normal file
@ -0,0 +1,40 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import styles from './index.module.css'
|
||||
import PriceUnit from '@shared/Price/PriceUnit'
|
||||
import Logo from '@shared/atoms/Logo'
|
||||
import Decimal from 'decimal.js'
|
||||
import Conversion from '@shared/Price/Conversion'
|
||||
import { MAX_DECIMALS } from '@utils/constants'
|
||||
|
||||
export default function Token({
|
||||
symbol,
|
||||
balance,
|
||||
conversion,
|
||||
noIcon,
|
||||
size
|
||||
}: {
|
||||
symbol: string
|
||||
balance: string
|
||||
conversion?: Decimal
|
||||
noIcon?: boolean
|
||||
size?: 'small' | 'mini'
|
||||
}): ReactElement {
|
||||
return (
|
||||
<>
|
||||
<div className={`${styles.token} ${size ? styles[size] : ''}`}>
|
||||
<figure
|
||||
className={`${styles.icon} ${symbol} ${noIcon ? styles.noIcon : ''}`}
|
||||
>
|
||||
<Logo noWordmark />
|
||||
</figure>
|
||||
<PriceUnit price={balance} symbol={symbol} size={size} />
|
||||
</div>
|
||||
{conversion?.greaterThan(0) && (
|
||||
<Conversion
|
||||
price={conversion.toDecimalPlaces(MAX_DECIMALS).toString()}
|
||||
className={styles.conversion}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
.actions {
|
||||
composes: container from './Pool/index.module.css';
|
||||
border-top: 1px solid var(--border-color);
|
||||
composes: section from './Pool/Section/index.module.css';
|
||||
margin-top: calc(var(--spacer) / 1.5);
|
||||
padding: calc(var(--spacer) / 1.5);
|
||||
background: var(--background-highlight);
|
||||
@ -12,7 +11,7 @@
|
||||
}
|
||||
|
||||
.title {
|
||||
composes: title from './Pool/index.module.css';
|
||||
composes: title from './Pool/Section/Title.module.css';
|
||||
margin-bottom: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { ReactElement, useState } from 'react'
|
||||
import Loader from '@shared/atoms/Loader'
|
||||
import Button from '@shared/atoms/Button'
|
||||
import styles from './Actions.module.css'
|
||||
import styles from './index.module.css'
|
||||
import ExplorerLink from '@shared/ExplorerLink'
|
||||
import SuccessConfetti from '@shared/SuccessConfetti'
|
||||
import { useWeb3 } from '@context/Web3'
|
@ -14,29 +14,21 @@ import { useWeb3 } from '@context/Web3'
|
||||
import { isValidNumber } from '@utils/numbers'
|
||||
import Decimal from 'decimal.js'
|
||||
import { useAsset } from '@context/Asset'
|
||||
import { LoggerInstance, Pool } from '@oceanprotocol/lib'
|
||||
import { Pool } from '@oceanprotocol/lib'
|
||||
import { usePool } from '@context/Pool'
|
||||
|
||||
export default function FormAdd({
|
||||
tokenInAddress,
|
||||
tokenInSymbol,
|
||||
amountMax,
|
||||
totalPoolTokens,
|
||||
totalBalance,
|
||||
poolAddress,
|
||||
setNewPoolTokens,
|
||||
setNewPoolShare
|
||||
}: {
|
||||
tokenInAddress: string
|
||||
tokenInSymbol: string
|
||||
amountMax: string
|
||||
totalPoolTokens: string
|
||||
totalBalance: PoolBalance
|
||||
poolAddress: string
|
||||
setNewPoolTokens: (value: string) => void
|
||||
setNewPoolShare: (value: string) => void
|
||||
}): ReactElement {
|
||||
const { balance, web3 } = useWeb3()
|
||||
const { isAssetNetwork } = useAsset()
|
||||
const { poolData, poolInfo } = usePool()
|
||||
|
||||
// Connect with form
|
||||
const {
|
||||
@ -47,9 +39,9 @@ export default function FormAdd({
|
||||
|
||||
useEffect(() => {
|
||||
async function calculatePoolShares() {
|
||||
if (!web3) return
|
||||
if (!web3 || !poolData?.id || !poolInfo?.totalPoolTokens) return
|
||||
|
||||
if (!values.amount || !tokenInAddress) {
|
||||
if (!values.amount || !poolInfo?.baseTokenAddress) {
|
||||
setNewPoolTokens('0')
|
||||
setNewPoolShare('0')
|
||||
return
|
||||
@ -59,31 +51,32 @@ export default function FormAdd({
|
||||
const poolInstance = new Pool(web3)
|
||||
|
||||
const poolTokens = await poolInstance.calcPoolOutGivenSingleIn(
|
||||
poolAddress,
|
||||
tokenInAddress,
|
||||
poolData.id,
|
||||
poolInfo.baseTokenAddress,
|
||||
values.amount
|
||||
)
|
||||
setNewPoolTokens(poolTokens)
|
||||
const newPoolShareDecimal =
|
||||
isValidNumber(poolTokens) && isValidNumber(totalPoolTokens)
|
||||
isValidNumber(poolTokens) && isValidNumber(poolInfo.totalPoolTokens)
|
||||
? new Decimal(poolTokens)
|
||||
.dividedBy(
|
||||
new Decimal(totalPoolTokens).plus(new Decimal(poolTokens))
|
||||
new Decimal(poolInfo.totalPoolTokens).plus(
|
||||
new Decimal(poolTokens)
|
||||
)
|
||||
)
|
||||
.mul(100)
|
||||
.toString()
|
||||
: '0'
|
||||
totalBalance && setNewPoolShare(newPoolShareDecimal)
|
||||
setNewPoolShare(newPoolShareDecimal)
|
||||
}
|
||||
calculatePoolShares()
|
||||
}, [
|
||||
tokenInAddress,
|
||||
poolInfo?.baseTokenAddress,
|
||||
web3,
|
||||
values.amount,
|
||||
totalBalance,
|
||||
totalPoolTokens,
|
||||
poolInfo?.totalPoolTokens,
|
||||
amountMax,
|
||||
poolAddress,
|
||||
poolData?.id,
|
||||
setNewPoolTokens,
|
||||
setNewPoolShare
|
||||
])
|
||||
@ -93,7 +86,7 @@ export default function FormAdd({
|
||||
<UserLiquidity
|
||||
amount={balance.ocean}
|
||||
amountMax={amountMax}
|
||||
symbol={tokenInSymbol}
|
||||
symbol={poolInfo?.baseTokenSymbol}
|
||||
/>
|
||||
|
||||
<Field name="amount">
|
||||
@ -111,7 +104,7 @@ export default function FormAdd({
|
||||
min="0"
|
||||
value={values.amount}
|
||||
step="any"
|
||||
prefix={tokenInSymbol}
|
||||
prefix={poolInfo?.baseTokenSymbol}
|
||||
placeholder="0"
|
||||
field={field}
|
||||
form={form}
|
||||
|
@ -1,60 +1,24 @@
|
||||
import { FormikContextType, useFormikContext } from 'formik'
|
||||
import React, { ReactElement, useEffect, useState } from 'react'
|
||||
import { FormAddLiquidity } from '.'
|
||||
import React, { ReactElement } from 'react'
|
||||
import FormHelp from '@shared/FormInput/Help'
|
||||
import Token from '../Token'
|
||||
import Token from '../../../../@shared/Token'
|
||||
import styles from './Output.module.css'
|
||||
import Decimal from 'decimal.js'
|
||||
import content from '../../../../../../content/price.json'
|
||||
import { usePool } from '@context/Pool'
|
||||
|
||||
export default function Output({
|
||||
newPoolTokens,
|
||||
newPoolShare,
|
||||
swapFee,
|
||||
datatokenSymbol,
|
||||
totalPoolTokens,
|
||||
totalBalance
|
||||
newPoolShare
|
||||
}: {
|
||||
newPoolTokens: string
|
||||
newPoolShare: string
|
||||
swapFee: string
|
||||
datatokenSymbol: string
|
||||
totalPoolTokens: string
|
||||
totalBalance: PoolBalance
|
||||
}): ReactElement {
|
||||
const { help, titleIn, titleOut } = content.pool.add.output
|
||||
|
||||
// Connect with form
|
||||
const { values }: FormikContextType<FormAddLiquidity> = useFormikContext()
|
||||
|
||||
const [poolOcean, setPoolOcean] = useState('0')
|
||||
const [poolDatatoken, setPoolDatatoken] = useState('0')
|
||||
|
||||
useEffect(() => {
|
||||
if (!values.amount || !totalBalance || !totalPoolTokens || !newPoolTokens)
|
||||
return
|
||||
const newPoolSupply = new Decimal(totalPoolTokens).plus(newPoolTokens)
|
||||
const ratio = new Decimal(newPoolTokens).div(newPoolSupply)
|
||||
const newOceanReserve = new Decimal(totalBalance.baseToken).plus(
|
||||
values.amount
|
||||
)
|
||||
const newDtReserve = new Decimal(totalBalance.datatoken)
|
||||
const poolOcean = newOceanReserve.mul(ratio).toString()
|
||||
const poolDatatoken = newDtReserve.mul(ratio).toString()
|
||||
setPoolOcean(poolOcean)
|
||||
setPoolDatatoken(poolDatatoken)
|
||||
}, [
|
||||
values.amount,
|
||||
totalBalance,
|
||||
totalPoolTokens,
|
||||
newPoolShare,
|
||||
newPoolTokens
|
||||
])
|
||||
const { help, titleIn } = content.pool.add.output
|
||||
const { poolInfo } = usePool()
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormHelp className={styles.help}>
|
||||
{help.replace('SWAPFEE', swapFee)}
|
||||
{help.replace('SWAPFEE', poolInfo?.liquidityProviderSwapFee)}
|
||||
</FormHelp>
|
||||
<div className={styles.output}>
|
||||
<p>{titleIn}</p>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { ReactElement, useState, useEffect } from 'react'
|
||||
import Header from '../Header'
|
||||
import Header from '../Actions/Header'
|
||||
import { toast } from 'react-toastify'
|
||||
import Actions from '../Actions'
|
||||
import * as Yup from 'yup'
|
||||
@ -25,28 +25,15 @@ const initialValues: FormAddLiquidity = {
|
||||
}
|
||||
|
||||
export default function Add({
|
||||
setShowAdd,
|
||||
poolAddress,
|
||||
totalPoolTokens,
|
||||
totalBalance,
|
||||
swapFee,
|
||||
datatokenSymbol,
|
||||
tokenInSymbol,
|
||||
tokenInAddress
|
||||
setShowAdd
|
||||
}: {
|
||||
setShowAdd: (show: boolean) => void
|
||||
poolAddress: string
|
||||
totalPoolTokens: string
|
||||
totalBalance: PoolBalance
|
||||
swapFee: string
|
||||
datatokenSymbol: string
|
||||
tokenInSymbol: string
|
||||
tokenInAddress: string
|
||||
}): ReactElement {
|
||||
const { accountId, balance, web3 } = useWeb3()
|
||||
const { isAssetNetwork } = useAsset()
|
||||
const { fetchAllData } = usePool()
|
||||
const { poolData, poolInfo, fetchAllData } = usePool()
|
||||
const { debug } = useUserPreferences()
|
||||
|
||||
const [txId, setTxId] = useState<string>()
|
||||
const [amountMax, setAmountMax] = useState<string>()
|
||||
const [newPoolTokens, setNewPoolTokens] = useState('0')
|
||||
@ -67,15 +54,22 @@ export default function Add({
|
||||
|
||||
// Get maximum amount for OCEAN
|
||||
useEffect(() => {
|
||||
if (!web3 || !accountId || !isAssetNetwork || !poolAddress) return
|
||||
if (
|
||||
!web3 ||
|
||||
!accountId ||
|
||||
!isAssetNetwork ||
|
||||
!poolData?.id ||
|
||||
!poolInfo?.baseTokenAddress
|
||||
)
|
||||
return
|
||||
|
||||
async function getMaximum() {
|
||||
try {
|
||||
const poolInstance = new Pool(web3)
|
||||
|
||||
const poolReserve = await poolInstance.getReserve(
|
||||
poolAddress,
|
||||
tokenInAddress
|
||||
poolData.id,
|
||||
poolInfo.baseTokenAddress
|
||||
)
|
||||
|
||||
const amountMaxPool = calcMaxExactIn(poolReserve)
|
||||
@ -93,8 +87,8 @@ export default function Add({
|
||||
web3,
|
||||
accountId,
|
||||
isAssetNetwork,
|
||||
poolAddress,
|
||||
tokenInAddress,
|
||||
poolData?.id,
|
||||
poolInfo?.baseTokenAddress,
|
||||
balance?.ocean
|
||||
])
|
||||
|
||||
@ -106,7 +100,7 @@ export default function Add({
|
||||
try {
|
||||
const result = await poolInstance.joinswapExternAmountIn(
|
||||
accountId,
|
||||
poolAddress,
|
||||
poolData?.id,
|
||||
amount,
|
||||
minPoolAmountOut
|
||||
)
|
||||
@ -141,12 +135,7 @@ export default function Add({
|
||||
<div className={styles.addInput}>
|
||||
{isWarningAccepted ? (
|
||||
<FormAdd
|
||||
tokenInAddress={tokenInAddress}
|
||||
tokenInSymbol={tokenInSymbol}
|
||||
amountMax={amountMax}
|
||||
totalPoolTokens={totalPoolTokens}
|
||||
totalBalance={totalBalance}
|
||||
poolAddress={poolAddress}
|
||||
setNewPoolTokens={setNewPoolTokens}
|
||||
setNewPoolShare={setNewPoolShare}
|
||||
/>
|
||||
@ -166,14 +155,7 @@ export default function Add({
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Output
|
||||
newPoolTokens={newPoolTokens}
|
||||
newPoolShare={newPoolShare}
|
||||
swapFee={swapFee}
|
||||
datatokenSymbol={datatokenSymbol}
|
||||
totalPoolTokens={totalPoolTokens}
|
||||
totalBalance={totalBalance}
|
||||
/>
|
||||
<Output newPoolTokens={newPoolTokens} newPoolShare={newPoolShare} />
|
||||
|
||||
<Actions
|
||||
isDisabled={
|
||||
@ -189,8 +171,8 @@ export default function Add({
|
||||
actionName={content.pool.add.action}
|
||||
action={submitForm}
|
||||
amount={values.amount}
|
||||
tokenAddress={tokenInAddress}
|
||||
tokenSymbol={tokenInSymbol}
|
||||
tokenAddress={poolInfo?.baseTokenAddress}
|
||||
tokenSymbol={poolInfo?.baseTokenSymbol}
|
||||
txId={txId}
|
||||
setSubmitting={setSubmitting}
|
||||
/>
|
||||
|
@ -1,9 +1,11 @@
|
||||
.type {
|
||||
position: absolute;
|
||||
bottom: -10px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding: 5px var(--spacer);
|
||||
border-top: 1px solid var(--border-color);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.button,
|
||||
|
@ -1,19 +1,17 @@
|
||||
.graphWrap {
|
||||
composes: container from '../Section/index.module.css';
|
||||
|
||||
padding: 0;
|
||||
grid-column: full;
|
||||
min-height: 120px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: calc(var(--spacer) / 6) -1.35rem calc(var(--spacer) / 1.5) -1.35rem;
|
||||
flex-direction: column;
|
||||
margin-bottom: calc(var(--spacer) / 2);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@media (min-width: 40rem) {
|
||||
.graphWrap {
|
||||
margin-left: -2rem;
|
||||
margin-right: -2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.graphWrap canvas {
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
|
@ -11,17 +11,14 @@ import Decimal from 'decimal.js'
|
||||
import { lineStyle, GraphType } from './_constants'
|
||||
import Nav from './Nav'
|
||||
import { getOptions } from './_utils'
|
||||
import { PoolData_poolSnapshots as PoolDataPoolSnapshots } from 'src/@types/subgraph/PoolData'
|
||||
import { usePrices } from '@context/Prices'
|
||||
import { MAX_DECIMALS } from '@utils/constants'
|
||||
import { usePool } from '@context/Pool'
|
||||
|
||||
export default function Graph({
|
||||
poolSnapshots
|
||||
}: {
|
||||
poolSnapshots: PoolDataPoolSnapshots[]
|
||||
}): ReactElement {
|
||||
export default function Graph(): ReactElement {
|
||||
const { locale, currency } = useUserPreferences()
|
||||
const { prices } = usePrices()
|
||||
const { poolSnapshots } = usePool()
|
||||
const darkMode = useDarkMode(false, darkModeConfig)
|
||||
|
||||
const [options, setOptions] = useState<ChartOptions<any>>()
|
||||
@ -104,13 +101,13 @@ export default function Graph({
|
||||
<Loader />
|
||||
) : (
|
||||
<>
|
||||
<Nav graphType={graphType} setGraphType={setGraphType} />
|
||||
|
||||
{graphType === 'volume' ? (
|
||||
<Bar width={416} height={120} data={graphData} options={options} />
|
||||
) : (
|
||||
<Line width={416} height={120} data={graphData} options={options} />
|
||||
)}
|
||||
|
||||
<Nav graphType={graphType} setGraphType={setGraphType} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
19
src/components/Asset/AssetActions/Pool/Remove/_utils.ts
Normal file
19
src/components/Asset/AssetActions/Pool/Remove/_utils.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { calcMaxExactOut } from '@oceanprotocol/lib'
|
||||
import Decimal from 'decimal.js'
|
||||
|
||||
export async function getMax(poolTokens: string, totalPoolTokens: string) {
|
||||
const poolTokensAmount = !poolTokens || poolTokens === '0' ? '1' : poolTokens
|
||||
const maxTokensToRemoveFromPool = calcMaxExactOut(totalPoolTokens)
|
||||
const poolTokensDecimal = new Decimal(poolTokensAmount)
|
||||
const maxTokensToRemoveForUser = maxTokensToRemoveFromPool.greaterThan(
|
||||
poolTokensDecimal
|
||||
)
|
||||
? poolTokensDecimal
|
||||
: maxTokensToRemoveFromPool
|
||||
|
||||
const maxPercent = new Decimal(100)
|
||||
.mul(maxTokensToRemoveForUser)
|
||||
.div(poolTokensDecimal)
|
||||
|
||||
return maxPercent.toDecimalPlaces(0, Decimal.ROUND_DOWN).toString()
|
||||
}
|
@ -6,11 +6,11 @@ import React, {
|
||||
useRef
|
||||
} from 'react'
|
||||
import styles from './index.module.css'
|
||||
import Header from '../Header'
|
||||
import Header from '../Actions/Header'
|
||||
import { toast } from 'react-toastify'
|
||||
import Actions from '../Actions'
|
||||
import { LoggerInstance, Pool, calcMaxExactOut } from '@oceanprotocol/lib'
|
||||
import Token from '../Token'
|
||||
import { LoggerInstance, Pool } from '@oceanprotocol/lib'
|
||||
import Token from '../../../../@shared/Token'
|
||||
import FormHelp from '@shared/FormInput/Help'
|
||||
import Button from '@shared/atoms/Button'
|
||||
import debounce from 'lodash.debounce'
|
||||
@ -21,27 +21,18 @@ import Decimal from 'decimal.js'
|
||||
import { useAsset } from '@context/Asset'
|
||||
import content from '../../../../../../content/price.json'
|
||||
import { usePool } from '@context/Pool'
|
||||
import { getMax } from './_utils'
|
||||
|
||||
const slippagePresets = ['5', '10', '15', '25', '50']
|
||||
|
||||
export default function Remove({
|
||||
setShowRemove,
|
||||
poolAddress,
|
||||
poolTokens,
|
||||
totalPoolTokens,
|
||||
tokenOutAddress,
|
||||
tokenOutSymbol
|
||||
setShowRemove
|
||||
}: {
|
||||
setShowRemove: (show: boolean) => void
|
||||
poolAddress: string
|
||||
poolTokens: string
|
||||
totalPoolTokens: string
|
||||
tokenOutAddress: string
|
||||
tokenOutSymbol: string
|
||||
}): ReactElement {
|
||||
const { accountId, web3 } = useWeb3()
|
||||
const { isAssetNetwork } = useAsset()
|
||||
const { fetchAllData } = usePool()
|
||||
const { poolData, poolInfo, poolInfoUser, fetchAllData } = usePool()
|
||||
|
||||
const [amountPercent, setAmountPercent] = useState('0')
|
||||
const [amountMaxPercent, setAmountMaxPercent] = useState('100')
|
||||
@ -62,7 +53,7 @@ export default function Remove({
|
||||
try {
|
||||
const result = await poolInstance.exitswapPoolAmountIn(
|
||||
accountId,
|
||||
poolAddress,
|
||||
poolData?.id,
|
||||
amountPoolShares,
|
||||
minOceanAmount
|
||||
)
|
||||
@ -81,35 +72,23 @@ export default function Remove({
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate and set maximum shares user is able to remove
|
||||
//
|
||||
useEffect(() => {
|
||||
if (!accountId || !poolTokens) return
|
||||
if (!accountId || !poolInfoUser?.poolShares || !poolInfo?.totalPoolTokens)
|
||||
return
|
||||
|
||||
async function getMax() {
|
||||
const poolTokensAmount =
|
||||
!poolTokens || poolTokens === '0' ? '1' : poolTokens
|
||||
const maxTokensToRemoveFromPool = calcMaxExactOut(totalPoolTokens)
|
||||
const poolTokensDecimal = new Decimal(poolTokensAmount)
|
||||
const maxTokensToRemoveForUser = maxTokensToRemoveFromPool.greaterThan(
|
||||
poolTokensDecimal
|
||||
)
|
||||
? poolTokensDecimal
|
||||
: maxTokensToRemoveFromPool
|
||||
|
||||
const maxPercent = new Decimal(100)
|
||||
.mul(maxTokensToRemoveForUser)
|
||||
.div(poolTokensDecimal)
|
||||
setAmountMaxPercent(
|
||||
maxPercent.toDecimalPlaces(0, Decimal.ROUND_DOWN).toString()
|
||||
)
|
||||
}
|
||||
getMax()
|
||||
}, [accountId, poolAddress, poolTokens, totalPoolTokens])
|
||||
getMax(poolInfoUser.poolShares, poolInfo.totalPoolTokens).then((max) =>
|
||||
setAmountMaxPercent(max)
|
||||
)
|
||||
}, [accountId, poolInfoUser?.poolShares, poolInfo?.totalPoolTokens])
|
||||
|
||||
const getValues = useRef(
|
||||
debounce(async (newAmountPoolShares) => {
|
||||
const newAmountOcean = await poolInstance.calcSingleOutGivenPoolIn(
|
||||
poolAddress,
|
||||
tokenOutAddress,
|
||||
poolData?.id,
|
||||
poolInfo?.baseTokenAddress,
|
||||
newAmountPoolShares
|
||||
)
|
||||
|
||||
@ -119,9 +98,21 @@ export default function Remove({
|
||||
|
||||
// Check and set outputs when amountPoolShares changes
|
||||
useEffect(() => {
|
||||
if (!accountId || !poolTokens) return
|
||||
if (
|
||||
!accountId ||
|
||||
!poolInfoUser?.poolShares ||
|
||||
!poolInfo?.totalPoolTokens ||
|
||||
!poolData?.id
|
||||
)
|
||||
return
|
||||
getValues.current(amountPoolShares)
|
||||
}, [amountPoolShares, accountId, poolTokens, poolAddress, totalPoolTokens])
|
||||
}, [
|
||||
amountPoolShares,
|
||||
accountId,
|
||||
poolInfoUser?.poolShares,
|
||||
poolData?.id,
|
||||
poolInfo?.totalPoolTokens
|
||||
])
|
||||
|
||||
useEffect(() => {
|
||||
if (!amountOcean || amountPercent === '0') {
|
||||
@ -135,16 +126,16 @@ export default function Remove({
|
||||
.toString()
|
||||
|
||||
setMinOceanAmount(minOceanAmount.slice(0, 18))
|
||||
}, [slippage, amountOcean])
|
||||
}, [slippage, amountOcean, amountPercent])
|
||||
|
||||
// Set amountPoolShares based on set slider value
|
||||
function handleAmountPercentChange(e: ChangeEvent<HTMLInputElement>) {
|
||||
setAmountPercent(e.target.value)
|
||||
if (!poolTokens) return
|
||||
if (!poolInfoUser?.poolShares) return
|
||||
|
||||
const amountPoolShares = new Decimal(e.target.value)
|
||||
.dividedBy(100)
|
||||
.mul(new Decimal(poolTokens))
|
||||
.mul(new Decimal(poolInfoUser.poolShares))
|
||||
.toString()
|
||||
|
||||
setAmountPoolShares(`${amountPoolShares.slice(0, 18)}`)
|
||||
@ -156,7 +147,7 @@ export default function Remove({
|
||||
|
||||
const amountPoolShares = new Decimal(amountMaxPercent)
|
||||
.dividedBy(100)
|
||||
.mul(new Decimal(poolTokens))
|
||||
.mul(new Decimal(poolInfoUser?.poolShares))
|
||||
.toString()
|
||||
|
||||
setAmountPoolShares(`${amountPoolShares.slice(0, 18)}`)
|
||||
@ -177,7 +168,7 @@ export default function Remove({
|
||||
/>
|
||||
|
||||
<form className={styles.removeInput}>
|
||||
<UserLiquidity amount={poolTokens} symbol="pool shares" />
|
||||
<UserLiquidity amount={poolInfoUser?.poolShares} symbol="pool shares" />
|
||||
<div className={styles.range}>
|
||||
<h3>{amountPercent}%</h3>
|
||||
<div className={styles.slider}>
|
||||
@ -206,7 +197,7 @@ export default function Remove({
|
||||
<div className={styles.output}>
|
||||
<div>
|
||||
<p>{content.pool.remove.output.titleOut} minimum</p>
|
||||
<Token symbol={tokenOutSymbol} balance={minOceanAmount} />
|
||||
<Token symbol={poolInfo?.baseTokenSymbol} balance={minOceanAmount} />
|
||||
</div>
|
||||
{/* <div>
|
||||
<p>{content.pool.remove.output.titleIn}</p>
|
||||
@ -237,11 +228,11 @@ export default function Remove({
|
||||
!isAssetNetwork ||
|
||||
amountPercent === '0' ||
|
||||
amountOcean === '0' ||
|
||||
poolTokens === '0'
|
||||
poolInfo?.totalPoolTokens === '0'
|
||||
}
|
||||
txId={txId}
|
||||
tokenAddress={tokenOutAddress}
|
||||
tokenSymbol={tokenOutSymbol}
|
||||
tokenAddress={poolInfo?.baseTokenAddress}
|
||||
tokenSymbol={poolInfo?.baseTokenSymbol}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
@ -0,0 +1,13 @@
|
||||
.title {
|
||||
font-size: var(--font-size-base);
|
||||
margin-bottom: calc(var(--spacer) / 3);
|
||||
color: var(--color-secondary);
|
||||
}
|
||||
|
||||
.titlePostfix {
|
||||
font-size: var(--font-size-mini);
|
||||
font-family: var(--font-family-base);
|
||||
font-weight: var(--font-weight-base);
|
||||
display: inline-block;
|
||||
margin-left: 0.3rem;
|
||||
}
|
26
src/components/Asset/AssetActions/Pool/Section/Title.tsx
Normal file
26
src/components/Asset/AssetActions/Pool/Section/Title.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
import Tooltip from '@shared/atoms/Tooltip'
|
||||
import React from 'react'
|
||||
import styles from './Title.module.css'
|
||||
|
||||
export default function Title({
|
||||
title,
|
||||
tooltip,
|
||||
titlePostfix,
|
||||
titlePostfixTitle
|
||||
}: {
|
||||
title: string
|
||||
tooltip?: string
|
||||
titlePostfix?: string
|
||||
titlePostfixTitle?: string
|
||||
}) {
|
||||
return (
|
||||
<h3 className={styles.title}>
|
||||
{title} {tooltip && <Tooltip content={tooltip} />}{' '}
|
||||
{titlePostfix && (
|
||||
<span className={styles.titlePostfix} title={titlePostfixTitle}>
|
||||
{titlePostfix}
|
||||
</span>
|
||||
)}
|
||||
</h3>
|
||||
)
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
.container {
|
||||
margin-left: calc(-1 * var(--spacer) / 1.5);
|
||||
margin-right: calc(-1 * var(--spacer) / 1.5);
|
||||
padding: calc(var(--spacer) / 1.5) calc(var(--spacer) / 1.5)
|
||||
calc(var(--spacer) / 2) calc(var(--spacer) / 1.5);
|
||||
}
|
||||
|
||||
@media (min-width: 40rem) {
|
||||
.container {
|
||||
padding-left: var(--spacer);
|
||||
padding-right: var(--spacer);
|
||||
margin-left: calc(-1 * var(--spacer));
|
||||
margin-right: calc(-1 * var(--spacer));
|
||||
}
|
||||
}
|
||||
|
||||
.section {
|
||||
composes: container;
|
||||
|
||||
border-top: 1px solid var(--border-color);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.section.highlight {
|
||||
background: var(--background-highlight);
|
||||
}
|
||||
|
||||
.section:first-child {
|
||||
padding-top: 0;
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: calc(var(--spacer) / 2);
|
||||
grid-template-columns:
|
||||
[full-start] minmax(13rem, 1fr) [break] minmax(7rem, 1fr)
|
||||
[full-end];
|
||||
}
|
39
src/components/Asset/AssetActions/Pool/Section/index.tsx
Normal file
39
src/components/Asset/AssetActions/Pool/Section/index.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
import React, { ReactElement, ReactNode } from 'react'
|
||||
import styles from './index.module.css'
|
||||
import Title from './Title'
|
||||
|
||||
export default function PoolSection({
|
||||
title,
|
||||
tooltip,
|
||||
titlePostfix,
|
||||
titlePostfixTitle,
|
||||
children,
|
||||
highlight,
|
||||
className
|
||||
}: {
|
||||
title?: string
|
||||
children: ReactNode
|
||||
tooltip?: string
|
||||
titlePostfix?: string
|
||||
titlePostfixTitle?: string
|
||||
highlight?: boolean
|
||||
className?: string
|
||||
}): ReactElement {
|
||||
return (
|
||||
<div
|
||||
className={`${styles.section} ${highlight ? styles.highlight : ''} ${
|
||||
className || ''
|
||||
}`}
|
||||
>
|
||||
{title && (
|
||||
<Title
|
||||
title={title}
|
||||
tooltip={tooltip}
|
||||
titlePostfix={titlePostfix}
|
||||
titlePostfixTitle={titlePostfixTitle}
|
||||
/>
|
||||
)}
|
||||
<div className={styles.grid}>{children}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
.update {
|
||||
font-size: var(--font-size-mini);
|
||||
color: var(--color-secondary);
|
||||
text-align: center;
|
||||
padding-top: calc(var(--spacer) / 4);
|
||||
padding-bottom: calc(var(--spacer) / 3);
|
||||
}
|
||||
|
||||
/* .update:before {
|
||||
content: '';
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
border: 1px solid var(--brand-alert-green);
|
||||
margin-right: 0.2rem;
|
||||
margin-top: -0.1rem;
|
||||
vertical-align: middle;
|
||||
animation: pulse 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
background: transparent;
|
||||
}
|
||||
50% {
|
||||
background: var(--brand-alert-green);
|
||||
}
|
||||
100% {
|
||||
background: transparent;
|
||||
}
|
||||
} */
|
17
src/components/Asset/AssetActions/Pool/Sections/Update.tsx
Normal file
17
src/components/Asset/AssetActions/Pool/Sections/Update.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import { usePool } from '@context/Pool'
|
||||
import Button from '@shared/atoms/Button'
|
||||
import React from 'react'
|
||||
import styles from './Update.module.css'
|
||||
|
||||
export default function Update() {
|
||||
const { fetchAllData } = usePool()
|
||||
|
||||
return (
|
||||
<div className={styles.update}>
|
||||
<Button style="text" size="small" onClick={() => fetchAllData()}>
|
||||
Refresh Data
|
||||
</Button>
|
||||
{/* Fetching every {refreshInterval / 1000} sec. */}
|
||||
</div>
|
||||
)
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
.dataToken {
|
||||
font-size: var(--font-size-large);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dataToken > div {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.dataTokenLinks {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-size: var(--font-size-small);
|
||||
margin-top: calc(var(--spacer) / 4);
|
||||
}
|
||||
|
||||
.dataTokenLinks a {
|
||||
margin-left: calc(var(--spacer) / 3);
|
||||
margin-right: calc(var(--spacer) / 3);
|
||||
}
|
130
src/components/Asset/AssetActions/Pool/Sections/index.tsx
Normal file
130
src/components/Asset/AssetActions/Pool/Sections/index.tsx
Normal file
@ -0,0 +1,130 @@
|
||||
import { useAsset } from '@context/Asset'
|
||||
import { usePool } from '@context/Pool'
|
||||
import Tooltip from '@shared/atoms/Tooltip'
|
||||
import ExplorerLink from '@shared/ExplorerLink'
|
||||
import PriceUnit from '@shared/Price/PriceUnit'
|
||||
import React from 'react'
|
||||
import Graph from '../Graph'
|
||||
import PoolSection from '../Section'
|
||||
import Token from '../../../../@shared/Token'
|
||||
import content from '../../../../../../content/price.json'
|
||||
import styles from './index.module.css'
|
||||
import Update from './Update'
|
||||
|
||||
export default function PoolSections() {
|
||||
const { asset } = useAsset()
|
||||
const { poolData, poolInfo, poolInfoUser, poolInfoOwner } = usePool()
|
||||
|
||||
return (
|
||||
<>
|
||||
<PoolSection className={styles.dataToken}>
|
||||
<PriceUnit price="1" symbol={poolInfo?.datatokenSymbol} size="large" />{' '}
|
||||
={' '}
|
||||
<PriceUnit
|
||||
price={`${poolData?.spotPrice}`}
|
||||
symbol={poolInfo?.baseTokenSymbol}
|
||||
size="large"
|
||||
/>
|
||||
<Tooltip content={content.pool.tooltips.price} />
|
||||
<div className={styles.dataTokenLinks}>
|
||||
<ExplorerLink
|
||||
networkId={asset?.chainId}
|
||||
path={`address/${asset?.accessDetails?.addressOrId}`}
|
||||
>
|
||||
Pool
|
||||
</ExplorerLink>
|
||||
<ExplorerLink
|
||||
networkId={asset?.chainId}
|
||||
path={
|
||||
asset?.chainId === 2021000 || asset?.chainId === 1287
|
||||
? `tokens/${asset?.services[0].datatokenAddress}`
|
||||
: `token/${asset?.services[0].datatokenAddress}`
|
||||
}
|
||||
>
|
||||
Datatoken
|
||||
</ExplorerLink>
|
||||
</div>
|
||||
</PoolSection>
|
||||
|
||||
<PoolSection
|
||||
title="Your Value Locked"
|
||||
titlePostfix={
|
||||
poolInfoUser?.poolShare && `${poolInfoUser?.poolShare}% of pool`
|
||||
}
|
||||
tooltip={content.pool.tooltips.liquidity.replace(
|
||||
'SWAPFEE',
|
||||
poolInfo?.liquidityProviderSwapFee
|
||||
)}
|
||||
highlight
|
||||
>
|
||||
<Token
|
||||
symbol={poolInfo?.baseTokenSymbol}
|
||||
balance={poolInfoUser?.liquidity.toString()}
|
||||
conversion={poolInfoUser?.liquidity}
|
||||
/>
|
||||
</PoolSection>
|
||||
|
||||
<PoolSection
|
||||
title="Owner Value Locked"
|
||||
titlePostfix={`${poolInfoOwner?.poolShare}% of pool`}
|
||||
>
|
||||
<Token
|
||||
symbol={poolInfo?.baseTokenSymbol}
|
||||
balance={poolInfoOwner?.liquidity.toString()}
|
||||
conversion={poolInfoOwner?.liquidity}
|
||||
/>
|
||||
</PoolSection>
|
||||
|
||||
<PoolSection title="Total Value Locked">
|
||||
<Token
|
||||
symbol={poolInfo?.baseTokenSymbol}
|
||||
balance={poolInfo?.totalLiquidityInOcean.toString()}
|
||||
conversion={poolInfo?.totalLiquidityInOcean}
|
||||
/>
|
||||
</PoolSection>
|
||||
|
||||
<PoolSection
|
||||
title="Pool Statistics"
|
||||
titlePostfix={
|
||||
poolInfo?.weightDt &&
|
||||
`${poolInfo?.weightBaseToken}/${poolInfo?.weightDt}`
|
||||
}
|
||||
titlePostfixTitle={`Weight of ${poolInfo?.weightBaseToken}% ${poolInfo?.baseTokenSymbol} & ${poolInfo?.weightDt}% ${poolInfo?.datatokenSymbol}`}
|
||||
>
|
||||
<Graph />
|
||||
|
||||
<Token
|
||||
symbol={poolInfo?.baseTokenSymbol}
|
||||
balance={`${poolData?.baseTokenLiquidity}`}
|
||||
size="mini"
|
||||
/>
|
||||
<Token
|
||||
symbol={poolInfo?.datatokenSymbol}
|
||||
balance={`${poolData?.datatokenLiquidity}`}
|
||||
size="mini"
|
||||
/>
|
||||
|
||||
<Token
|
||||
symbol="% pool fee"
|
||||
balance={poolInfo?.liquidityProviderSwapFee}
|
||||
noIcon
|
||||
size="mini"
|
||||
/>
|
||||
<Token
|
||||
symbol="% market fee"
|
||||
balance={poolInfo?.publishMarketSwapFee}
|
||||
noIcon
|
||||
size="mini"
|
||||
/>
|
||||
<Token
|
||||
symbol="% OPF fee"
|
||||
balance={poolInfo?.opcFee}
|
||||
noIcon
|
||||
size="mini"
|
||||
/>
|
||||
</PoolSection>
|
||||
|
||||
<Update />
|
||||
</>
|
||||
)
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import styles from './Token.module.css'
|
||||
import PriceUnit from '@shared/Price/PriceUnit'
|
||||
import Logo from '@shared/atoms/Logo'
|
||||
|
||||
export default function Token({
|
||||
symbol,
|
||||
balance,
|
||||
noIcon,
|
||||
size
|
||||
}: {
|
||||
symbol: string
|
||||
balance: string
|
||||
noIcon?: boolean
|
||||
size?: 'small' | 'mini'
|
||||
}): ReactElement {
|
||||
return (
|
||||
<div className={`${styles.token} ${size ? styles[size] : ''}`}>
|
||||
<figure
|
||||
className={`${styles.icon} ${symbol} ${noIcon ? styles.noIcon : ''}`}
|
||||
>
|
||||
<Logo noWordmark />
|
||||
</figure>
|
||||
<PriceUnit price={balance} symbol={symbol} size={size} />
|
||||
</div>
|
||||
)
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
.tokenlist {
|
||||
margin-left: -2rem;
|
||||
margin-right: -2rem;
|
||||
padding: calc(var(--spacer) / 1.5) calc(var(--spacer) / 1.5)
|
||||
calc(var(--spacer) / 2) calc(var(--spacer) / 1.5);
|
||||
border-top: 1px solid var(--border-color);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@media (min-width: 40rem) {
|
||||
.tokenlist {
|
||||
padding-left: var(--spacer);
|
||||
padding-right: var(--spacer);
|
||||
}
|
||||
}
|
||||
|
||||
.tokenlist.highlight {
|
||||
background: var(--background-highlight);
|
||||
}
|
||||
|
||||
.tokens {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
|
||||
}
|
||||
|
||||
.title {
|
||||
composes: title from './index.module.css';
|
||||
}
|
||||
|
||||
.totalLiquidity {
|
||||
composes: token from './Token.module.css';
|
||||
margin-bottom: 0;
|
||||
font-weight: var(--font-weight-base) !important;
|
||||
font-size: var(--font-size-small);
|
||||
padding-left: var(--font-size-base);
|
||||
padding-top: calc(var(--spacer) / 10);
|
||||
}
|
||||
|
||||
.totalLiquidity strong {
|
||||
font-size: var(--font-size-base);
|
||||
color: var(--font-color-heading);
|
||||
line-height: 1;
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
import Conversion from '@shared/Price/Conversion'
|
||||
import React, { ReactElement, ReactNode } from 'react'
|
||||
import Token from './Token'
|
||||
import styles from './TokenList.module.css'
|
||||
import Decimal from 'decimal.js'
|
||||
|
||||
export default function TokenList({
|
||||
title,
|
||||
children,
|
||||
baseTokenValue,
|
||||
baseTokenSymbol,
|
||||
datatokenValue,
|
||||
datatokenSymbol,
|
||||
conversion,
|
||||
highlight,
|
||||
size = 'small'
|
||||
}: {
|
||||
title?: string | ReactNode
|
||||
children?: ReactNode
|
||||
baseTokenValue: string
|
||||
baseTokenSymbol: string
|
||||
datatokenValue?: string
|
||||
datatokenSymbol?: string
|
||||
conversion?: Decimal
|
||||
highlight?: boolean
|
||||
size?: 'small' | 'mini'
|
||||
}): ReactElement {
|
||||
return (
|
||||
<div className={`${styles.tokenlist} ${highlight ? styles.highlight : ''}`}>
|
||||
{title && <h3 className={styles.title}>{title}</h3>}
|
||||
<div className={styles.tokens}>
|
||||
<Token symbol={baseTokenSymbol} balance={baseTokenValue} size={size} />
|
||||
|
||||
{conversion?.greaterThan(0) && (
|
||||
<Conversion
|
||||
price={conversion.toString()}
|
||||
className={styles.totalLiquidity}
|
||||
/>
|
||||
)}
|
||||
{datatokenValue && (
|
||||
<Token
|
||||
symbol={datatokenSymbol}
|
||||
balance={datatokenValue}
|
||||
size={size}
|
||||
/>
|
||||
)}
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
.container {
|
||||
margin-left: -2rem;
|
||||
margin-right: -2rem;
|
||||
padding-left: calc(var(--spacer) / 1.5);
|
||||
padding-right: calc(var(--spacer) / 1.5);
|
||||
}
|
||||
|
||||
.dataToken {
|
||||
composes: container;
|
||||
padding-bottom: calc(var(--spacer) / 1.5);
|
||||
font-size: var(--font-size-large);
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dataTokenLinks {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-size: var(--font-size-small);
|
||||
margin-top: calc(var(--spacer) / 4);
|
||||
}
|
||||
|
||||
.dataTokenLinks a {
|
||||
margin-left: calc(var(--spacer) / 3);
|
||||
margin-right: calc(var(--spacer) / 3);
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: var(--font-size-base);
|
||||
margin-bottom: calc(var(--spacer) / 3);
|
||||
color: var(--color-secondary);
|
||||
}
|
||||
|
||||
.titleInfo {
|
||||
font-size: var(--font-size-mini);
|
||||
font-family: var(--font-family-base);
|
||||
font-weight: var(--font-weight-base);
|
||||
display: inline-block;
|
||||
margin-left: 0.3rem;
|
||||
}
|
||||
|
||||
.update {
|
||||
composes: container;
|
||||
font-size: var(--font-size-mini);
|
||||
color: var(--color-secondary);
|
||||
text-align: center;
|
||||
border-top: 1px solid var(--border-color);
|
||||
padding-top: calc(var(--spacer) / 4);
|
||||
padding-bottom: calc(var(--spacer) / 4);
|
||||
}
|
||||
|
||||
/* .update:before {
|
||||
content: '';
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
border: 1px solid var(--brand-alert-green);
|
||||
margin-right: 0.2rem;
|
||||
margin-top: -0.1rem;
|
||||
vertical-align: middle;
|
||||
animation: pulse 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
background: transparent;
|
||||
}
|
||||
50% {
|
||||
background: var(--brand-alert-green);
|
||||
}
|
||||
100% {
|
||||
background: transparent;
|
||||
}
|
||||
} */
|
@ -1,37 +1,20 @@
|
||||
import React, { ReactElement, useState } from 'react'
|
||||
import styles from './index.module.css'
|
||||
import stylesActions from './Actions.module.css'
|
||||
import PriceUnit from '@shared/Price/PriceUnit'
|
||||
import stylesActions from './Actions/index.module.css'
|
||||
import Button from '@shared/atoms/Button'
|
||||
import Add from './Add'
|
||||
import Remove from './Remove'
|
||||
import Tooltip from '@shared/atoms/Tooltip'
|
||||
import ExplorerLink from '@shared/ExplorerLink'
|
||||
import TokenList from './TokenList'
|
||||
import AssetActionHistoryTable from '../AssetActionHistoryTable'
|
||||
import Graph from './Graph'
|
||||
import { useAsset } from '@context/Asset'
|
||||
import { useWeb3 } from '@context/Web3'
|
||||
import PoolTransactions from '@shared/PoolTransactions'
|
||||
import Decimal from 'decimal.js'
|
||||
import content from '../../../../../content/price.json'
|
||||
|
||||
import { usePool } from '@context/Pool'
|
||||
import Token from './Token'
|
||||
import PoolSections from './Sections'
|
||||
|
||||
export default function Pool(): ReactElement {
|
||||
const { accountId } = useWeb3()
|
||||
const { isInPurgatory, asset, isAssetNetwork } = useAsset()
|
||||
const {
|
||||
poolData,
|
||||
poolInfo,
|
||||
poolInfoUser,
|
||||
poolInfoOwner,
|
||||
poolSnapshots,
|
||||
hasUserAddedLiquidity,
|
||||
isRemoveDisabled,
|
||||
fetchAllData
|
||||
// refreshInterval
|
||||
} = usePool()
|
||||
const { hasUserAddedLiquidity, isRemoveDisabled } = usePool()
|
||||
const { accountId } = useWeb3()
|
||||
|
||||
const [showAdd, setShowAdd] = useState(false)
|
||||
const [showRemove, setShowRemove] = useState(false)
|
||||
@ -39,150 +22,13 @@ export default function Pool(): ReactElement {
|
||||
return (
|
||||
<>
|
||||
{showAdd ? (
|
||||
<Add
|
||||
setShowAdd={setShowAdd}
|
||||
poolAddress={asset?.accessDetails?.addressOrId}
|
||||
totalPoolTokens={poolInfo?.totalPoolTokens}
|
||||
totalBalance={{
|
||||
baseToken: new Decimal(poolData?.baseTokenLiquidity).toString(),
|
||||
datatoken: new Decimal(poolData?.datatokenLiquidity).toString()
|
||||
}}
|
||||
swapFee={poolInfo?.liquidityProviderSwapFee}
|
||||
datatokenSymbol={poolInfo?.datatokenSymbol}
|
||||
tokenInAddress={poolInfo?.baseTokenAddress}
|
||||
tokenInSymbol={poolInfo?.baseTokenSymbol}
|
||||
/>
|
||||
<Add setShowAdd={setShowAdd} />
|
||||
) : showRemove ? (
|
||||
<Remove
|
||||
setShowRemove={setShowRemove}
|
||||
poolAddress={asset?.accessDetails?.addressOrId}
|
||||
poolTokens={poolInfoUser?.poolShares}
|
||||
totalPoolTokens={poolInfo?.totalPoolTokens}
|
||||
tokenOutAddress={poolInfo?.baseTokenAddress}
|
||||
tokenOutSymbol={poolInfo?.baseTokenSymbol}
|
||||
/>
|
||||
<Remove setShowRemove={setShowRemove} />
|
||||
) : (
|
||||
<>
|
||||
<div className={styles.dataToken}>
|
||||
<PriceUnit
|
||||
price="1"
|
||||
symbol={poolInfo?.datatokenSymbol}
|
||||
size="large"
|
||||
/>{' '}
|
||||
={' '}
|
||||
<PriceUnit
|
||||
price={`${poolData?.spotPrice}`}
|
||||
symbol={poolInfo?.baseTokenSymbol}
|
||||
size="large"
|
||||
/>
|
||||
<Tooltip content={content.pool.tooltips.price} />
|
||||
<div className={styles.dataTokenLinks}>
|
||||
<ExplorerLink
|
||||
networkId={asset?.chainId}
|
||||
path={`address/${asset?.accessDetails?.addressOrId}`}
|
||||
>
|
||||
Pool
|
||||
</ExplorerLink>
|
||||
<ExplorerLink
|
||||
networkId={asset?.chainId}
|
||||
path={
|
||||
asset?.chainId === 2021000 || asset?.chainId === 1287
|
||||
? `tokens/${asset?.services[0].datatokenAddress}`
|
||||
: `token/${asset?.services[0].datatokenAddress}`
|
||||
}
|
||||
>
|
||||
Datatoken
|
||||
</ExplorerLink>
|
||||
</div>
|
||||
</div>
|
||||
<TokenList
|
||||
title={
|
||||
<>
|
||||
Your Value Locked
|
||||
<Tooltip
|
||||
content={content.pool.tooltips.liquidity.replace(
|
||||
'SWAPFEE',
|
||||
poolInfo?.liquidityProviderSwapFee
|
||||
)}
|
||||
/>
|
||||
{poolInfoUser?.poolShare && (
|
||||
<span className={styles.titleInfo}>
|
||||
{poolInfoUser?.poolShare}% of pool
|
||||
</span>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
baseTokenValue={poolInfoUser?.liquidity.toString()}
|
||||
baseTokenSymbol={poolInfo?.baseTokenSymbol}
|
||||
conversion={poolInfoUser?.liquidity}
|
||||
highlight
|
||||
/>
|
||||
<TokenList
|
||||
title={
|
||||
<>
|
||||
Owner Value Locked
|
||||
<span className={styles.titleInfo}>
|
||||
{poolInfoOwner?.poolShare}% of pool
|
||||
</span>
|
||||
</>
|
||||
}
|
||||
baseTokenValue={poolInfoOwner?.liquidity.toString()}
|
||||
baseTokenSymbol={poolInfo?.baseTokenSymbol}
|
||||
conversion={poolInfoOwner?.liquidity}
|
||||
/>
|
||||
<TokenList
|
||||
title={
|
||||
<>
|
||||
Pool Statistics
|
||||
{poolInfo?.weightDt && (
|
||||
<span
|
||||
className={styles.titleInfo}
|
||||
title={`Weight of ${poolInfo?.weightBaseToken}% ${poolInfo?.baseTokenSymbol} & ${poolInfo?.weightDt}% ${poolInfo?.datatokenSymbol}`}
|
||||
>
|
||||
{poolInfo?.weightBaseToken}/{poolInfo?.weightDt}
|
||||
</span>
|
||||
)}
|
||||
<Graph poolSnapshots={poolSnapshots} />
|
||||
</>
|
||||
}
|
||||
baseTokenValue={`${poolInfo?.totalLiquidityInOcean}`}
|
||||
baseTokenSymbol={poolInfo?.baseTokenSymbol}
|
||||
conversion={poolInfo?.totalLiquidityInOcean}
|
||||
/>
|
||||
<PoolSections />
|
||||
|
||||
<TokenList
|
||||
size="mini"
|
||||
baseTokenValue={`${poolData?.baseTokenLiquidity}`}
|
||||
baseTokenSymbol={poolInfo?.baseTokenSymbol}
|
||||
datatokenValue={`${poolData?.datatokenLiquidity}`}
|
||||
datatokenSymbol={poolInfo?.datatokenSymbol}
|
||||
>
|
||||
<Token
|
||||
symbol="% pool fee"
|
||||
balance={poolInfo?.liquidityProviderSwapFee}
|
||||
noIcon
|
||||
size="mini"
|
||||
/>
|
||||
<Token
|
||||
symbol="% market fee"
|
||||
balance={poolInfo?.publishMarketSwapFee}
|
||||
noIcon
|
||||
size="mini"
|
||||
/>
|
||||
<Token
|
||||
symbol="% OPF fee"
|
||||
balance={poolInfo?.opcFee}
|
||||
noIcon
|
||||
size="mini"
|
||||
/>
|
||||
</TokenList>
|
||||
|
||||
<div className={styles.update}>
|
||||
<Button style="text" size="small" onClick={() => fetchAllData()}>
|
||||
Refresh Data
|
||||
</Button>
|
||||
{/* Fetching every {refreshInterval / 1000} sec. */}
|
||||
</div>
|
||||
<div className={stylesActions.actions}>
|
||||
<Button
|
||||
style="primary"
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { FormikContextType, useFormikContext } from 'formik'
|
||||
import React, { ReactElement, useEffect, useState } from 'react'
|
||||
import { useAsset } from '@context/Asset'
|
||||
import Token from '../Pool/Token'
|
||||
import Token from '../../../@shared/Token'
|
||||
import styles from './Output.module.css'
|
||||
|
||||
import Decimal from 'decimal.js'
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react'
|
||||
import Conversion from '@shared/Price/Conversion'
|
||||
import styles from './Liquidity.module.css'
|
||||
import Token from '../../../Asset/AssetActions/Pool/Token'
|
||||
import Token from '../../../@shared/Token'
|
||||
import { isValidNumber } from '@utils/numbers'
|
||||
import Decimal from 'decimal.js'
|
||||
import { AssetPoolShare } from './index'
|
||||
|
Loading…
Reference in New Issue
Block a user