import { ArrowPathIcon, ExclamationCircleIcon } from '@heroicons/react/20/solid' import { useWallet } from '@solana/wallet-adapter-react' import { useTranslation } from 'next-i18next' import React, { useCallback, useEffect, useMemo, useState } from 'react' import NumberFormat, { NumberFormatValues } from 'react-number-format' import mangoStore from '@store/mangoStore' import { ACCOUNT_ACTION_MODAL_INNER_HEIGHT, // INPUT_TOKEN_DEFAULT, } from '../utils/constants' import { notify } from '../utils/notifications' import { TokenAccount, formatTokenSymbol } from '../utils/tokens' // import ActionTokenList from './account/ActionTokenList' import Label from './forms/Label' import Button, { IconButton } from './shared/Button' import Loading from './shared/Loading' import { EnterBottomExitBottom, FadeInFadeOut } from './shared/Transitions' import MaxAmountButton from '@components/shared/MaxAmountButton' import Tooltip from '@components/shared/Tooltip' import SolBalanceWarnings from '@components/shared/SolBalanceWarnings' import useSolBalance from 'hooks/useSolBalance' import { floorToDecimal, withValueLimit } from 'utils/numbers' import BankAmountWithValue from './shared/BankAmountWithValue' // import useBanksWithBalances from 'hooks/useBanksWithBalances' import { isMangoError } from 'types' // import TokenListButton from './shared/TokenListButton' import TokenLogo from './shared/TokenLogo' import SecondaryConnectButton from './shared/SecondaryConnectButton' import useMangoAccountAccounts from 'hooks/useMangoAccountAccounts' import InlineNotification from './shared/InlineNotification' import Link from 'next/link' import BackButton from './swap/BackButton' import useMangoGroup from 'hooks/useMangoGroup' import FormatNumericValue from './shared/FormatNumericValue' import useMangoAccount from 'hooks/useMangoAccount' import { unstakeAndClose } from 'utils/transactions' const set = mangoStore.getState().set interface UnstakeFormProps { onSuccess: () => void token: string } export const walletBalanceForToken = ( walletTokens: TokenAccount[], token: string, ): { maxAmount: number; maxDecimals: number } => { const group = mangoStore.getState().group const bank = group?.banksMapByName.get(token)?.[0] let walletToken if (bank) { const tokenMint = bank?.mint walletToken = tokenMint ? walletTokens.find((t) => t.mint.toString() === tokenMint.toString()) : null } return { maxAmount: walletToken ? walletToken.uiAmount : 0, maxDecimals: bank?.mintDecimals || 6, } } function UnstakeForm({ onSuccess, token: selectedToken }: UnstakeFormProps) { const { t } = useTranslation(['common', 'account']) const [inputAmount, setInputAmount] = useState('') const [submitting, setSubmitting] = useState(false) // const [selectedToken, setSelectedToken] = useState( // token || INPUT_TOKEN_DEFAULT, // ) const [showTokenList, setShowTokenList] = useState(false) const [refreshingWalletTokens, setRefreshingWalletTokens] = useState(false) const { maxSolDeposit } = useSolBalance() // const banks = useBanksWithBalances('walletBalance') const { usedTokens, totalTokens } = useMangoAccountAccounts() const { group } = useMangoGroup() const { mangoAccount } = useMangoAccount() const stakeBank = useMemo(() => { return group?.banksMapByName.get(selectedToken)?.[0] }, [selectedToken, group]) const solBank = useMemo(() => { return group?.banksMapByName.get('SOL')?.[0] }, [group]) const tokenPositionsFull = useMemo(() => { if (!stakeBank || !usedTokens.length || !totalTokens.length) return false const hasTokenPosition = usedTokens.find( (token) => token.tokenIndex === stakeBank.tokenIndex, ) return hasTokenPosition ? false : usedTokens.length >= totalTokens.length }, [stakeBank, usedTokens, totalTokens]) const { connected, publicKey } = useWallet() const tokenMax = useMemo(() => { if (!stakeBank || !mangoAccount) return { maxAmount: 0.0, maxDecimals: 6 } return { maxAmount: mangoAccount.getTokenBalanceUi(stakeBank), maxDecimals: stakeBank.mintDecimals, } }, [stakeBank, mangoAccount]) const setMax = useCallback(() => { const max = floorToDecimal(tokenMax.maxAmount, tokenMax.maxDecimals) setInputAmount(max.toFixed()) }, [tokenMax]) // const handleSelectToken = (token: string) => { // setSelectedToken(token) // setShowTokenList(false) // } const handleRefreshWalletBalances = useCallback(async () => { if (!publicKey) return const actions = mangoStore.getState().actions setRefreshingWalletTokens(true) await actions.fetchMangoAccounts(publicKey) setRefreshingWalletTokens(false) }, [publicKey]) const solBorrowed = useMemo(() => { if (!solBank || !mangoAccount) return 0.0 return mangoAccount.getTokenBalanceUi(solBank) }, [solBank, mangoAccount]) const handleWithdraw = useCallback(async () => { const client = mangoStore.getState().client const group = mangoStore.getState().group const actions = mangoStore.getState().actions const mangoAccount = mangoStore.getState().mangoAccount.current if (!group || !stakeBank || !publicKey || !mangoAccount) return setSubmitting(true) try { console.log('starting deposit') const { signature: tx } = await unstakeAndClose( client, group, mangoAccount, stakeBank.mint, Number(inputAmount), ) notify({ title: 'Transaction confirmed', type: 'success', txid: tx, }) await actions.fetchMangoAccounts(mangoAccount.owner) await actions.fetchWalletTokens(publicKey) setSubmitting(false) onSuccess() } catch (e) { console.error('Error depositing:', e) setSubmitting(false) if (!isMangoError(e)) return notify({ title: 'Transaction failed', description: e.message, txid: e?.txid, type: 'error', }) } }, [stakeBank, publicKey, inputAmount, onSuccess]) const showInsufficientBalance = tokenMax.maxAmount < Number(inputAmount) || (selectedToken === 'SOL' && maxSolDeposit <= 0) useEffect(() => { const group = mangoStore.getState().group set((state) => { state.swap.outputBank = group?.banksMapByName.get(selectedToken)?.[0] }) }, [selectedToken]) return ( <> setShowTokenList(false)} />

Select token to unstake

{t('token')}

{t('wallet-balance')}

{/* */}
{/*
} setShowList={setShowTokenList} />
*/}
{ setInputAmount( !Number.isNaN(Number(e.value)) ? e.value : '', ) }} isAllowed={withValueLimit} />
{formatTokenSymbol(selectedToken)}
{stakeBank && solBank ? ( <>

Staked Amount

SOL borrowed

{solBank ? ( ) : null}
) : null}
{connected ? ( ) : ( )} {tokenPositionsFull ? ( {t('error-token-positions-full')}{' '} onSuccess()} shallow> {t('manage')} } /> ) : null}
) } export default UnstakeForm