2023-01-15 19:58:01 -08:00
|
|
|
import { PerpMarket, Serum3Market } from '@blockworks-foundation/mango-v4'
|
2022-12-26 03:58:17 -08:00
|
|
|
import MaxAmountButton from '@components/shared/MaxAmountButton'
|
|
|
|
import { FadeInFadeOut } from '@components/shared/Transitions'
|
2023-04-04 22:25:25 -07:00
|
|
|
import { useWallet } from '@solana/wallet-adapter-react'
|
2022-12-26 03:58:17 -08:00
|
|
|
import mangoStore from '@store/mangoStore'
|
|
|
|
import useMangoAccount from 'hooks/useMangoAccount'
|
|
|
|
import useSelectedMarket from 'hooks/useSelectedMarket'
|
2023-02-12 18:46:41 -08:00
|
|
|
import useUnownedAccount from 'hooks/useUnownedAccount'
|
2022-12-26 03:58:17 -08:00
|
|
|
import { useTranslation } from 'next-i18next'
|
|
|
|
import { useCallback, useMemo } from 'react'
|
2023-04-01 03:05:53 -07:00
|
|
|
import { floorToDecimal } from 'utils/numbers'
|
2023-01-15 19:58:01 -08:00
|
|
|
import { useSpotMarketMax } from './SpotSlider'
|
2022-12-26 03:58:17 -08:00
|
|
|
|
|
|
|
const MaxSizeButton = ({
|
|
|
|
minOrderDecimals,
|
|
|
|
tickDecimals,
|
2023-01-15 19:58:01 -08:00
|
|
|
useMargin,
|
2023-05-23 04:48:26 -07:00
|
|
|
large,
|
2022-12-26 03:58:17 -08:00
|
|
|
}: {
|
|
|
|
minOrderDecimals: number
|
|
|
|
tickDecimals: number
|
2023-01-15 19:58:01 -08:00
|
|
|
useMargin: boolean
|
2023-05-23 04:48:26 -07:00
|
|
|
large?: boolean
|
2022-12-26 03:58:17 -08:00
|
|
|
}) => {
|
|
|
|
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)
|
2023-01-15 19:58:01 -08:00
|
|
|
const spotMax = useSpotMarketMax(
|
|
|
|
mangoAccount,
|
|
|
|
selectedMarket,
|
|
|
|
side,
|
2023-07-21 11:47:53 -07:00
|
|
|
useMargin,
|
2023-01-15 19:58:01 -08:00
|
|
|
)
|
2023-03-04 11:17:34 -08:00
|
|
|
const { isUnownedAccount } = useUnownedAccount()
|
2023-04-04 22:25:25 -07:00
|
|
|
const { connected } = useWallet()
|
2022-12-26 03:58:17 -08:00
|
|
|
|
2023-01-15 19:58:01 -08:00
|
|
|
const perpMax = useMemo(() => {
|
2022-12-26 03:58:17 -08:00
|
|
|
const group = mangoStore.getState().group
|
|
|
|
if (!mangoAccount || !group || !selectedMarket) return 0
|
2023-01-15 19:58:01 -08:00
|
|
|
if (selectedMarket instanceof PerpMarket) {
|
|
|
|
try {
|
2023-01-04 17:09:43 -08:00
|
|
|
if (side === 'buy') {
|
2022-12-26 03:58:17 -08:00
|
|
|
return mangoAccount.getMaxQuoteForPerpBidUi(
|
|
|
|
group,
|
2023-07-21 11:47:53 -07:00
|
|
|
selectedMarket.perpMarketIndex,
|
2022-12-26 03:58:17 -08:00
|
|
|
)
|
|
|
|
} else {
|
|
|
|
return mangoAccount.getMaxBaseForPerpAskUi(
|
|
|
|
group,
|
2023-07-21 11:47:53 -07:00
|
|
|
selectedMarket.perpMarketIndex,
|
2022-12-26 03:58:17 -08:00
|
|
|
)
|
|
|
|
}
|
2023-01-15 19:58:01 -08:00
|
|
|
} catch (e) {
|
|
|
|
console.error('Error calculating max leverage: spot btn group: ', e)
|
|
|
|
return 0
|
2022-12-26 03:58:17 -08:00
|
|
|
}
|
|
|
|
}
|
2023-01-04 17:09:43 -08:00
|
|
|
}, [mangoAccount, side, selectedMarket])
|
2022-12-26 03:58:17 -08:00
|
|
|
|
|
|
|
const handleMax = useCallback(() => {
|
2023-01-15 19:58:01 -08:00
|
|
|
const max = selectedMarket instanceof Serum3Market ? spotMax : perpMax || 0
|
2022-12-26 03:58:17 -08:00
|
|
|
const set = mangoStore.getState().set
|
|
|
|
set((state) => {
|
2023-01-04 17:09:43 -08:00
|
|
|
if (side === 'buy') {
|
|
|
|
if (tradeType === 'Market' || !price) {
|
2023-04-25 17:23:14 -07:00
|
|
|
const baseSize = floorToDecimal(max / oraclePrice, minOrderDecimals)
|
|
|
|
const quoteSize = floorToDecimal(max, tickDecimals)
|
|
|
|
state.tradeForm.baseSize = baseSize.toFixed()
|
|
|
|
state.tradeForm.quoteSize = quoteSize.toFixed()
|
2022-12-26 03:58:17 -08:00
|
|
|
} else {
|
2023-04-25 17:23:14 -07:00
|
|
|
const baseSize = floorToDecimal(
|
2023-01-15 19:58:01 -08:00
|
|
|
max / parseFloat(price),
|
2023-07-21 11:47:53 -07:00
|
|
|
minOrderDecimals,
|
2023-04-25 17:23:14 -07:00
|
|
|
)
|
|
|
|
const quoteSize = floorToDecimal(baseSize.mul(price), tickDecimals)
|
|
|
|
state.tradeForm.baseSize = baseSize.toFixed()
|
|
|
|
state.tradeForm.quoteSize = quoteSize.toFixed()
|
2022-12-26 03:58:17 -08:00
|
|
|
}
|
|
|
|
} else {
|
2023-04-25 17:23:14 -07:00
|
|
|
const baseSize = floorToDecimal(max, minOrderDecimals)
|
2023-01-04 17:09:43 -08:00
|
|
|
if (tradeType === 'Market' || !price) {
|
2023-04-25 17:23:14 -07:00
|
|
|
const quoteSize = floorToDecimal(
|
|
|
|
baseSize.mul(oraclePrice),
|
2023-07-21 11:47:53 -07:00
|
|
|
tickDecimals,
|
2023-04-25 17:23:14 -07:00
|
|
|
)
|
|
|
|
state.tradeForm.baseSize = baseSize.toFixed()
|
|
|
|
state.tradeForm.quoteSize = quoteSize.toFixed()
|
2022-12-26 03:58:17 -08:00
|
|
|
} else {
|
2023-04-25 17:23:14 -07:00
|
|
|
const quoteSize = floorToDecimal(baseSize.mul(price), tickDecimals)
|
|
|
|
state.tradeForm.baseSize = baseSize.toFixed()
|
|
|
|
state.tradeForm.quoteSize = quoteSize.toFixed()
|
2022-12-26 03:58:17 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
2023-01-19 20:45:44 -08:00
|
|
|
}, [
|
|
|
|
minOrderDecimals,
|
|
|
|
perpMax,
|
|
|
|
price,
|
|
|
|
selectedMarket,
|
|
|
|
side,
|
|
|
|
spotMax,
|
|
|
|
tickDecimals,
|
|
|
|
tradeType,
|
|
|
|
])
|
2022-12-26 03:58:17 -08:00
|
|
|
|
|
|
|
const maxAmount = useMemo(() => {
|
2023-01-15 19:58:01 -08:00
|
|
|
const max = selectedMarket instanceof Serum3Market ? spotMax : perpMax || 0
|
2023-01-04 17:09:43 -08:00
|
|
|
const tradePrice = tradeType === 'Market' ? oraclePrice : Number(price)
|
|
|
|
if (side === 'buy') {
|
2023-01-23 19:04:05 -08:00
|
|
|
return max / tradePrice
|
2022-12-26 03:58:17 -08:00
|
|
|
} else {
|
2023-01-23 19:04:05 -08:00
|
|
|
return max
|
2022-12-26 03:58:17 -08:00
|
|
|
}
|
2023-01-23 19:04:05 -08:00
|
|
|
}, [perpMax, spotMax, selectedMarket, price, side, tradeType])
|
2022-12-26 03:58:17 -08:00
|
|
|
|
|
|
|
return (
|
2023-11-04 05:24:17 -07:00
|
|
|
<FadeInFadeOut show={!!price && !isUnownedAccount && connected}>
|
|
|
|
<MaxAmountButton
|
|
|
|
className={large ? 'text-sm' : 'text-xs'}
|
|
|
|
decimals={minOrderDecimals}
|
|
|
|
label={t('max')}
|
|
|
|
onClick={handleMax}
|
|
|
|
value={maxAmount}
|
|
|
|
/>
|
|
|
|
</FadeInFadeOut>
|
2022-12-26 03:58:17 -08:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
export default MaxSizeButton
|