import { HealthType } from '@blockworks-foundation/mango-v4' import { ChevronDownIcon, CurrencyDollarIcon, ExclamationCircleIcon, } from '@heroicons/react/20/solid' import Decimal from 'decimal.js' import { useTranslation } from 'next-i18next' import Image from 'next/image' import React, { useCallback, useMemo, useState } from 'react' import NumberFormat, { NumberFormatValues } from 'react-number-format' import mangoStore from '@store/mangoStore' import { ModalProps } from '../../types/modal' import { INPUT_TOKEN_DEFAULT } from '../../utils/constants' import { notify } from '../../utils/notifications' import { floorToDecimal, formatFixedDecimals } from '../../utils/numbers' import ActionTokenList from '../account/ActionTokenList' import ButtonGroup from '../forms/ButtonGroup' import Label from '../forms/Label' import Button, { LinkButton } from '../shared/Button' import HealthImpact from '../shared/HealthImpact' import InlineNotification from '../shared/InlineNotification' import Loading from '../shared/Loading' import Modal from '../shared/Modal' import { EnterBottomExitBottom, FadeInFadeOut } from '../shared/Transitions' import { withValueLimit } from '../swap/SwapForm' import { getMaxWithdrawForBank } from '../swap/useTokenMax' import MaxAmountButton from '@components/shared/MaxAmountButton' interface BorrowModalProps { token?: string } type ModalCombinedProps = BorrowModalProps & ModalProps function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) { const { t } = useTranslation('common') const group = mangoStore((s) => s.group) const [inputAmount, setInputAmount] = useState('') const [submitting, setSubmitting] = useState(false) const [selectedToken, setSelectedToken] = useState( token || INPUT_TOKEN_DEFAULT ) const [showTokenList, setShowTokenList] = useState(false) const [sizePercentage, setSizePercentage] = useState('') const jupiterTokens = mangoStore((s) => s.jupiterTokens) const bank = useMemo(() => { const group = mangoStore.getState().group return group?.banksMapByName.get(selectedToken)![0] }, [selectedToken]) const logoUri = useMemo(() => { let logoURI if (jupiterTokens.length) { logoURI = jupiterTokens.find( (t) => t.address === bank?.mint.toString() )!.logoURI } return logoURI }, [jupiterTokens, bank]) const mangoAccount = mangoStore((s) => s.mangoAccount.current) const tokenMax = useMemo(() => { const group = mangoStore.getState().group if (!group || !bank || !mangoAccount) return new Decimal(0) return getMaxWithdrawForBank(group, bank, mangoAccount, true) }, [mangoAccount, bank]) const setMax = useCallback(() => { setInputAmount(tokenMax.toFixed()) }, [tokenMax]) const handleSizePercentage = useCallback( (percentage: string) => { if (!bank) return setSizePercentage(percentage) const amount = (Number(percentage) / 100) * (tokenMax.toNumber() || 0) setInputAmount(floorToDecimal(amount, bank.mintDecimals).toFixed()) }, [tokenMax, bank] ) const handleSelectToken = (token: string) => { setSelectedToken(token) setShowTokenList(false) } const handleWithdraw = async () => { const client = mangoStore.getState().client const group = mangoStore.getState().group const mangoAccount = mangoStore.getState().mangoAccount.current const actions = mangoStore.getState().actions if (!mangoAccount || !group) return setSubmitting(true) try { const tx = await client.tokenWithdraw( group, mangoAccount, bank!.mint, Number(inputAmount), true ) notify({ title: 'Transaction confirmed', type: 'success', txid: tx, }) actions.reloadMangoAccount() } catch (e: any) { console.error(e) notify({ title: 'Transaction failed', description: e.message, txid: e?.txid, type: 'error', }) } finally { setSubmitting(false) onClose() } } const banks = useMemo(() => { if (mangoAccount) { return group?.banksMapByName ? Array.from(group?.banksMapByName, ([key, value]) => { const bank = value[0] const maxAmount = getMaxWithdrawForBank( group, bank, mangoAccount, true ) return { key, value, maxAmount: maxAmount.toNumber() } }) : [] } return [] }, [mangoAccount, group]) const initHealth = useMemo(() => { return group && mangoAccount ? mangoAccount.getHealthRatioUi(group, HealthType.init) : 100 }, [mangoAccount]) const showInsufficientBalance = Number(inputAmount) ? tokenMax.lt(inputAmount) : false return (

{t('select-token')}

{t('token')}

{t('borrow-rate')}

{t('max-borrow')}

{t('borrow')}

{initHealth && initHealth <= 0 ? (
) : null}
setInputAmount(Number(e.value) ? e.value : '') } isAllowed={withValueLimit} />
handleSizePercentage(p)} values={['10', '25', '50', '75', '100']} unit="%" />
{/*

{t('leverage')}

0.00x

setInputAmount(x)} />
*/}

{t('borrow-value')}

{formatFixedDecimals( bank?.uiPrice! * Number(inputAmount), true )}

) } export default BorrowModal