import { FC, useCallback, useEffect, useMemo, useState } from 'react' import Container from '../Container' import Flex from '../Flex' import Input from '../Input' import Select from '../Select' import Text from '../Text' import { SelectOption, TransactionState, transactionsOptions, TxFields, getTxFields, defaultTransactionType } from '../../state/transactions' import { useSnapshot } from 'valtio' import state from '../../state' import { streamState } from '../DebugStream' import { Button } from '..' import Textarea from '../Textarea' interface UIProps { setState: (pTx?: Partial | undefined) => TransactionState | undefined state: TransactionState estimateFee?: (...arg: any) => Promise } export const TxUI: FC = ({ state: txState, setState, estimateFee }) => { const { accounts } = useSnapshot(state) const { selectedAccount, selectedDestAccount, selectedTransaction, txFields } = txState const accountOptions: SelectOption[] = accounts.map(acc => ({ label: acc.name, value: acc.address })) const destAccountOptions: SelectOption[] = accounts .map(acc => ({ label: acc.name, value: acc.address })) .filter(acc => acc.value !== selectedAccount?.value) const [feeLoading, setFeeLoading] = useState(false) const resetFields = useCallback( (tt: string) => { const fields = getTxFields(tt) if (fields.Destination !== undefined) { setState({ selectedDestAccount: null }) fields.Destination = '' } else { fields.Destination = undefined } return setState({ txFields: fields }) }, [setState] ) const handleSetAccount = (acc: SelectOption) => { setState({ selectedAccount: acc }) streamState.selectedAccount = acc } const handleSetField = useCallback( (field: keyof TxFields, value: string, opFields?: TxFields) => { const fields = opFields || txFields const obj = fields[field] setState({ txFields: { ...fields, [field]: typeof obj === 'object' ? { ...obj, $value: value } : value } }) }, [setState, txFields] ) const handleEstimateFee = useCallback( async (state?: TransactionState, silent?: boolean) => { setFeeLoading(true) const fee = await estimateFee?.(state, { silent }) if (fee) handleSetField('Fee', fee, state?.txFields) setFeeLoading(false) }, [estimateFee, handleSetField] ) const handleChangeTxType = useCallback( (tt: SelectOption) => { setState({ selectedTransaction: tt }) const newState = resetFields(tt.value) handleEstimateFee(newState, true) }, [handleEstimateFee, resetFields, setState] ) const switchToJson = () => setState({ viewType: 'json' }) // default tx useEffect(() => { if (selectedTransaction?.value) return if (defaultTransactionType) { handleChangeTxType(defaultTransactionType) } }, [handleChangeTxType, selectedTransaction?.value]) const fields = useMemo( () => getTxFields(selectedTransaction?.value), [selectedTransaction?.value] ) const specialFields = ['TransactionType', 'Account'] if (fields.Destination !== undefined) { specialFields.push('Destination') } const otherFields = Object.keys(txFields).filter(k => !specialFields.includes(k)) as [ keyof TxFields ] return ( Transaction type:{' '} handleSetAccount(acc)} // TODO make react-select have correct types for acc /> {fields.Destination !== undefined && ( Destination account:{' '}