import { useState, useCallback, useEffect } from 'react' import { PublicKey } from '@solana/web3.js' import mangoStore from '@store/mangoStore' import ContentBox from '../shared/ContentBox' import { useTranslation } from 'next-i18next' import SwapFormTokenList from './SwapFormTokenList' import { EnterBottomExitBottom } from '../shared/Transitions' import { OUTPUT_TOKEN_DEFAULT, SWAP_MARGIN_KEY } from '../../utils/constants' import TokenVaultWarnings from '@components/shared/TokenVaultWarnings' import SwapSettings from './SwapSettings' import InlineNotification from '@components/shared/InlineNotification' import Tooltip from '@components/shared/Tooltip' import MarketSwapForm from './MarketSwapForm' import Switch from '@components/forms/Switch' import useLocalStorageState from 'hooks/useLocalStorageState' import { SwapFormTokenListType } from './SwapFormTokenList' import { SwapTypes } from 'types' import TriggerSwapForm from './TriggerSwapForm' import WalletSwapForm from './WalletSwapForm' import TabButtons from '@components/shared/TabButtons' import useMangoAccount from 'hooks/useMangoAccount' import { useWallet } from '@solana/wallet-adapter-react' import { useRouter } from 'next/router' import SwapSummaryInfo from './SwapSummaryInfo' const set = mangoStore.getState().set export const handleTokenInSelect = (mintAddress: string, close: () => void) => { const group = mangoStore.getState().group if (group) { const bank = group.getFirstBankByMint(new PublicKey(mintAddress)) set((s) => { s.swap.inputBank = bank }) } close() } export const handleTokenOutSelect = ( mintAddress: string, close: () => void, ) => { const group = mangoStore.getState().group if (group) { const bank = group.getFirstBankByMint(new PublicKey(mintAddress)) set((s) => { s.swap.outputBank = bank }) } close() } const SwapForm = () => { const { t } = useTranslation(['common', 'swap', 'trade']) const groupLoaded = mangoStore((s) => s.groupLoaded) const { mangoAccountAddress, initialLoad } = useMangoAccount() const { connected } = useWallet() const { query } = useRouter() const [showTokenSelect, setShowTokenSelect] = useState() const [showSettings, setShowSettings] = useState(false) const [walletSwap, setWalletSwap] = useState(false) const [, setSavedSwapMargin] = useLocalStorageState( SWAP_MARGIN_KEY, true, ) const { margin: useMargin, inputBank, outputBank, swapOrTrigger, } = mangoStore((s) => s.swap) // enable wallet swap when connected and no mango account useEffect(() => { if (connected && !mangoAccountAddress && !initialLoad) { setWalletSwap(true) } }, [connected, mangoAccountAddress, initialLoad]) // setup swap from url query useEffect(() => { const { group } = mangoStore.getState() if ('walletSwap' in query) { setWalletSwap(true) } if (!groupLoaded) return if (query.in) { const inBank = group?.banksMapByName.get(query.in.toString())?.[0] set((state) => { state.swap.inputBank = inBank }) } if (query.out) { const outBank = group?.banksMapByName.get(query.out.toString())?.[0] set((state) => { state.swap.outputBank = outBank }) } }, [groupLoaded, query]) const handleSwapOrTrigger = useCallback( (orderType: SwapTypes) => { set((state) => { state.swap.swapOrTrigger = orderType if (orderType !== 'swap' && outputBank?.name === OUTPUT_TOKEN_DEFAULT) { const { group } = mangoStore.getState() const outputBankName = inputBank?.name === 'USDC' ? 'SOL' : 'USDC' state.swap.outputBank = group?.banksMapByName.get(outputBankName)?.[0] } }) }, [inputBank, outputBank], ) useEffect(() => { setSavedSwapMargin(useMargin) }, [useMargin]) return (
setShowTokenSelect(undefined)} onTokenSelect={ showTokenSelect === 'input' || showTokenSelect === 'reduce-input' || showTokenSelect === 'wallet-input' ? handleTokenInSelect : handleTokenOutSelect } type={showTokenSelect} useMargin={swapOrTrigger === 'swap' ? useMargin : false} walletSwap={walletSwap} /> setShowSettings(false)} />
handleSwapOrTrigger(v)} />
{swapOrTrigger === 'swap' ? ( <>
setWalletSwap(!walletSwap)} small > {t('swap:wallet-swap')}
{walletSwap ? (
) : (
)} ) : (
)}
{inputBank && !walletSwap ? ( ) : null} {inputBank && !walletSwap && inputBank.areBorrowsReduceOnly() && useMargin ? (
) : null} {outputBank && !walletSwap && outputBank.areDepositsReduceOnly() ? (
) : null}
) } export default SwapForm