mango-ui-v3/components/MarketCloseModal.tsx

112 lines
3.8 KiB
TypeScript
Raw Normal View History

import { FunctionComponent, useState } from 'react'
2021-09-13 14:14:59 -07:00
import useMangoStore from '../stores/useMangoStore'
2021-08-25 11:30:16 -07:00
import { PerpMarket, ZERO_BN } from '@blockworks-foundation/mango-client'
2021-08-24 20:15:57 -07:00
import Button, { LinkButton } from './Button'
import { notify } from '../utils/notifications'
import Loading from './Loading'
import { sleep } from '../utils'
2021-08-24 20:15:57 -07:00
import Modal from './Modal'
import { useTranslation } from 'next-i18next'
2021-08-24 20:15:57 -07:00
interface MarketCloseModalProps {
onClose: () => void
isOpen: boolean
market: PerpMarket
2021-08-25 11:30:16 -07:00
marketIndex: number
2021-08-24 20:15:57 -07:00
}
const MarketCloseModal: FunctionComponent<MarketCloseModalProps> = ({
onClose,
isOpen,
market,
2021-08-25 11:30:16 -07:00
marketIndex,
2021-08-24 20:15:57 -07:00
}) => {
const { t } = useTranslation('common')
2021-08-24 20:15:57 -07:00
const [submitting, setSubmitting] = useState(false)
const actions = useMangoStore((s) => s.actions)
2021-09-13 14:14:59 -07:00
const mangoClient = useMangoStore((s) => s.connection.client)
2021-08-25 11:30:16 -07:00
const config = useMangoStore.getState().selectedMarket.config
async function handleMarketClose() {
2021-08-24 20:15:57 -07:00
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()]
2021-08-24 20:15:57 -07:00
const wallet = useMangoStore.getState().wallet.current
const orderbook = useMangoStore.getState().selectedMarket.orderBook
const markPrice = useMangoStore.getState().selectedMarket.markPrice
const referrerPk = useMangoStore.getState().referrerPk
// 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
2021-08-24 20:15:57 -07:00
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
2022-02-20 09:52:37 -08:00
const txid = await mangoClient.placePerpOrder2(
2021-08-24 20:15:57 -07:00
mangoGroup,
mangoAccount,
market,
wallet,
side,
referencePrice * (1 + (side === 'buy' ? 1 : -1) * maxSlippage),
2021-08-24 20:15:57 -07:00
size,
2022-02-20 09:52:37 -08:00
{
orderType: 'ioc',
bookSideInfo: side === 'buy' ? askInfo : bidInfo,
reduceOnly: true,
referrerMangoAccountPk: referrerPk ? referrerPk : undefined,
}
2021-08-24 20:15:57 -07:00
)
await sleep(500)
actions.reloadMangoAccount()
notify({ title: t('transaction-sent'), txid })
2021-08-24 20:15:57 -07:00
} catch (e) {
notify({
title: t('order-error'),
2021-08-24 20:15:57 -07:00
description: e.message,
txid: e.txid,
type: 'error',
})
} finally {
setSubmitting(false)
onClose()
}
}
2021-08-24 20:15:57 -07:00
return (
<Modal onClose={onClose} isOpen={isOpen}>
<div className="pb-2 text-th-fgd-1 text-lg">
{t('close-confirm', { config_name: config.name })}
2021-08-24 20:15:57 -07:00
</div>
<div className="pb-6 text-th-fgd-3">{t('price-expect')}</div>
2021-08-24 20:15:57 -07:00
<div className="flex items-center">
2021-08-25 11:30:16 -07:00
<Button onClick={handleMarketClose}>
{submitting ? <Loading /> : <span>{t('close-position')}</span>}
2021-08-24 20:15:57 -07:00
</Button>
<LinkButton className="ml-4 text-th-fgd-1" onClick={onClose}>
{t('cancel')}
2021-08-24 20:15:57 -07:00
</LinkButton>
</div>
</Modal>
)
}
export default MarketCloseModal