'use client' import React, { useState } from 'react' import { Box, SxProps } from '@mui/material' import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyFormField' import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField' import { CurrencyDenom, DecCoin } from '@nymproject/types' import { useWalletContext } from '@/app/context/wallet' import { urls } from '@/app/utils' import { useDelegationsContext } from '@/app/context/delegations' import { validateAmount } from '@/app/utils/currency' import { SimpleModal } from './SimpleModal' import { ModalListItem } from './ModalListItem' import { DelegationModalProps } from './DelegationModal' const MIN_AMOUNT_TO_DELEGATE = 10 type Props = { mixId: number identityKey: string header?: string buttonText?: string rewardInterval?: string estimatedReward?: number profitMarginPercentage?: string | null nodeUptimePercentage?: number | null denom: CurrencyDenom sx?: SxProps backdropProps?: object onClose: () => void onOk?: (delegationModalProps: DelegationModalProps) => void } export const DelegateModal = ({ mixId, identityKey, onClose, onOk, denom, sx, }: Props) => { const [amount, setAmount] = useState({ amount: '10', denom: 'nym', }) const [isValidated, setValidated] = useState(false) const [errorAmount, setErrorAmount] = useState() const { address, balance } = useWalletContext() const { handleDelegate } = useDelegationsContext() const validate = async () => { let newValidatedValue = true let errorAmountMessage if (amount && !(await validateAmount(amount.amount, '0'))) { newValidatedValue = false errorAmountMessage = 'Please enter a valid amount' } if (amount && +amount.amount < MIN_AMOUNT_TO_DELEGATE) { errorAmountMessage = `Min. delegation amount: ${MIN_AMOUNT_TO_DELEGATE} ${denom.toUpperCase()}` newValidatedValue = false } if (!amount?.amount.length) { newValidatedValue = false } if (amount && balance.data && +balance.data - +amount.amount <= 0) { errorAmountMessage = 'Not enough funds' newValidatedValue = false } setErrorAmount(errorAmountMessage) setValidated(newValidatedValue) } const delegateToMixnode = async ({ delegationMixId, delegationAmount, }: { delegationMixId: number delegationAmount: string }) => { try { const tx = await handleDelegate(delegationMixId, delegationAmount) return tx } catch (e) { console.error('Failed to delegate to mixnode', e) throw e } } const handleConfirm = async () => { if (mixId && amount && onOk) { onOk({ status: 'loading', }) try { if (!address) { throw new Error('Please connect your wallet') } const tx = await delegateToMixnode({ delegationMixId: mixId, delegationAmount: amount.amount, }) if (!tx) { throw new Error('Failed to delegate') } onOk({ status: 'success', message: 'Delegation can take up to one hour to process', transactions: [ { url: `${urls('MAINNET').blockExplorer}/transaction/${ tx.transactionHash }`, hash: tx.transactionHash, }, ], }) } catch (e) { console.error('Failed to delegate', e) onOk({ status: 'error', message: (e as Error).message, }) } } } const handleAmountChanged = (newAmount: DecCoin) => { setAmount(newAmount) } React.useEffect(() => { validate() }, [amount, identityKey, mixId]) return ( undefined} initialValue={identityKey} readOnly showTickOnValid={false} /> ) }