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 (
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
Choose Wallet
You need a Mango Account to get started.
Account Name{' '} (Optional)
) => setAccountName(e.target.value) } />{t('token')}
{t('deposit-rate')}
{t('wallet-balance')}