2022-08-17 18:26:38 -07:00
import { useState , useCallback , useEffect , useMemo } from 'react'
2022-08-19 21:03:26 -07:00
import { PublicKey } from '@solana/web3.js'
2022-08-25 17:27:05 -07:00
import {
ArrowDownIcon ,
ArrowRightIcon ,
2022-09-07 17:47:59 -07:00
Cog8ToothIcon ,
MagnifyingGlassIcon ,
2022-08-25 17:27:05 -07:00
ExclamationCircleIcon ,
2022-09-16 03:49:10 -07:00
HeartIcon ,
2022-09-06 21:36:35 -07:00
} from '@heroicons/react/20/solid'
2022-08-03 14:46:37 -07:00
import { RouteInfo } from '@jup-ag/core'
2022-08-17 18:26:38 -07:00
import NumberFormat , { NumberFormatValues } from 'react-number-format'
import Decimal from 'decimal.js'
2022-09-12 08:53:57 -07:00
import mangoStore from '@store/mangoStore'
2022-07-05 20:37:49 -07:00
import ContentBox from '../shared/ContentBox'
2022-08-17 13:06:25 -07:00
import JupiterRouteInfo from './JupiterRouteInfo'
2022-09-01 10:33:29 -07:00
import TokenSelect from './TokenSelect'
2022-07-05 20:37:49 -07:00
import useDebounce from '../shared/useDebounce'
2022-08-26 10:17:31 -07:00
import { floorToDecimal , numberFormat } from '../../utils/numbers'
2022-08-15 15:18:23 -07:00
import { SwapLeverageSlider } from './LeverageSlider'
2022-07-15 05:50:29 -07:00
import { useTranslation } from 'next-i18next'
2022-08-20 11:54:38 -07:00
import SwapFormTokenList from './SwapFormTokenList'
2022-07-16 04:22:59 -07:00
import { Transition } from '@headlessui/react'
2022-08-12 05:40:26 -07:00
import Button , { IconButton , LinkButton } from '../shared/Button'
2022-07-17 04:48:33 -07:00
import ButtonGroup from '../forms/ButtonGroup'
2022-07-18 03:02:43 -07:00
import Loading from '../shared/Loading'
2022-07-23 19:48:26 -07:00
import { EnterBottomExitBottom } from '../shared/Transitions'
2022-08-03 14:46:37 -07:00
import useJupiter from './useJupiter'
2022-08-08 10:42:18 -07:00
import SwapSettings from './SwapSettings'
2022-08-15 04:28:36 -07:00
import SheenLoader from '../shared/SheenLoader'
2022-08-25 06:00:42 -07:00
import { HealthType } from '@blockworks-foundation/mango-v4'
2022-08-20 11:17:57 -07:00
import {
INPUT_TOKEN_DEFAULT ,
OUTPUT_TOKEN_DEFAULT ,
} from '../../utils/constants'
2022-10-05 04:25:26 -07:00
import { useTokenMax } from './useTokenMax'
2022-09-07 17:47:59 -07:00
import WalletIcon from '../icons/WalletIcon'
2022-09-19 23:31:07 -07:00
import Tooltip from '@components/shared/Tooltip'
2022-10-05 16:03:10 -07:00
import MaxAmountButton from '@components/shared/MaxAmountButton'
2022-07-18 03:02:43 -07:00
2022-08-17 18:26:38 -07:00
const MAX_DIGITS = 11
2022-09-02 11:36:57 -07:00
export const withValueLimit = ( values : NumberFormatValues ) : boolean = > {
2022-08-17 18:26:38 -07:00
return values . floatValue
? values . floatValue . toFixed ( 0 ) . length <= MAX_DIGITS
: true
}
2022-08-19 21:03:26 -07:00
const SwapForm = ( ) = > {
2022-09-14 18:06:00 -07:00
const { t } = useTranslation ( [ 'common' , 'swap' ] )
2022-07-18 03:02:43 -07:00
const [ selectedRoute , setSelectedRoute ] = useState < RouteInfo > ( )
2022-08-17 21:13:50 -07:00
const [ amountInFormValue , setAmountInFormValue ] = useState ( '' )
2022-07-22 08:40:53 -07:00
const [ animateSwitchArrow , setAnimateSwitchArrow ] = useState ( 0 )
2022-07-16 04:22:59 -07:00
const [ showTokenSelect , setShowTokenSelect ] = useState ( '' )
2022-08-08 10:42:18 -07:00
const [ showSettings , setShowSettings ] = useState ( false )
2022-07-17 19:49:14 -07:00
const [ showConfirm , setShowConfirm ] = useState ( false )
2022-07-22 08:40:53 -07:00
2022-10-07 05:22:18 -07:00
const group = mangoStore . getState ( ) . group
2022-07-10 19:01:16 -07:00
const set = mangoStore . getState ( ) . set
2022-08-09 15:44:01 -07:00
const useMargin = mangoStore ( ( s ) = > s . swap . margin )
const slippage = mangoStore ( ( s ) = > s . swap . slippage )
2022-08-25 06:00:42 -07:00
const mangoAccount = mangoStore ( ( s ) = > s . mangoAccount . current )
2022-08-18 13:50:34 -07:00
const inputTokenInfo = mangoStore ( ( s ) = > s . swap . inputTokenInfo )
const outputTokenInfo = mangoStore ( ( s ) = > s . swap . outputTokenInfo )
2022-08-02 11:04:00 -07:00
const jupiterTokens = mangoStore ( ( s ) = > s . jupiterTokens )
2022-07-17 19:49:14 -07:00
const connected = mangoStore ( ( s ) = > s . connected )
2022-08-18 13:50:34 -07:00
const [ debouncedAmountIn ] = useDebounce ( amountInFormValue , 300 )
2022-09-14 17:02:16 -07:00
2022-09-01 10:33:29 -07:00
const amountIn : Decimal | null = useMemo ( ( ) = > {
return Number ( debouncedAmountIn )
? new Decimal ( debouncedAmountIn )
: new Decimal ( 0 )
} , [ debouncedAmountIn ] )
2022-08-18 13:50:34 -07:00
const { amountOut , jupiter , routes } = useJupiter ( {
inputTokenInfo ,
outputTokenInfo ,
2022-08-17 13:06:25 -07:00
inputAmount : debouncedAmountIn ,
2022-08-03 14:46:37 -07:00
slippage ,
} )
2022-07-18 03:02:43 -07:00
useEffect ( ( ) = > {
2022-08-03 14:46:37 -07:00
setSelectedRoute ( routes [ 0 ] )
} , [ routes ] )
2022-07-18 03:02:43 -07:00
2022-08-25 14:24:10 -07:00
useEffect ( ( ) = > {
2022-09-02 16:52:07 -07:00
setAmountInFormValue ( '' )
2022-08-25 14:24:10 -07:00
} , [ useMargin ] )
2022-08-17 18:26:38 -07:00
const handleAmountInChange = useCallback ( ( e : NumberFormatValues ) = > {
2022-08-17 21:13:50 -07:00
setAmountInFormValue ( e . value )
2022-08-17 18:26:38 -07:00
} , [ ] )
2022-07-05 20:37:49 -07:00
2022-08-17 18:26:38 -07:00
const handleTokenInSelect = useCallback (
( mintAddress : string ) = > {
const inputTokenInfo = jupiterTokens . find (
( t : any ) = > t . address === mintAddress
)
const group = mangoStore . getState ( ) . group
if ( group ) {
2022-08-18 13:50:34 -07:00
const bank = group . getFirstBankByMint ( new PublicKey ( mintAddress ) )
2022-08-17 18:26:38 -07:00
set ( ( s ) = > {
2022-08-18 13:50:34 -07:00
s . swap . inputBank = bank
2022-08-17 18:26:38 -07:00
s . swap . inputTokenInfo = inputTokenInfo
} )
}
setShowTokenSelect ( '' )
} ,
[ jupiterTokens , set ]
)
2022-08-10 13:23:19 -07:00
2022-08-17 18:26:38 -07:00
const handleTokenOutSelect = useCallback (
( mintAddress : string ) = > {
const outputTokenInfo = jupiterTokens . find (
( t : any ) = > t . address === mintAddress
)
const group = mangoStore . getState ( ) . group
if ( group ) {
2022-08-18 13:50:34 -07:00
const bank = group . getFirstBankByMint ( new PublicKey ( mintAddress ) )
2022-08-17 18:26:38 -07:00
set ( ( s ) = > {
2022-08-18 13:50:34 -07:00
s . swap . outputBank = bank
2022-08-17 18:26:38 -07:00
s . swap . outputTokenInfo = outputTokenInfo
} )
}
setShowTokenSelect ( '' )
} ,
[ jupiterTokens , set ]
)
2022-07-05 20:37:49 -07:00
2022-08-17 18:26:38 -07:00
const handleSwitchTokens = useCallback ( ( ) = > {
2022-08-31 08:10:34 -07:00
if ( amountIn ? . gt ( 0 ) ) {
setAmountInFormValue ( amountOut . toString ( ) )
}
2022-08-18 13:50:34 -07:00
const inputBank = mangoStore . getState ( ) . swap . inputBank
const outputBank = mangoStore . getState ( ) . swap . outputBank
2022-07-11 20:00:22 -07:00
set ( ( s ) = > {
2022-08-18 13:50:34 -07:00
s . swap . inputBank = outputBank
s . swap . outputBank = inputBank
2022-07-25 22:27:53 -07:00
s . swap . inputTokenInfo = outputTokenInfo
s . swap . outputTokenInfo = inputTokenInfo
2022-07-11 20:00:22 -07:00
} )
2022-08-17 18:26:38 -07:00
setAnimateSwitchArrow (
( prevanimateSwitchArrow ) = > prevanimateSwitchArrow + 1
)
2022-09-01 10:33:29 -07:00
} , [ inputTokenInfo , outputTokenInfo , set , amountOut , amountIn ] )
2022-08-17 18:26:38 -07:00
2022-08-25 06:00:42 -07:00
const currentMaintHealth = useMemo ( ( ) = > {
2022-10-07 05:22:18 -07:00
if ( ! group || ! mangoAccount ) return 0
return mangoAccount . getHealthRatioUi ( group , HealthType . maint )
2022-08-25 06:00:42 -07:00
} , [ mangoAccount ] )
const maintProjectedHealth = useMemo ( ( ) = > {
const group = mangoStore . getState ( ) . group
if (
! inputTokenInfo ||
! mangoAccount ||
! outputTokenInfo ||
! amountOut ||
! group
)
return 0
const simulatedHealthRatio =
mangoAccount . simHealthRatioWithTokenPositionUiChanges (
group ,
[
{
mintPk : new PublicKey ( inputTokenInfo . address ) ,
uiTokenAmount : amountIn.toNumber ( ) * - 1 ,
} ,
{
mintPk : new PublicKey ( outputTokenInfo . address ) ,
2022-09-02 16:52:07 -07:00
uiTokenAmount : amountOut.toNumber ( ) ,
2022-08-25 06:00:42 -07:00
} ,
] ,
HealthType . maint
)
2022-08-31 13:17:17 -07:00
return simulatedHealthRatio ! > 100
2022-08-25 06:00:42 -07:00
? 100
2022-08-31 13:17:17 -07:00
: simulatedHealthRatio ! < 0
2022-08-25 06:00:42 -07:00
? 0
2022-09-04 23:32:10 -07:00
: Math . trunc ( simulatedHealthRatio ! )
2022-08-25 06:00:42 -07:00
} , [ mangoAccount , inputTokenInfo , outputTokenInfo , amountIn , amountOut ] )
2022-09-22 14:35:07 -07:00
const loadingSwapDetails : boolean = useMemo ( ( ) = > {
2022-08-17 18:26:38 -07:00
return (
2022-09-22 14:35:07 -07:00
! ! amountIn . toNumber ( ) && connected && ( ! selectedRoute || ! outputTokenInfo )
2022-08-17 18:26:38 -07:00
)
} , [ amountIn , connected , selectedRoute , outputTokenInfo ] )
2022-07-18 03:02:43 -07:00
2022-08-25 12:44:02 -07:00
const showHealthImpact = ! ! inputTokenInfo && ! ! outputTokenInfo && ! ! amountOut
2022-07-05 20:37:49 -07:00
return (
2022-09-14 14:57:12 -07:00
< ContentBox
hidePadding
2022-09-14 21:51:19 -07:00
// showBackground
2022-09-18 20:53:52 -07:00
className = "relative overflow-hidden border-x-0 md:border-l md:border-r-0 md:border-t-0 md:border-b-0"
2022-09-14 14:57:12 -07:00
>
2022-09-14 23:06:23 -07:00
< div className = "p-6 pt-3" >
2022-08-25 06:00:42 -07:00
< Transition
2022-10-08 03:15:03 -07:00
className = "thin-scroll absolute top-0 left-0 z-10 h-full w-full overflow-auto bg-th-bkg-1 p-6 pb-0"
2022-08-25 06:00:42 -07:00
show = { showConfirm }
enter = "transition ease-in duration-300"
enterFrom = "translate-x-full"
enterTo = "translate-x-0"
leave = "transition ease-out duration-300"
leaveFrom = "translate-x-0"
leaveTo = "translate-x-full"
2022-07-17 04:48:33 -07:00
>
2022-08-25 06:00:42 -07:00
< JupiterRouteInfo
onClose = { ( ) = > setShowConfirm ( false ) }
amountIn = { amountIn }
slippage = { slippage }
jupiter = { jupiter }
routes = { routes }
selectedRoute = { selectedRoute }
setSelectedRoute = { setSelectedRoute }
2022-07-16 04:22:59 -07:00
/ >
2022-08-25 06:00:42 -07:00
< / Transition >
< EnterBottomExitBottom
2022-10-08 03:15:03 -07:00
className = "thin-scroll absolute bottom-0 left-0 z-10 h-full w-full overflow-auto bg-th-bkg-1 p-6 pb-0"
2022-08-25 06:00:42 -07:00
show = { ! ! showTokenSelect }
>
< SwapFormTokenList
onClose = { ( ) = > setShowTokenSelect ( '' ) }
onTokenSelect = {
showTokenSelect === 'input'
? handleTokenInSelect
: handleTokenOutSelect
}
type = { showTokenSelect }
2022-09-14 03:37:45 -07:00
useMargin = { useMargin }
2022-07-15 05:50:29 -07:00
/ >
2022-08-25 06:00:42 -07:00
< / EnterBottomExitBottom >
2022-08-25 12:44:02 -07:00
< EnterBottomExitBottom
2022-10-08 03:15:03 -07:00
className = "thin-scroll absolute bottom-0 left-0 z-10 h-full w-full overflow-auto bg-th-bkg-1 p-6 pb-0"
2022-08-25 12:44:02 -07:00
show = { showSettings }
>
< SwapSettings onClose = { ( ) = > setShowSettings ( false ) } / >
< / EnterBottomExitBottom >
2022-08-25 06:00:42 -07:00
< div className = "mb-4 flex items-center justify-between" >
2022-09-16 04:37:24 -07:00
< h2 className = "text-base text-th-fgd-2" > { t ( 'swap' ) } < / h2 >
2022-09-21 21:25:24 -07:00
< div id = "swap-step-one" >
2022-09-11 17:22:37 -07:00
< IconButton
2022-09-14 19:41:55 -07:00
className = "text-th-fgd-2"
hideBg
2022-09-11 17:22:37 -07:00
onClick = { ( ) = > setShowSettings ( true ) }
size = "small"
>
< Cog8ToothIcon className = "h-5 w-5" / >
< / IconButton >
< / div >
2022-07-10 19:01:16 -07:00
< / div >
2022-10-05 04:25:26 -07:00
< div id = "swap-step-two" className = "mb-2 flex items-end justify-between" >
2022-09-14 18:06:00 -07:00
< p className = "text-th-fgd-3" > { t ( 'swap:from' ) } < / p >
2022-08-25 06:00:42 -07:00
< MaxSwapAmount
useMargin = { useMargin }
2022-08-23 05:41:37 -07:00
setAmountIn = { setAmountInFormValue }
/ >
2022-07-15 05:50:29 -07:00
< / div >
2022-08-25 06:00:42 -07:00
< div className = "mb-3 grid grid-cols-2" >
< div className = "col-span-1 rounded-lg rounded-r-none border border-r-0 border-th-bkg-4 bg-th-bkg-1" >
< TokenSelect
tokenSymbol = { inputTokenInfo ? . symbol || INPUT_TOKEN_DEFAULT }
showTokenList = { setShowTokenSelect }
type = "input"
/ >
< / div >
< div className = "col-span-1" >
< NumberFormat
inputMode = "decimal"
thousandSeparator = ","
2022-08-31 08:54:43 -07:00
allowNegative = { false }
isNumericString = { true }
2022-08-25 06:00:42 -07:00
decimalScale = { inputTokenInfo ? . decimals || 6 }
name = "amountIn"
id = "amountIn"
2022-09-22 03:46:51 -07:00
className = "w-full rounded-lg rounded-l-none border border-th-bkg-4 bg-th-bkg-1 p-3 text-right font-mono text-xl font-bold text-th-fgd-1 focus:outline-none"
2022-08-25 06:00:42 -07:00
placeholder = "0.00"
value = { amountInFormValue }
onValueChange = { handleAmountInChange }
isAllowed = { withValueLimit }
/ >
< / div >
{ ! useMargin ? (
< PercentageSelectButtons
amountIn = { amountInFormValue }
setAmountIn = { setAmountInFormValue }
2022-09-22 14:35:07 -07:00
useMargin = { useMargin }
2022-08-25 06:00:42 -07:00
/ >
) : null }
< / div >
2022-09-29 21:21:23 -07:00
< div className = "-mb-2 flex justify-center" >
2022-08-25 06:00:42 -07:00
< button
className = "rounded-full border border-th-bkg-4 p-1.5 text-th-fgd-3 md:hover:text-th-primary"
onClick = { handleSwitchTokens }
>
< ArrowDownIcon
className = "h-5 w-5"
style = {
animateSwitchArrow % 2 == 0
? { transform : 'rotate(0deg)' }
: { transform : 'rotate(360deg)' }
}
/ >
< / button >
< / div >
2022-09-14 18:06:00 -07:00
< p className = "mb-2 text-th-fgd-3" > { t ( 'swap:to' ) } < / p >
2022-09-21 21:25:24 -07:00
< div id = "swap-step-three" className = "mb-3 grid grid-cols-2" >
2022-08-25 06:00:42 -07:00
< div className = "col-span-1 rounded-lg rounded-r-none border border-r-0 border-th-bkg-4 bg-th-bkg-1" >
< TokenSelect
tokenSymbol = { outputTokenInfo ? . symbol || OUTPUT_TOKEN_DEFAULT }
showTokenList = { setShowTokenSelect }
type = "output"
/ >
< / div >
2022-09-22 03:46:51 -07:00
< div className = "flex h-[54px] w-full items-center justify-end rounded-r-lg border border-th-bkg-4 bg-th-bkg-3 text-right text-xl font-bold text-th-fgd-3" >
2022-09-22 14:35:07 -07:00
{ loadingSwapDetails ? (
2022-08-25 06:00:42 -07:00
< div className = "w-full" >
2022-09-08 18:00:47 -07:00
< SheenLoader className = "flex flex-1 rounded-l-none" >
< div className = "h-[52px] w-full rounded-r-lg bg-th-bkg-4" / >
2022-08-25 06:00:42 -07:00
< / SheenLoader >
< / div >
) : (
2022-09-22 03:46:51 -07:00
< span className = "p-3 font-mono" >
2022-09-02 16:52:07 -07:00
{ amountOut ? numberFormat . format ( amountOut . toNumber ( ) ) : '' }
2022-08-25 06:00:42 -07:00
< / span >
) }
< / div >
< / div >
{ useMargin ? (
< >
< div className = "mb-1 flex items-center justify-between" >
< p className = "text-th-fgd-3" > { t ( 'leverage' ) } < / p >
{ /* <p className="text-th-fgd-1">0.00x</p> */ }
2022-08-15 04:28:36 -07:00
< / div >
2022-08-25 06:00:42 -07:00
< SwapLeverageSlider
2022-09-22 14:35:07 -07:00
useMargin = { useMargin }
2022-08-25 06:00:42 -07:00
amount = { amountIn . toNumber ( ) }
onChange = { setAmountInFormValue }
/ >
< / >
) : null }
2022-09-22 14:35:07 -07:00
< SwapFormSubmitButton
loadingSwapDetails = { loadingSwapDetails }
useMargin = { useMargin }
setShowConfirm = { setShowConfirm }
amountIn = { amountIn }
inputSymbol = { inputTokenInfo ? . symbol }
amountOut = { amountOut }
/ >
2022-07-05 20:37:49 -07:00
< / div >
2022-09-11 17:22:37 -07:00
< div
2022-09-21 21:25:24 -07:00
id = "swap-step-four"
2022-10-05 19:23:31 -07:00
className = { ` border-t border-th-bkg-3 px-6 py-4 transition-all ` }
2022-09-11 17:22:37 -07:00
>
< div className = "flex justify-between" >
2022-09-16 03:49:10 -07:00
< div className = "flex items-center" >
< HeartIcon className = "mr-1.5 h-4 w-4 text-th-fgd-4" / >
2022-09-19 23:31:07 -07:00
< Tooltip content = "Projects the health of your account before you make a trade. The first value is your current account health and the second, your projected account health." >
< p className = "tooltip-underline text-sm" > { t ( 'health-impact' ) } < / p >
< / Tooltip >
2022-09-16 03:49:10 -07:00
< / div >
2022-09-22 03:46:51 -07:00
< div className = "flex items-center space-x-2 font-mono" >
2022-09-11 17:22:37 -07:00
< p className = "text-sm text-th-fgd-1" > { currentMaintHealth } % < / p >
< ArrowRightIcon className = "h-4 w-4 text-th-fgd-4" / >
< p
className = { ` ${
maintProjectedHealth ! < 50 && maintProjectedHealth ! > 15
? 'text-th-orange'
: maintProjectedHealth ! <= 15
? 'text-th-red'
: 'text-th-green'
} text - sm ` }
>
{ maintProjectedHealth ! } % { ' ' }
< span
className = { ` text-xs ${
maintProjectedHealth ! >= currentMaintHealth !
? 'text-th-green'
: 'text-th-red'
} ` }
2022-08-25 06:00:42 -07:00
>
2022-09-11 17:22:37 -07:00
( { maintProjectedHealth ! >= currentMaintHealth ! ? '+' : '' }
{ maintProjectedHealth ! - currentMaintHealth ! } % )
< / span >
< / p >
2022-07-17 04:48:33 -07:00
< / div >
2022-08-24 03:51:06 -07:00
< / div >
2022-09-11 17:22:37 -07:00
< / div >
2022-07-05 20:37:49 -07:00
< / ContentBox >
)
}
2022-08-19 21:03:26 -07:00
export default SwapForm
2022-08-15 09:02:46 -07:00
2022-09-22 14:35:07 -07:00
const SwapFormSubmitButton = ( {
amountIn ,
amountOut ,
inputSymbol ,
loadingSwapDetails ,
setShowConfirm ,
useMargin ,
} : {
amountIn : Decimal
amountOut : Decimal
inputSymbol : string | undefined
loadingSwapDetails : boolean
setShowConfirm : ( x : any ) = > any
useMargin : boolean
} ) = > {
const { t } = useTranslation ( 'common' )
const connected = mangoStore ( ( s ) = > s . connected )
const { amount : tokenMax , amountWithBorrow } = useTokenMax ( useMargin )
const showInsufficientBalance = useMargin
? amountWithBorrow . lt ( amountIn )
: tokenMax . lt ( amountIn )
const disabled =
! amountIn . toNumber ( ) ||
! connected ||
showInsufficientBalance ||
! amountOut . gt ( 0 )
return (
< Button
onClick = { ( ) = > setShowConfirm ( true ) }
className = "mt-6 flex w-full items-center justify-center text-base"
disabled = { disabled }
size = "large"
>
{ connected ? (
showInsufficientBalance ? (
< div className = "flex items-center" >
< ExclamationCircleIcon className = "mr-2 h-5 w-5 flex-shrink-0" / >
{ t ( 'swap:insufficient-balance' , {
symbol : inputSymbol ,
} ) }
< / div >
) : loadingSwapDetails ? (
< Loading / >
) : disabled ? (
< div className = "flex items-center" >
< ExclamationCircleIcon className = "mr-2 h-5 w-5 flex-shrink-0" / >
No routes found
< / div >
) : (
< div className = "flex items-center" >
< MagnifyingGlassIcon className = "mr-2 h-5 w-5" / >
{ t ( 'swap:review-swap' ) }
< / div >
)
) : (
< div className = "flex items-center" >
< WalletIcon className = "mr-2 h-5 w-5" / >
{ t ( 'connect' ) }
< / div >
) }
< / Button >
)
}
2022-08-17 21:13:50 -07:00
const MaxSwapAmount = ( {
2022-08-15 09:02:46 -07:00
setAmountIn ,
2022-08-17 21:13:50 -07:00
useMargin ,
2022-08-15 09:02:46 -07:00
} : {
2022-08-31 08:54:43 -07:00
setAmountIn : ( x : string ) = > void
2022-08-17 21:13:50 -07:00
useMargin : boolean
2022-08-15 09:02:46 -07:00
} ) = > {
const { t } = useTranslation ( 'common' )
2022-09-22 14:35:07 -07:00
const mangoAccountLoading = mangoStore ( ( s ) = > s . mangoAccount . initialLoad )
const {
amount : tokenMax ,
amountWithBorrow ,
decimals ,
} = useTokenMax ( useMargin )
2022-08-15 09:02:46 -07:00
2022-08-19 14:25:31 -07:00
if ( mangoAccountLoading ) return null
2022-08-15 09:02:46 -07:00
return (
2022-10-05 04:25:26 -07:00
< div className = "flex flex-wrap justify-end pl-6 text-xs" >
2022-10-05 16:03:10 -07:00
< MaxAmountButton
className = "mb-0.5"
label = "Bal"
2022-10-05 04:25:26 -07:00
onClick = { ( ) = > setAmountIn ( tokenMax . toFixed ( decimals ) ) }
2022-10-05 16:03:10 -07:00
value = { tokenMax . toFixed ( ) }
/ >
2022-10-05 04:25:26 -07:00
{ useMargin ? (
2022-10-05 16:03:10 -07:00
< MaxAmountButton
className = "mb-0.5 ml-2"
label = { t ( 'max' ) }
2022-10-05 04:25:26 -07:00
onClick = { ( ) = > setAmountIn ( amountWithBorrow . toFixed ( decimals ) ) }
2022-10-05 16:03:10 -07:00
value = { amountWithBorrow . toFixed ( ) }
/ >
2022-10-05 04:25:26 -07:00
) : null }
< / div >
2022-08-15 09:02:46 -07:00
)
}
const PercentageSelectButtons = ( {
2022-08-23 05:41:37 -07:00
amountIn ,
2022-08-15 09:02:46 -07:00
setAmountIn ,
2022-09-22 14:35:07 -07:00
useMargin ,
2022-08-15 09:02:46 -07:00
} : {
2022-08-23 05:41:37 -07:00
amountIn : string
2022-08-31 08:54:43 -07:00
setAmountIn : ( x : string ) = > any
2022-09-22 14:35:07 -07:00
useMargin : boolean
2022-08-15 09:02:46 -07:00
} ) = > {
const [ sizePercentage , setSizePercentage ] = useState ( '' )
2022-09-22 14:35:07 -07:00
const { amount : tokenMax , decimals } = useTokenMax ( useMargin )
2022-08-15 09:02:46 -07:00
2022-08-23 05:41:37 -07:00
useEffect ( ( ) = > {
2022-09-13 17:19:56 -07:00
if ( tokenMax . gt ( 0 ) && amountIn && tokenMax . eq ( amountIn ) ) {
2022-08-23 05:41:37 -07:00
setSizePercentage ( '100' )
}
} , [ amountIn , tokenMax ] )
2022-08-15 09:02:46 -07:00
const handleSizePercentage = ( percentage : string ) = > {
setSizePercentage ( percentage )
2022-09-02 16:52:07 -07:00
if ( tokenMax . gt ( 0 ) ) {
let amount = tokenMax . mul ( percentage ) . div ( 100 )
2022-08-15 21:19:09 -07:00
if ( percentage !== '100' ) {
amount = floorToDecimal ( amount , decimals )
}
2022-09-02 11:36:57 -07:00
setAmountIn ( amount . toFixed ( ) )
2022-08-15 20:16:20 -07:00
} else {
setAmountIn ( '0' )
2022-08-15 09:02:46 -07:00
}
}
return (
< div className = "col-span-2 mt-2" >
< ButtonGroup
activeValue = { sizePercentage }
onChange = { ( p ) = > handleSizePercentage ( p ) }
values = { [ '10' , '25' , '50' , '75' , '100' ] }
unit = "%"
/ >
< / div >
)
}