add est liq price to balances table (#366)
* add est liq price to balances * add est liq price tooltip
This commit is contained in:
parent
ad27c58ea9
commit
089579f27d
|
@ -1,16 +1,24 @@
|
|||
import { useCallback, useState } from 'react'
|
||||
import { useCallback, useMemo, useState } from 'react'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import Button, { LinkButton } from '../components/Button'
|
||||
import Button from '../components/Button'
|
||||
import { notify } from '../utils/notifications'
|
||||
import { ArrowSmDownIcon, ExclamationIcon } from '@heroicons/react/solid'
|
||||
import { ExclamationIcon, InformationCircleIcon } from '@heroicons/react/solid'
|
||||
import { Market } from '@project-serum/serum'
|
||||
import { getTokenBySymbol } from '@blockworks-foundation/mango-client'
|
||||
import {
|
||||
getMarketIndexBySymbol,
|
||||
getTokenBySymbol,
|
||||
ZERO_I80F48,
|
||||
} from '@blockworks-foundation/mango-client'
|
||||
import Loading from './Loading'
|
||||
import { useViewport } from '../hooks/useViewport'
|
||||
import { breakpoints } from './TradePageGrid'
|
||||
import { floorToDecimal, formatUsdValue, getPrecisionDigits } from '../utils'
|
||||
import {
|
||||
floorToDecimal,
|
||||
formatUsdValue,
|
||||
getPrecisionDigits,
|
||||
usdFormatter,
|
||||
} from '../utils'
|
||||
import { ExpandableRow, Table, Td, Th, TrBody, TrHead } from './TableElements'
|
||||
import { useSortableData } from '../hooks/useSortableData'
|
||||
import DepositModal from './DepositModal'
|
||||
import WithdrawModal from './WithdrawModal'
|
||||
import MobileTableHeader from './mobile/MobileTableHeader'
|
||||
|
@ -19,6 +27,7 @@ import { TransactionSignature } from '@solana/web3.js'
|
|||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useWallet } from '@solana/wallet-adapter-react'
|
||||
import Tooltip from './Tooltip'
|
||||
|
||||
const BalancesTable = ({
|
||||
showZeroBalances = false,
|
||||
|
@ -30,8 +39,9 @@ const BalancesTable = ({
|
|||
const [showWithdrawModal, setShowWithdrawModal] = useState(false)
|
||||
const [actionSymbol, setActionSymbol] = useState('')
|
||||
const spotBalances = useMangoStore((s) => s.selectedMangoAccount.spotBalances)
|
||||
const { items, requestSort, sortConfig } = useSortableData(
|
||||
spotBalances?.length > 0
|
||||
|
||||
const balances = useMemo(() => {
|
||||
return spotBalances?.length > 0
|
||||
? spotBalances
|
||||
.filter((bal) => {
|
||||
return (
|
||||
|
@ -48,10 +58,12 @@ const BalancesTable = ({
|
|||
return bV - aV
|
||||
})
|
||||
: []
|
||||
)
|
||||
}, [spotBalances])
|
||||
|
||||
const actions = useMangoStore((s) => s.actions)
|
||||
const mangoGroup = useMangoStore((s) => s.selectedMangoGroup.current)
|
||||
const mangoGroupConfig = useMangoStore((s) => s.selectedMangoGroup.config)
|
||||
const mangoCache = useMangoStore((s) => s.selectedMangoGroup.cache)
|
||||
const selectedMarket = useMangoStore((s) => s.selectedMarket.current)
|
||||
const marketConfig = useMangoStore((s) => s.selectedMarket.config)
|
||||
const setMangoStore = useMangoStore((s) => s.set)
|
||||
|
@ -248,168 +260,35 @@ const BalancesTable = ({
|
|||
) : null}
|
||||
<div className={`md:overflow-x-auto`}>
|
||||
<div className={`inline-block min-w-full align-middle`}>
|
||||
{items.length > 0 ? (
|
||||
{balances.length > 0 ? (
|
||||
!isMobile ? (
|
||||
<Table>
|
||||
<thead>
|
||||
<TrHead>
|
||||
<Th>{t('asset')}</Th>
|
||||
<Th>{t('deposits')}</Th>
|
||||
<Th>{t('borrows')}</Th>
|
||||
<Th>{t('in-orders')}</Th>
|
||||
<Th>{t('unsettled')}</Th>
|
||||
<Th>{t('net-balance')}</Th>
|
||||
<Th>{t('value')}</Th>
|
||||
<Th>
|
||||
<LinkButton
|
||||
className="flex items-center text-left no-underline"
|
||||
onClick={() => requestSort('symbol')}
|
||||
>
|
||||
<span className="font-normal">{t('asset')}</span>
|
||||
<ArrowSmDownIcon
|
||||
className={`default-transition ml-1 h-4 w-4 flex-shrink-0 ${
|
||||
sortConfig?.key === 'symbol'
|
||||
? sortConfig.direction === 'ascending'
|
||||
? 'rotate-180 transform'
|
||||
: 'rotate-360 transform'
|
||||
: null
|
||||
}`}
|
||||
/>
|
||||
</LinkButton>
|
||||
<Tooltip content={t('tooltip-estimated-liq-price')}>
|
||||
<span className="flex items-center">
|
||||
{t('estimated-liq-price')}
|
||||
<InformationCircleIcon className="ml-1 h-4 w-4 flex-shrink-0 text-th-fgd-4" />
|
||||
</span>
|
||||
</Tooltip>
|
||||
</Th>
|
||||
<Th>
|
||||
<LinkButton
|
||||
className="flex items-center text-left no-underline"
|
||||
onClick={() => requestSort('deposits')}
|
||||
>
|
||||
<span className="font-normal">{t('deposits')}</span>
|
||||
<ArrowSmDownIcon
|
||||
className={`default-transition ml-1 h-4 w-4 flex-shrink-0 ${
|
||||
sortConfig?.key === 'deposits'
|
||||
? sortConfig.direction === 'ascending'
|
||||
? 'rotate-180 transform'
|
||||
: 'rotate-360 transform'
|
||||
: null
|
||||
}`}
|
||||
/>
|
||||
</LinkButton>
|
||||
</Th>
|
||||
<Th>
|
||||
<LinkButton
|
||||
className="flex items-center text-left no-underline"
|
||||
onClick={() => requestSort('borrows')}
|
||||
>
|
||||
<span className="font-normal">{t('borrows')}</span>
|
||||
<ArrowSmDownIcon
|
||||
className={`default-transition ml-1 h-4 w-4 flex-shrink-0 ${
|
||||
sortConfig?.key === 'borrows'
|
||||
? sortConfig.direction === 'ascending'
|
||||
? 'rotate-180 transform'
|
||||
: 'rotate-360 transform'
|
||||
: null
|
||||
}`}
|
||||
/>
|
||||
</LinkButton>
|
||||
</Th>
|
||||
<Th>
|
||||
<LinkButton
|
||||
className="flex items-center text-left no-underline"
|
||||
onClick={() => requestSort('orders')}
|
||||
>
|
||||
<span className="font-normal">{t('in-orders')}</span>
|
||||
<ArrowSmDownIcon
|
||||
className={`default-transition ml-1 h-4 w-4 flex-shrink-0 ${
|
||||
sortConfig?.key === 'orders'
|
||||
? sortConfig.direction === 'ascending'
|
||||
? 'rotate-180 transform'
|
||||
: 'rotate-360 transform'
|
||||
: null
|
||||
}`}
|
||||
/>
|
||||
</LinkButton>
|
||||
</Th>
|
||||
<Th>
|
||||
<LinkButton
|
||||
className="flex items-center text-left no-underline"
|
||||
onClick={() => requestSort('unsettled')}
|
||||
>
|
||||
<span className="font-normal">{t('unsettled')}</span>
|
||||
<ArrowSmDownIcon
|
||||
className={`default-transition ml-1 h-4 w-4 flex-shrink-0 ${
|
||||
sortConfig?.key === 'unsettled'
|
||||
? sortConfig.direction === 'ascending'
|
||||
? 'rotate-180 transform'
|
||||
: 'rotate-360 transform'
|
||||
: null
|
||||
}`}
|
||||
/>
|
||||
</LinkButton>
|
||||
</Th>
|
||||
<Th>
|
||||
<LinkButton
|
||||
className="flex items-center text-left no-underline"
|
||||
onClick={() => requestSort('net')}
|
||||
>
|
||||
<span className="font-normal">{t('net-balance')}</span>
|
||||
<ArrowSmDownIcon
|
||||
className={`default-transition ml-1 h-4 w-4 flex-shrink-0 ${
|
||||
sortConfig?.key === 'net'
|
||||
? sortConfig.direction === 'ascending'
|
||||
? 'rotate-180 transform'
|
||||
: 'rotate-360 transform'
|
||||
: null
|
||||
}`}
|
||||
/>
|
||||
</LinkButton>
|
||||
</Th>
|
||||
<Th>
|
||||
<LinkButton
|
||||
className="flex items-center text-left no-underline"
|
||||
onClick={() => requestSort('value')}
|
||||
>
|
||||
<span className="font-normal">{t('value')}</span>
|
||||
<ArrowSmDownIcon
|
||||
className={`default-transition ml-1 h-4 w-4 flex-shrink-0 ${
|
||||
sortConfig?.key === 'value'
|
||||
? sortConfig.direction === 'ascending'
|
||||
? 'rotate-180 transform'
|
||||
: 'rotate-360 transform'
|
||||
: null
|
||||
}`}
|
||||
/>
|
||||
</LinkButton>
|
||||
</Th>
|
||||
<Th>
|
||||
<LinkButton
|
||||
className="flex items-center text-left no-underline"
|
||||
onClick={() => requestSort('depositRate')}
|
||||
>
|
||||
<span className="font-normal">{t('deposit-rate')}</span>
|
||||
<ArrowSmDownIcon
|
||||
className={`default-transition ml-1 h-4 w-4 flex-shrink-0 ${
|
||||
sortConfig?.key === 'depositRate'
|
||||
? sortConfig.direction === 'ascending'
|
||||
? 'rotate-180 transform'
|
||||
: 'rotate-360 transform'
|
||||
: null
|
||||
}`}
|
||||
/>
|
||||
</LinkButton>
|
||||
</Th>
|
||||
<Th>
|
||||
<LinkButton
|
||||
className="flex items-center text-left no-underline"
|
||||
onClick={() => requestSort('borrowRate')}
|
||||
>
|
||||
<span className="font-normal">{t('borrow-rate')}</span>
|
||||
<ArrowSmDownIcon
|
||||
className={`default-transition ml-1 h-4 w-4 flex-shrink-0 ${
|
||||
sortConfig?.key === 'borrowRate'
|
||||
? sortConfig.direction === 'ascending'
|
||||
? 'rotate-180 transform'
|
||||
: 'rotate-360 transform'
|
||||
: null
|
||||
}`}
|
||||
/>
|
||||
</LinkButton>
|
||||
{t('deposit')}
|
||||
<span className="mx-1 text-th-fgd-4">|</span>
|
||||
{t('borrow')} (APR)
|
||||
</Th>
|
||||
</TrHead>
|
||||
</thead>
|
||||
<tbody>
|
||||
{items.map((balance, index) => {
|
||||
{balances.map((balance, index) => {
|
||||
if (
|
||||
!balance ||
|
||||
typeof balance.decimals !== 'number' ||
|
||||
|
@ -422,6 +301,25 @@ const BalancesTable = ({
|
|||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
const marketIndex = getMarketIndexBySymbol(
|
||||
mangoGroupConfig,
|
||||
balance.symbol
|
||||
)
|
||||
|
||||
const liquidationPrice =
|
||||
mangoGroup &&
|
||||
mangoAccount &&
|
||||
marketIndex &&
|
||||
mangoGroup &&
|
||||
mangoCache
|
||||
? mangoAccount.getLiquidationPrice(
|
||||
mangoGroup,
|
||||
mangoCache,
|
||||
marketIndex
|
||||
)
|
||||
: undefined
|
||||
|
||||
return (
|
||||
<TrBody key={`${balance.symbol}${index}`}>
|
||||
<Td>
|
||||
|
@ -498,12 +396,16 @@ const BalancesTable = ({
|
|||
)}
|
||||
</Td>
|
||||
<Td>{formatUsdValue(balance.value.toNumber())}</Td>
|
||||
<Td>
|
||||
{liquidationPrice && liquidationPrice.gt(ZERO_I80F48)
|
||||
? usdFormatter(liquidationPrice)
|
||||
: '–'}
|
||||
</Td>
|
||||
<Td>
|
||||
<span className="text-th-green">
|
||||
{balance.depositRate.toFixed(2)}%
|
||||
</span>
|
||||
</Td>
|
||||
<Td>
|
||||
<span className="mx-1 text-th-fgd-4">|</span>
|
||||
<span className="text-th-red">
|
||||
{balance.borrowRate.toFixed(2)}%
|
||||
</span>
|
||||
|
@ -564,7 +466,7 @@ const BalancesTable = ({
|
|||
colOneHeader={t('asset')}
|
||||
colTwoHeader={t('net-balance')}
|
||||
/>
|
||||
{items.map((balance, index) => {
|
||||
{balances.map((balance, index) => {
|
||||
if (
|
||||
!balance ||
|
||||
typeof balance.decimals !== 'number' ||
|
||||
|
@ -579,6 +481,23 @@ const BalancesTable = ({
|
|||
) {
|
||||
return null
|
||||
}
|
||||
const marketIndex = getMarketIndexBySymbol(
|
||||
mangoGroupConfig,
|
||||
balance.symbol
|
||||
)
|
||||
|
||||
const liquidationPrice =
|
||||
mangoGroup &&
|
||||
mangoAccount &&
|
||||
marketIndex &&
|
||||
mangoGroup &&
|
||||
mangoCache
|
||||
? mangoAccount.getLiquidationPrice(
|
||||
mangoGroup,
|
||||
mangoCache,
|
||||
marketIndex
|
||||
)
|
||||
: undefined
|
||||
return (
|
||||
<ExpandableRow
|
||||
buttonTemplate={
|
||||
|
@ -637,15 +556,33 @@ const BalancesTable = ({
|
|||
</div>
|
||||
{formatUsdValue(balance.value.toNumber())}
|
||||
</div>
|
||||
<div className="text-left">
|
||||
<div className="pb-0.5 text-xs text-th-fgd-3">
|
||||
<Tooltip
|
||||
content={t('tooltip-estimated-liq-price')}
|
||||
>
|
||||
<span className="flex items-center">
|
||||
{t('estimated-liq-price')}
|
||||
<InformationCircleIcon className="ml-1 h-4 w-4 flex-shrink-0 text-th-fgd-4" />
|
||||
</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
{liquidationPrice &&
|
||||
liquidationPrice.gt(ZERO_I80F48)
|
||||
? usdFormatter(liquidationPrice)
|
||||
: '–'}
|
||||
</div>
|
||||
<div className="text-left text-th-fgd-4">
|
||||
<div className="pb-0.5 text-xs text-th-fgd-3">
|
||||
{t('rates')}
|
||||
<span>{t('deposit')}</span>
|
||||
<span className="mx-1 text-th-fgd-4">|</span>
|
||||
<span>{`${t('borrow')} (APR)`}</span>
|
||||
</div>
|
||||
<span className="mr-1 text-th-green">
|
||||
<span className="text-th-green">
|
||||
{balance.depositRate.toFixed(2)}%
|
||||
</span>
|
||||
/
|
||||
<span className="ml-1 text-th-red">
|
||||
<span className="mx-1 text-th-fgd-4">|</span>
|
||||
<span className="text-th-red">
|
||||
{balance.borrowRate.toFixed(2)}%
|
||||
</span>
|
||||
</div>
|
||||
|
@ -666,6 +603,7 @@ const BalancesTable = ({
|
|||
onClick={() =>
|
||||
handleOpenWithdrawModal(balance.symbol)
|
||||
}
|
||||
primary={false}
|
||||
>
|
||||
{t('withdraw')}
|
||||
</Button>
|
||||
|
|
|
@ -559,7 +559,14 @@ const PositionsTable: React.FC = () => {
|
|||
</div>
|
||||
<div className="col-span-1 text-left">
|
||||
<div className="pb-0.5 text-xs text-th-fgd-3">
|
||||
{t('estimated-liq-price')}
|
||||
<Tooltip
|
||||
content={t('tooltip-estimated-liq-price')}
|
||||
>
|
||||
<span className="flex items-center">
|
||||
{t('estimated-liq-price')}
|
||||
<InformationCircleIcon className="ml-1 h-4 w-4 flex-shrink-0 text-th-fgd-4" />
|
||||
</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
{liquidationPrice &&
|
||||
liquidationPrice.gt(ZERO_I80F48)
|
||||
|
|
Loading…
Reference in New Issue