import { FunctionComponent, useState } from 'react' import useMangoStore from '../stores/useMangoStore' import { PerpMarket, ZERO_BN } from '@blockworks-foundation/mango-client' import Button, { LinkButton } from './Button' import { notify } from '../utils/notifications' import Loading from './Loading' import { sleep } from '../utils' import Modal from './Modal' import { useTranslation } from 'next-i18next' interface MarketCloseModalProps { onClose: () => void isOpen: boolean market: PerpMarket marketIndex: number } const MarketCloseModal: FunctionComponent = ({ onClose, isOpen, market, marketIndex, }) => { const { t } = useTranslation('common') const [submitting, setSubmitting] = useState(false) const actions = useMangoStore((s) => s.actions) const mangoClient = useMangoStore((s) => s.connection.client) const config = useMangoStore.getState().selectedMarket.config async function handleMarketClose() { const mangoAccount = useMangoStore.getState().selectedMangoAccount.current const mangoGroup = useMangoStore.getState().selectedMangoGroup.current const marketConfig = useMangoStore.getState().selectedMarket.config const askInfo = useMangoStore.getState().accountInfos[marketConfig.asksKey.toString()] const bidInfo = useMangoStore.getState().accountInfos[marketConfig.bidsKey.toString()] const wallet = useMangoStore.getState().wallet.current const orderbook = useMangoStore.getState().selectedMarket.orderBook const markPrice = useMangoStore.getState().selectedMarket.markPrice // The reference price is the book mid if book is double sided; else mark price const bb = orderbook?.bids?.length > 0 && Number(orderbook.bids[0][0]) const ba = orderbook?.asks?.length > 0 && Number(orderbook.asks[0][0]) const referencePrice = bb && ba ? (bb + ba) / 2 : markPrice if (!wallet || !mangoGroup || !mangoAccount) return setSubmitting(true) try { const perpAccount = mangoAccount.perpAccounts[marketIndex] const side = perpAccount.basePosition.gt(ZERO_BN) ? 'sell' : 'buy' // send a large size to ensure we are reducing the entire position const size = Math.abs(market.baseLotsToNumber(perpAccount.basePosition)) * 2 // hard coded for now; market orders are very dangerous and fault prone const maxSlippage: number | undefined = 0.025 const txid = await mangoClient.placePerpOrder( mangoGroup, mangoAccount, mangoGroup.mangoCache, market, wallet, side, referencePrice * (1 + (side === 'buy' ? 1 : -1) * maxSlippage), size, 'ioc', 0, // client order id side === 'buy' ? askInfo : bidInfo, true // reduce only ) await sleep(500) actions.reloadMangoAccount() notify({ title: t('transaction-sent'), txid }) } catch (e) { notify({ title: t('order-error'), description: e.message, txid: e.txid, type: 'error', }) } finally { setSubmitting(false) onClose() } } return (
{t('close-confirm', { config_name: config.name })}
{t('price-expect')}
{t('cancel')}
) } export default MarketCloseModal