import { Transition } from '@headlessui/react' import { ArrowDownTrayIcon, CheckCircleIcon, FireIcon, PencilIcon, PlusCircleIcon, XMarkIcon, } from '@heroicons/react/20/solid' import { Wallet } from '@project-serum/anchor' import { useWallet } from '@solana/wallet-adapter-react' import mangoStore from '@store/mangoStore' import Decimal from 'decimal.js' import useLocalStorageState from 'hooks/useLocalStorageState' import { useTranslation } from 'next-i18next' import Image from 'next/image' import { ChangeEvent, useCallback, useEffect, useMemo, useState } from 'react' import { IS_ONBOARDED_KEY } from 'utils/constants' import { notify } from 'utils/notifications' import { floorToDecimal } from 'utils/numbers' import ActionTokenList from './account/ActionTokenList' import ButtonGroup from './forms/ButtonGroup' import Input from './forms/Input' import Label from './forms/Label' import WalletIcon from './icons/WalletIcon' import { walletBalanceForToken } from './modals/DepositModal' import ParticlesBackground from './ParticlesBackground' import BounceLoader from './shared/BounceLoader' import Button, { IconButton, LinkButton } from './shared/Button' import InlineNotification from './shared/InlineNotification' import MaxAmountButton from './shared/MaxAmountButton' import { EnterRightExitLeft, FadeInFadeOut } from './shared/Transitions' import { handleWalletConnect } from './wallet/ConnectWalletButton' const UserSetup = ({ onClose }: { onClose: () => void }) => { const { t } = useTranslation() const group = mangoStore((s) => s.group) const { connected, select, wallet, wallets } = useWallet() const mangoAccount = mangoStore((s) => s.mangoAccount.current) const mangoAccountLoading = mangoStore((s) => s.mangoAccount.initialLoad) const [accountName, setAccountName] = useState('') const [loadingAccount, setLoadingAccount] = useState(false) const [showSetupStep, setShowSetupStep] = useState(0) const [depositToken, setDepositToken] = useState('') const [depositAmount, setDepositAmount] = useState('') const [submitDeposit, setSubmitDeposit] = useState(false) const [sizePercentage, setSizePercentage] = useState('') const [showEditProfilePic, setShowEditProfilePic] = useState(false) const [, setIsOnboarded] = useLocalStorageState(IS_ONBOARDED_KEY) const walletTokens = mangoStore((s) => s.wallet.tokens) const connectWallet = async () => { if (wallet) { try { await handleWalletConnect(wallet) setShowSetupStep(2) setIsOnboarded(true) } catch (e) { notify({ title: 'Setup failed. Refresh and try again.', type: 'error', }) } } } const handleCreateAccount = useCallback(async () => { const client = mangoStore.getState().client const group = mangoStore.getState().group const actions = mangoStore.getState().actions if (!group || !wallet) return setLoadingAccount(true) try { const tx = await client.createMangoAccount( group, 0, accountName || 'Account 1', undefined, // tokenCount undefined, // serum3Count 8, // perpCount 8 // perpOoCount ) actions.fetchMangoAccounts(wallet!.adapter as unknown as Wallet) if (tx) { setLoadingAccount(false) setShowSetupStep(3) notify({ title: t('new-account-success'), type: 'success', txid: tx, }) } } catch (e: any) { setLoadingAccount(false) notify({ title: t('new-account-failed'), txid: e?.signature, type: 'error', }) console.error(e) } }, [accountName, wallet, t]) const handleDeposit = useCallback(async () => { const client = mangoStore.getState().client const group = mangoStore.getState().group const actions = mangoStore.getState().actions const mangoAccount = mangoStore.getState().mangoAccount.current if (!mangoAccount || !group) return const bank = group.banksMapByName.get(depositToken)![0] try { setSubmitDeposit(true) const tx = await client.tokenDeposit( group, mangoAccount, bank.mint, parseFloat(depositAmount) ) notify({ title: 'Transaction confirmed', type: 'success', txid: tx, }) await actions.reloadMangoAccount() onClose() setSubmitDeposit(false) } catch (e: any) { notify({ title: 'Transaction failed', description: e.message, txid: e?.txid, type: 'error', }) setSubmitDeposit(false) console.error(e) } }, [depositAmount, depositToken, onClose]) useEffect(() => { if (mangoAccount && showSetupStep === 2) { onClose() } }, [mangoAccount, showSetupStep, onClose]) const banks = useMemo(() => { const banks = group?.banksMapByName ? Array.from(group?.banksMapByName, ([key, value]) => { const walletBalance = walletBalanceForToken(walletTokens, key) return { key, value, tokenDecimals: walletBalance.maxDecimals, walletBalance: floorToDecimal( walletBalance.maxAmount, walletBalance.maxDecimals ).toNumber(), walletBalanceValue: walletBalance.maxAmount * value[0]?.uiPrice!, } }) : [] return banks }, [group?.banksMapByName, walletTokens]) const tokenMax = useMemo(() => { const bank = banks.find((bank) => bank.key === depositToken) if (bank) { return { amount: bank.walletBalance, decimals: bank.tokenDecimals } } return { amount: 0, decimals: 0 } }, [banks, depositToken]) const handleSizePercentage = useCallback( (percentage: string) => { setSizePercentage(percentage) let amount = new Decimal(tokenMax.amount).mul(percentage).div(100) if (percentage !== '100') { amount = floorToDecimal(amount, tokenMax.decimals) } setDepositAmount(amount.toString()) }, [tokenMax] ) const handleNextStep = () => { setShowSetupStep(showSetupStep + 1) } return (

Better than your average exchange

We've got DeFi covered. Trade, swap, borrow and lend all of your favorite tokens with low fees and lightning execution.

Fully permissionless and trusted by 1,000s of DeFi users

{/*

Deeply liquid markets

*/}

Up to 20x leverage across 100s of tokens

Automatically earn interest on your deposits

Borrow 100s of tokens with many collateral options

{connected && mangoAccountLoading ? (
) : (

Connect Wallet

Choose Wallet

{wallets?.map((w) => ( ))}
)}
{loadingAccount ? (
) : (

Create Your Account

You need a Mango Account to get started.

Account Name{' '} (Optional)

) => setAccountName(e.target.value) } />
Skip for now
)}
{submitDeposit ? (
) : (

Fund Your Account

0} enter="transition ease-in duration-300" enterFrom="opacity-0" enterTo="opacity-100" leave="transition ease-out duration-300" leaveFrom="opacity-100" leaveTo="opacity-0" >
) => setDepositAmount(e.target.value) } />
handleSizePercentage(p)} values={['10', '25', '50', '75', '100']} unit="%" />

{t('token')}

{t('deposit-rate')}

{t('wallet-balance')}

Skip for now
)}
onClose()}>
next
) } export default UserSetup