import { ChangeEvent, useCallback, useMemo, useState } from 'react' import { useTranslation } from 'next-i18next' import mangoStore from '@store/mangoStore' import { createSolanaMessage, notify } from '../../utils/notifications' import Button, { IconButton, LinkButton } from '../shared/Button' import BounceLoader from '../shared/BounceLoader' import Input from '../forms/Input' import Label from '../forms/Label' import { useWallet } from '@solana/wallet-adapter-react' import InlineNotification from '../shared/InlineNotification' import { MangoAccount } from '@blockworks-foundation/mango-v4' import { ArrowLeftIcon } from '@heroicons/react/20/solid' import useSolBalance from 'hooks/useSolBalance' import { isMangoError } from 'types' import { MAX_ACCOUNTS } from 'utils/constants' import Switch from '@components/forms/Switch' import NotificationCookieStore from '@store/notificationCookieStore' import { usePlausible } from 'next-plausible' import { TelemetryEvents } from 'utils/telemetry' import { waitForSlot } from 'utils/network' import CreateAccountAdvancedOptions, { ACCOUNT_SLOTS, DEFAULT_SLOTS, } from './CreateAccountAdvancedOptions' import { EnterBottomExitBottom } from '@components/shared/Transitions' const getNextAccountNumber = (accounts: MangoAccount[]): number => { if (accounts.length > 1) { return ( accounts .map((a) => a.accountNum) .reduce((a, b) => Math.max(a, b), -Infinity) + 1 ) } else if (accounts.length === 1) { return accounts[0].accountNum + 1 } return 0 } const CreateAccountForm = ({ customClose, handleBack, }: { customClose?: () => void handleBack?: () => void }) => { const { t } = useTranslation('common') const [loading, setLoading] = useState(false) const [name, setName] = useState('') const [signToNotifications, setSignToNotifications] = useState(true) const [showAdvancedOptionsAccountForm, setShowAdvancedOptionsAccountForm] = useState(false) const [slots, setSlots] = useState(DEFAULT_SLOTS) //whole context needed to sign msgs const walletContext = useWallet() const { maxSolDeposit } = useSolBalance() const telemetry = usePlausible() const setCookie = NotificationCookieStore((s) => s.setCookie) const hasSetCustomOptions = useMemo(() => { return !!Object.entries(slots).find( (slot) => slot[1] !== DEFAULT_SLOTS[slot[0] as keyof ACCOUNT_SLOTS], ) }, [slots]) const handleNewAccount = useCallback(async () => { const client = mangoStore.getState().client const group = mangoStore.getState().group const existingMangoAccts = mangoStore.getState().mangoAccounts const set = mangoStore.getState().set const connection = mangoStore.getState().connection if (!group || !walletContext.wallet) return setLoading(true) const perpOpenOrdersSlots = slots.perpSlots ? parseInt(MAX_ACCOUNTS.perpOpenOrders) : 0 try { const newAccountNum = getNextAccountNumber(existingMangoAccts) const { signature: tx, slot } = await client.createMangoAccount( group, newAccountNum, name || `Account ${newAccountNum + 1}`, slots.tokenSlots, // tokens slots.serumSlots, // serum3 slots.perpSlots, // perps perpOpenOrdersSlots, // perp Oo ) if (tx) { if (signToNotifications) { createSolanaMessage(walletContext, setCookie) } const pk = walletContext.wallet.adapter.publicKey await waitForSlot(connection, slot!) const mangoAccounts = await client.getMangoAccountsForOwner(group, pk!) const reloadedMangoAccounts = await Promise.all( mangoAccounts.map((ma) => ma.reloadSerum3OpenOrders(client)), ) const newAccount = mangoAccounts.find( (acc) => acc.accountNum === newAccountNum, ) const filteredMangoAccounts = reloadedMangoAccounts?.length ? reloadedMangoAccounts.filter( (acc) => !acc.name.includes('Leverage Stake'), ) : [] if (newAccount) { set((s) => { s.mangoAccount.current = newAccount s.mangoAccount.lastSlot = slot! s.mangoAccounts = filteredMangoAccounts }) } telemetry('accountCreate', { props: { accountNum: newAccountNum, enableNotifications: signToNotifications, }, }) setLoading(false) notify({ title: t('new-account-success'), type: 'success', txid: tx, }) if (customClose) { customClose() } } } catch (e) { console.error(e) setLoading(false) if (!isMangoError(e)) return notify({ title: t('new-account-failed'), txid: e?.txid, type: 'error', }) } }, [ customClose, name, setCookie, signToNotifications, slots, t, telemetry, walletContext, ]) return loading ? (
) : (
{handleBack ? ( ) : null}

{t('create-account')}

{handleBack ?
: null}

{t('insufficient-sol')}

) => setName(e.target.value) } maxLength={30} />

{t('enable-notifications')}

{t('asked-sign-transaction')}

setSignToNotifications(checked)} />
{maxSolDeposit <= 0 ? ( ) : null} setShowAdvancedOptionsAccountForm(true)} > {t('account:advanced-options')} {hasSetCustomOptions ? (

{t('account:custom-account-options-saved')}

) : null}
setShowAdvancedOptionsAccountForm(false)} />
) } export default CreateAccountForm