import { ModalProps } from '../../types/modal' import Modal from '../shared/Modal' import mangoStore from '@store/mangoStore' import { notify } from '../../utils/notifications' import Button from '../shared/Button' import { useTranslation } from 'next-i18next' import { useCallback, useEffect, useState } from 'react' import BounceLoader from '../shared/BounceLoader' import { MangoAccount, TokenPosition, toUiDecimalsForQuote, } from '@blockworks-foundation/mango-v4' import { ExclamationCircleIcon, TrashIcon } from '@heroicons/react/20/solid' import useUnsettledPerpPositions from 'hooks/useUnsettledPerpPositions' import { getMultipleAccounts } from '@project-serum/anchor/dist/cjs/utils/rpc' import { formatCurrencyValue } from 'utils/numbers' const CloseAccountModal = ({ isOpen, onClose }: ModalProps) => { const { t } = useTranslation(['close-account']) const [loading, setLoading] = useState(false) const set = mangoStore((s) => s.set) const openOrders = Object.values(mangoStore((s) => s.mangoAccount.openOrders)) const connection = mangoStore.getState().connection const hasOpenOrders = openOrders.length && openOrders.filter((x) => x.length).length > 0 const mangoAccount = mangoStore((s) => s.mangoAccount) const perpPositions = mangoStore((s) => s.mangoAccount.perpPositions) const openPerpPositions = Object.values(perpPositions).filter((p) => p.basePositionLots.toNumber(), ) const group = mangoStore.getState().group const unsettledBalances = Object.values(mangoAccount.spotBalances).filter( (x) => x.unsettled && x.unsettled > 0, ) const unsettledPerpPositions = useUnsettledPerpPositions() const [hasBorrows, setHasBorrows] = useState(false) const [hasOpenPositions, setHasOpenPositions] = useState(false) const [totalAccountSOL, setTotalAccountSOL] = useState(0) const handleCloseMangoAccount = async () => { const client = mangoStore.getState().client const mangoAccount = mangoStore.getState().mangoAccount.current const mangoAccounts = mangoStore.getState().mangoAccounts if (!mangoAccount || !group) return setLoading(true) try { const { signature: tx } = await client.emptyAndCloseMangoAccount( group, mangoAccount, ) if (tx) { const newMangoAccounts = mangoAccounts.filter( (ma) => !ma.publicKey.equals(mangoAccount.publicKey), ) let newCurrentAccount: MangoAccount if (newMangoAccounts[0]) { newCurrentAccount = await newMangoAccounts[0].reload(client) } setLoading(false) onClose() notify({ title: t('account-closed'), type: 'success', txid: tx, }) set((state) => { state.mangoAccounts = newMangoAccounts state.mangoAccount.current = newCurrentAccount }) } } catch (e) { setLoading(false) console.error(e) } } const fetchTotalAccountSOL = useCallback(async () => { if (!mangoAccount?.current) { return } const accountKeys = [ mangoAccount.current!.publicKey, ...mangoAccount.openOrderAccounts.map((x) => x.address), ] const accounts = await getMultipleAccounts(connection, accountKeys) const lamports = accounts.reduce((total, account) => { return total + (account?.account.lamports || 0) }, 0) * 0.000000001 setTotalAccountSOL(lamports) }, [mangoAccount]) useEffect(() => { if (mangoAccount && group) { if ( mangoAccount.current ?.tokensActive() .filter((token: TokenPosition) => token .balance(group.getFirstBankByTokenIndex(token.tokenIndex)) .isNeg(), ).length ) { setHasBorrows(true) } if (openPerpPositions.length || unsettledPerpPositions.length) { setHasOpenPositions(true) } fetchTotalAccountSOL() } }, [mangoAccount, group]) const isDisabled = hasOpenOrders || hasBorrows || hasOpenPositions || !!unsettledBalances.length return (
{loading ? ( ) : (

{t('close-account')}

{!isDisabled ? ( <>

{t('are-you-sure')}:

  1. {t('delete-your-account')}
  2. {t('withdraw-assets-worth', { value: mangoAccount && group ? formatCurrencyValue( toUiDecimalsForQuote( mangoAccount!.current!.getEquity(group), ), ) : 0, })}
  3. {t('recover-x-sol', { amount: totalAccountSOL.toFixed(4), })}
) : ( <>

{t('you-must')}:

{hasBorrows ? (

{t('close-all-borrows')}

) : null} {hasOpenPositions ? (

{t('close-perp-positions')}

) : null} {hasOpenOrders ? (

{t('close-open-orders')}

) : null} {unsettledBalances.length ? (

{t('settle-balances')}

) : null}
)}
)}
) } export default CloseAccountModal