mango-v4-ui/components/trade/MaxSizeButton.tsx

123 lines
3.7 KiB
TypeScript
Raw Normal View History

import { Serum3Market } from '@blockworks-foundation/mango-v4'
import MaxAmountButton from '@components/shared/MaxAmountButton'
import { FadeInFadeOut } from '@components/shared/Transitions'
import mangoStore from '@store/mangoStore'
import useMangoAccount from 'hooks/useMangoAccount'
import useSelectedMarket from 'hooks/useSelectedMarket'
import { useTranslation } from 'next-i18next'
import { useCallback, useMemo } from 'react'
2023-01-05 20:10:25 -08:00
import { floorToDecimal } from 'utils/numbers'
const MaxSizeButton = ({
minOrderDecimals,
tickDecimals,
}: {
minOrderDecimals: number
tickDecimals: number
}) => {
const { t } = useTranslation(['common', 'trade'])
const { mangoAccount } = useMangoAccount()
const { selectedMarket, price: oraclePrice } = useSelectedMarket()
2023-01-04 17:09:43 -08:00
const { price, side, tradeType } = mangoStore((s) => s.tradeForm)
const leverageMax = useMemo(() => {
const group = mangoStore.getState().group
if (!mangoAccount || !group || !selectedMarket) return 0
try {
if (selectedMarket instanceof Serum3Market) {
2023-01-04 17:09:43 -08:00
if (side === 'buy') {
return mangoAccount.getMaxQuoteForSerum3BidUi(
group,
selectedMarket.serumMarketExternal
)
} else {
return mangoAccount.getMaxBaseForSerum3AskUi(
group,
selectedMarket.serumMarketExternal
)
}
} else {
2023-01-04 17:09:43 -08:00
if (side === 'buy') {
return mangoAccount.getMaxQuoteForPerpBidUi(
group,
selectedMarket.perpMarketIndex
)
} else {
return mangoAccount.getMaxBaseForPerpAskUi(
group,
selectedMarket.perpMarketIndex
)
}
}
} catch (e) {
console.error('Error calculating max leverage: spot btn group: ', e)
return 0
}
2023-01-04 17:09:43 -08:00
}, [mangoAccount, side, selectedMarket])
const handleMax = useCallback(() => {
const set = mangoStore.getState().set
set((state) => {
2023-01-04 17:09:43 -08:00
if (side === 'buy') {
2023-01-05 20:10:25 -08:00
state.tradeForm.quoteSize = floorToDecimal(
leverageMax,
tickDecimals
2023-01-05 20:10:25 -08:00
).toFixed()
2023-01-04 17:09:43 -08:00
if (tradeType === 'Market' || !price) {
2023-01-05 20:10:25 -08:00
state.tradeForm.baseSize = floorToDecimal(
leverageMax / oraclePrice,
minOrderDecimals
2023-01-05 20:10:25 -08:00
).toFixed()
} else {
2023-01-05 20:10:25 -08:00
state.tradeForm.baseSize = floorToDecimal(
2023-01-04 17:09:43 -08:00
leverageMax / parseFloat(price),
minOrderDecimals
2023-01-05 20:10:25 -08:00
).toFixed()
}
} else {
2023-01-05 20:10:25 -08:00
state.tradeForm.baseSize = floorToDecimal(
leverageMax,
tickDecimals
2023-01-05 20:10:25 -08:00
).toFixed()
2023-01-04 17:09:43 -08:00
if (tradeType === 'Market' || !price) {
2023-01-05 20:10:25 -08:00
state.tradeForm.quoteSize = floorToDecimal(
leverageMax * oraclePrice,
minOrderDecimals
2023-01-05 20:10:25 -08:00
).toFixed()
} else {
2023-01-05 20:10:25 -08:00
state.tradeForm.quoteSize = floorToDecimal(
2023-01-04 17:09:43 -08:00
leverageMax * parseFloat(price),
minOrderDecimals
2023-01-05 20:10:25 -08:00
).toFixed()
}
}
})
2023-01-04 17:09:43 -08:00
}, [leverageMax, price, side, tradeType])
const maxAmount = useMemo(() => {
2023-01-04 17:09:43 -08:00
const tradePrice = tradeType === 'Market' ? oraclePrice : Number(price)
if (side === 'buy') {
2023-01-05 20:10:25 -08:00
return floorToDecimal(leverageMax / tradePrice, tickDecimals).toFixed()
} else {
2023-01-05 20:10:25 -08:00
return floorToDecimal(leverageMax, minOrderDecimals).toFixed()
}
2023-01-04 17:09:43 -08:00
}, [leverageMax, minOrderDecimals, tickDecimals, price, side, tradeType])
return (
<div className="mb-2 mt-3 flex items-center justify-between">
<p className="text-xs text-th-fgd-3">{t('trade:size')}</p>
2023-01-04 17:09:43 -08:00
<FadeInFadeOut show={!!price}>
<MaxAmountButton
className="text-xs"
label={t('max')}
onClick={handleMax}
value={maxAmount}
/>
</FadeInFadeOut>
</div>
)
}
export default MaxSizeButton