2021-08-04 11:31:32 -07:00
|
|
|
import {
|
2021-08-16 14:35:40 -07:00
|
|
|
I80F48,
|
2021-08-23 12:35:59 -07:00
|
|
|
nativeI80F48ToUi,
|
2021-08-04 11:31:32 -07:00
|
|
|
nativeToUi,
|
2021-08-20 05:50:48 -07:00
|
|
|
QUOTE_INDEX,
|
2021-08-04 11:31:32 -07:00
|
|
|
ZERO_BN,
|
|
|
|
ZERO_I80F48,
|
|
|
|
} from '@blockworks-foundation/mango-client'
|
2021-09-04 15:20:49 -07:00
|
|
|
import { useCallback, useState } from 'react'
|
2021-10-04 18:55:29 -07:00
|
|
|
import { ExclamationIcon, HeartIcon } from '@heroicons/react/solid'
|
2021-09-13 14:14:59 -07:00
|
|
|
import useMangoStore, { MNGO_INDEX } from '../stores/useMangoStore'
|
2021-08-23 12:35:59 -07:00
|
|
|
import { formatUsdValue, usdFormatter } from '../utils'
|
2021-08-04 11:31:32 -07:00
|
|
|
import { notify } from '../utils/notifications'
|
2021-08-05 11:55:18 -07:00
|
|
|
import { LinkButton } from './Button'
|
2021-08-04 14:47:05 -07:00
|
|
|
import { ElementTitle } from './styles'
|
2021-04-16 11:16:31 -07:00
|
|
|
import Tooltip from './Tooltip'
|
2021-08-16 06:31:25 -07:00
|
|
|
import DepositModal from './DepositModal'
|
|
|
|
import WithdrawModal from './WithdrawModal'
|
|
|
|
import Button from './Button'
|
2021-08-21 06:02:51 -07:00
|
|
|
import { DataLoader } from './MarketPosition'
|
2021-09-19 17:36:02 -07:00
|
|
|
import { useViewport } from '../hooks/useViewport'
|
|
|
|
import { breakpoints } from './TradePageGrid'
|
2021-07-05 08:03:57 -07:00
|
|
|
|
2021-08-16 14:35:40 -07:00
|
|
|
const I80F48_100 = I80F48.fromString('100')
|
|
|
|
|
2021-08-23 12:35:59 -07:00
|
|
|
export default function AccountInfo() {
|
2021-07-22 04:34:03 -07:00
|
|
|
const connected = useMangoStore((s) => s.wallet.connected)
|
2021-06-20 11:08:14 -07:00
|
|
|
const mangoGroup = useMangoStore((s) => s.selectedMangoGroup.current)
|
|
|
|
const mangoCache = useMangoStore((s) => s.selectedMangoGroup.cache)
|
2021-07-06 17:13:17 -07:00
|
|
|
const mangoAccount = useMangoStore((s) => s.selectedMangoAccount.current)
|
2021-08-20 06:17:02 -07:00
|
|
|
const isLoading = useMangoStore((s) => s.selectedMangoAccount.initialLoad)
|
2021-08-23 12:35:59 -07:00
|
|
|
const marketConfig = useMangoStore((s) => s.selectedMarket.config)
|
2021-09-13 14:14:59 -07:00
|
|
|
const mangoClient = useMangoStore((s) => s.connection.client)
|
2021-08-04 11:31:32 -07:00
|
|
|
const actions = useMangoStore((s) => s.actions)
|
2021-09-19 17:36:02 -07:00
|
|
|
const { width } = useViewport()
|
|
|
|
const isMobile = width ? width < breakpoints.sm : false
|
2021-04-05 07:32:11 -07:00
|
|
|
|
2021-08-16 06:31:25 -07:00
|
|
|
const [showDepositModal, setShowDepositModal] = useState(false)
|
|
|
|
const [showWithdrawModal, setShowWithdrawModal] = useState(false)
|
|
|
|
|
|
|
|
const handleCloseDeposit = useCallback(() => {
|
|
|
|
setShowDepositModal(false)
|
|
|
|
}, [])
|
|
|
|
|
|
|
|
const handleCloseWithdraw = useCallback(() => {
|
|
|
|
setShowWithdrawModal(false)
|
|
|
|
}, [])
|
|
|
|
|
2021-07-07 13:38:04 -07:00
|
|
|
const equity = mangoAccount
|
|
|
|
? mangoAccount.computeValue(mangoGroup, mangoCache)
|
|
|
|
: ZERO_I80F48
|
|
|
|
|
2021-08-05 11:55:18 -07:00
|
|
|
const mngoAccrued = mangoAccount
|
|
|
|
? mangoAccount.perpAccounts.reduce((acc, perpAcct) => {
|
|
|
|
return perpAcct.mngoAccrued.add(acc)
|
|
|
|
}, ZERO_BN)
|
|
|
|
: ZERO_BN
|
2021-08-04 11:31:32 -07:00
|
|
|
|
|
|
|
const handleRedeemMngo = async () => {
|
|
|
|
const wallet = useMangoStore.getState().wallet.current
|
|
|
|
const mngoNodeBank =
|
|
|
|
mangoGroup.rootBankAccounts[MNGO_INDEX].nodeBankAccounts[0]
|
|
|
|
|
|
|
|
try {
|
|
|
|
const txid = await mangoClient.redeemAllMngo(
|
|
|
|
mangoGroup,
|
|
|
|
mangoAccount,
|
|
|
|
wallet,
|
|
|
|
mangoGroup.tokens[MNGO_INDEX].rootBank,
|
|
|
|
mngoNodeBank.publicKey,
|
|
|
|
mngoNodeBank.vault
|
|
|
|
)
|
2021-09-29 15:09:35 -07:00
|
|
|
actions.reloadMangoAccount()
|
2021-08-04 11:31:32 -07:00
|
|
|
notify({
|
|
|
|
title: 'Successfully redeemed MNGO',
|
|
|
|
description: '',
|
|
|
|
txid,
|
|
|
|
})
|
|
|
|
} catch (e) {
|
|
|
|
notify({
|
|
|
|
title: 'Error redeeming MNGO',
|
|
|
|
description: e.message,
|
|
|
|
txid: e.txid,
|
|
|
|
type: 'error',
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-04 15:20:49 -07:00
|
|
|
const maintHealthRatio = mangoAccount
|
|
|
|
? mangoAccount.getHealthRatio(mangoGroup, mangoCache, 'Maint')
|
|
|
|
: I80F48_100
|
2021-08-04 14:47:05 -07:00
|
|
|
|
2021-09-04 15:20:49 -07:00
|
|
|
const initHealthRatio = mangoAccount
|
|
|
|
? mangoAccount.getHealthRatio(mangoGroup, mangoCache, 'Init')
|
|
|
|
: I80F48_100
|
2021-08-04 14:47:05 -07:00
|
|
|
|
2021-09-04 15:41:02 -07:00
|
|
|
const maintHealth = mangoAccount
|
|
|
|
? mangoAccount.getHealth(mangoGroup, mangoCache, 'Maint')
|
|
|
|
: I80F48_100
|
|
|
|
const initHealth = mangoAccount
|
|
|
|
? mangoAccount.getHealth(mangoGroup, mangoCache, 'Init')
|
|
|
|
: I80F48_100
|
|
|
|
|
2021-07-05 08:03:57 -07:00
|
|
|
return (
|
2021-09-19 17:36:02 -07:00
|
|
|
<>
|
|
|
|
<div className={!connected && !isMobile ? 'filter blur-sm' : undefined}>
|
|
|
|
{!isMobile ? (
|
|
|
|
<ElementTitle>
|
|
|
|
<Tooltip
|
|
|
|
content={
|
|
|
|
mangoAccount ? (
|
|
|
|
<div>
|
|
|
|
Init Health: {initHealth.toFixed(4)}
|
|
|
|
<br />
|
|
|
|
Maint Health: {maintHealth.toFixed(4)}
|
|
|
|
</div>
|
|
|
|
) : (
|
|
|
|
''
|
|
|
|
)
|
|
|
|
}
|
|
|
|
>
|
|
|
|
Account
|
|
|
|
</Tooltip>
|
|
|
|
</ElementTitle>
|
|
|
|
) : null}
|
2021-07-22 04:34:03 -07:00
|
|
|
<div>
|
2021-07-05 08:03:57 -07:00
|
|
|
<div>
|
2021-08-20 18:42:59 -07:00
|
|
|
<div className="flex justify-between pb-3">
|
2021-08-15 06:31:59 -07:00
|
|
|
<div className="font-normal text-th-fgd-3 leading-4">Equity</div>
|
2021-08-20 06:17:02 -07:00
|
|
|
<div className="text-th-fgd-1">
|
2021-08-21 06:02:51 -07:00
|
|
|
{isLoading ? <DataLoader /> : formatUsdValue(+equity)}
|
2021-08-20 06:17:02 -07:00
|
|
|
</div>
|
2021-07-06 21:34:21 -07:00
|
|
|
</div>
|
2021-08-20 18:42:59 -07:00
|
|
|
<div className="flex justify-between pb-3">
|
2021-07-20 07:21:58 -07:00
|
|
|
<div className="font-normal text-th-fgd-3 leading-4">
|
|
|
|
Leverage
|
|
|
|
</div>
|
2021-08-14 14:14:43 -07:00
|
|
|
<div className="text-th-fgd-1">
|
2021-08-20 06:17:02 -07:00
|
|
|
{isLoading ? (
|
2021-08-21 06:02:51 -07:00
|
|
|
<DataLoader />
|
2021-08-20 06:17:02 -07:00
|
|
|
) : mangoAccount ? (
|
|
|
|
`${mangoAccount
|
|
|
|
.getLeverage(mangoGroup, mangoCache)
|
|
|
|
.toFixed(2)}x`
|
|
|
|
) : (
|
|
|
|
'0.00x'
|
|
|
|
)}
|
2021-08-14 14:14:43 -07:00
|
|
|
</div>
|
2021-08-04 14:47:05 -07:00
|
|
|
</div>
|
2021-08-20 18:42:59 -07:00
|
|
|
<div className={`flex justify-between pb-3`}>
|
2021-08-20 05:50:48 -07:00
|
|
|
<div className="font-normal text-th-fgd-3 leading-4">
|
2021-08-23 12:35:59 -07:00
|
|
|
Collateral Available
|
2021-08-20 05:50:48 -07:00
|
|
|
</div>
|
|
|
|
<div className={`text-th-fgd-1`}>
|
2021-08-21 06:02:51 -07:00
|
|
|
{isLoading ? (
|
|
|
|
<DataLoader />
|
|
|
|
) : mangoAccount ? (
|
2021-08-23 12:35:59 -07:00
|
|
|
usdFormatter(
|
|
|
|
nativeI80F48ToUi(
|
2021-09-04 15:41:02 -07:00
|
|
|
initHealth,
|
2021-08-23 12:35:59 -07:00
|
|
|
mangoGroup.tokens[QUOTE_INDEX].decimals
|
|
|
|
).toFixed()
|
|
|
|
)
|
2021-08-21 06:02:51 -07:00
|
|
|
) : (
|
|
|
|
'--'
|
|
|
|
)}
|
2021-08-20 05:50:48 -07:00
|
|
|
</div>
|
|
|
|
</div>
|
2021-08-23 12:35:59 -07:00
|
|
|
<div className={`flex justify-between pb-3`}>
|
|
|
|
<div className="font-normal text-th-fgd-3 leading-4">
|
|
|
|
{marketConfig.name} Margin Available
|
|
|
|
</div>
|
|
|
|
<div className={`text-th-fgd-1`}>
|
|
|
|
{mangoAccount
|
|
|
|
? usdFormatter(
|
|
|
|
nativeI80F48ToUi(
|
|
|
|
mangoAccount.getMarketMarginAvailable(
|
|
|
|
mangoGroup,
|
|
|
|
mangoCache,
|
|
|
|
marketConfig.marketIndex,
|
|
|
|
marketConfig.kind
|
|
|
|
),
|
2021-08-31 18:27:13 -07:00
|
|
|
mangoGroup.tokens[QUOTE_INDEX].decimals
|
2021-08-23 12:35:59 -07:00
|
|
|
).toFixed()
|
|
|
|
)
|
|
|
|
: '0.00'}
|
|
|
|
</div>
|
|
|
|
</div>
|
2021-08-20 18:42:59 -07:00
|
|
|
<div className={`flex justify-between pb-3`}>
|
2021-08-04 12:25:56 -07:00
|
|
|
<Tooltip
|
|
|
|
content={
|
|
|
|
<div>
|
2021-08-05 07:07:29 -07:00
|
|
|
Earn MNGO by market making on Perp markets.{' '}
|
2021-08-04 12:25:56 -07:00
|
|
|
<a
|
|
|
|
href="https://docs.mango.markets/mango-v3/liquidity-incentives"
|
|
|
|
target="_blank"
|
|
|
|
rel="noopener noreferrer"
|
|
|
|
>
|
|
|
|
Learn more
|
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
}
|
|
|
|
>
|
|
|
|
<div className="cursor-help font-normal text-th-fgd-3 leading-4 border-b border-th-fgd-3 border-dashed border-opacity-20 default-transition hover:border-th-bkg-2">
|
2021-08-05 07:07:29 -07:00
|
|
|
MNGO Rewards
|
2021-08-04 12:25:56 -07:00
|
|
|
</div>
|
|
|
|
</Tooltip>
|
2021-08-05 07:07:29 -07:00
|
|
|
<div className={`flex items-center text-th-fgd-1`}>
|
2021-08-20 06:17:02 -07:00
|
|
|
{isLoading ? (
|
2021-08-21 06:02:51 -07:00
|
|
|
<DataLoader />
|
2021-08-20 06:17:02 -07:00
|
|
|
) : mangoGroup ? (
|
|
|
|
nativeToUi(
|
|
|
|
mngoAccrued.toNumber(),
|
|
|
|
mangoGroup.tokens[MNGO_INDEX].decimals
|
|
|
|
)
|
|
|
|
) : (
|
|
|
|
0
|
|
|
|
)}
|
2021-08-05 07:07:29 -07:00
|
|
|
<LinkButton
|
|
|
|
onClick={handleRedeemMngo}
|
2021-08-16 06:31:25 -07:00
|
|
|
className="ml-2 text-th-primary text-xs disabled:cursor-not-allowed disabled:opacity-60 disabled:hover:underline"
|
2021-08-05 07:07:29 -07:00
|
|
|
disabled={mngoAccrued.eq(ZERO_BN)}
|
|
|
|
>
|
|
|
|
Claim
|
|
|
|
</LinkButton>
|
2021-08-04 11:31:32 -07:00
|
|
|
</div>
|
|
|
|
</div>
|
2021-07-05 08:03:57 -07:00
|
|
|
</div>
|
2021-09-19 17:36:02 -07:00
|
|
|
<div className="border border-th-bkg-4 rounded flex items-center my-2 sm:my-3 p-2.5">
|
2021-08-16 06:31:25 -07:00
|
|
|
<div className="flex items-center pr-2">
|
|
|
|
<HeartIcon
|
|
|
|
className="h-5 mr-1.5 w-5 text-th-primary"
|
|
|
|
aria-hidden="true"
|
|
|
|
/>
|
|
|
|
<span>
|
|
|
|
<Tooltip
|
|
|
|
content={
|
|
|
|
<div>
|
2021-10-11 14:46:52 -07:00
|
|
|
Account will be liquidated if Health Ratio reaches 0% and
|
|
|
|
will continue until Init Health is above 0.{' '}
|
2021-08-16 06:31:25 -07:00
|
|
|
<a
|
|
|
|
href="https://docs.mango.markets/mango-v3/overview#health"
|
|
|
|
target="_blank"
|
|
|
|
rel="noopener noreferrer"
|
|
|
|
>
|
|
|
|
Learn more
|
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
}
|
|
|
|
>
|
|
|
|
<div className="cursor-help font-normal text-th-fgd-3 leading-4 border-b border-th-fgd-3 border-dashed border-opacity-20 default-transition hover:border-th-bkg-2">
|
|
|
|
Health
|
|
|
|
</div>
|
|
|
|
</Tooltip>
|
|
|
|
</span>
|
2021-07-01 07:12:42 -07:00
|
|
|
</div>
|
2021-08-16 06:31:25 -07:00
|
|
|
<div className="h-1.5 flex flex-grow rounded bg-th-bkg-4">
|
|
|
|
<div
|
|
|
|
style={{
|
|
|
|
width: `${maintHealthRatio}%`,
|
|
|
|
}}
|
|
|
|
className={`flex rounded ${
|
2021-08-16 14:35:40 -07:00
|
|
|
maintHealthRatio.toNumber() > 30
|
2021-08-16 06:31:25 -07:00
|
|
|
? 'bg-th-green'
|
2021-08-16 14:35:40 -07:00
|
|
|
: initHealthRatio.toNumber() > 0
|
2021-08-16 06:31:25 -07:00
|
|
|
? 'bg-th-orange'
|
|
|
|
: 'bg-th-red'
|
|
|
|
}`}
|
|
|
|
></div>
|
|
|
|
</div>
|
|
|
|
<div className="pl-2 text-right">
|
2021-08-16 14:35:40 -07:00
|
|
|
{maintHealthRatio.gt(I80F48_100)
|
|
|
|
? '>100'
|
|
|
|
: maintHealthRatio.toFixed(2)}
|
|
|
|
%
|
2021-08-16 06:31:25 -07:00
|
|
|
</div>
|
|
|
|
</div>
|
2021-10-04 19:14:07 -07:00
|
|
|
{mangoAccount && mangoAccount.beingLiquidated ? (
|
2021-10-04 18:55:29 -07:00
|
|
|
<div className="pt-0.5 text-xs sm:text-sm flex items-center justify-center">
|
|
|
|
<ExclamationIcon className="flex-shrink-0 h-5 w-5 mr-1.5 text-th-red" />
|
|
|
|
<span className="text-th-red">You are being liquidated!</span>
|
|
|
|
</div>
|
|
|
|
) : null}
|
2021-09-19 17:36:02 -07:00
|
|
|
<div className={`grid grid-cols-2 grid-rows-1 gap-4 pt-2 sm:pt-4`}>
|
2021-08-16 06:31:25 -07:00
|
|
|
<Button
|
2021-08-25 14:20:59 -07:00
|
|
|
onClick={() => setShowDepositModal(true)}
|
2021-08-16 06:31:25 -07:00
|
|
|
className="w-full"
|
|
|
|
disabled={!connected}
|
|
|
|
>
|
|
|
|
<span>Deposit</span>
|
|
|
|
</Button>
|
|
|
|
<Button
|
|
|
|
onClick={() => setShowWithdrawModal(true)}
|
|
|
|
className="w-full"
|
2021-08-25 03:54:39 -07:00
|
|
|
disabled={!connected || !mangoAccount}
|
2021-08-16 06:31:25 -07:00
|
|
|
>
|
|
|
|
<span>Withdraw</span>
|
|
|
|
</Button>
|
2021-07-05 08:03:57 -07:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2021-08-16 06:31:25 -07:00
|
|
|
{showDepositModal && (
|
|
|
|
<DepositModal isOpen={showDepositModal} onClose={handleCloseDeposit} />
|
|
|
|
)}
|
|
|
|
{showWithdrawModal && (
|
|
|
|
<WithdrawModal
|
|
|
|
isOpen={showWithdrawModal}
|
|
|
|
onClose={handleCloseWithdraw}
|
|
|
|
/>
|
|
|
|
)}
|
2021-09-19 17:36:02 -07:00
|
|
|
</>
|
2021-04-05 07:32:11 -07:00
|
|
|
)
|
|
|
|
}
|