diff --git a/components/Transaction/index.tsx b/components/Transaction/index.tsx index ae09717..f5b2cb3 100644 --- a/components/Transaction/index.tsx +++ b/components/Transaction/index.tsx @@ -3,6 +3,7 @@ import { FC, useCallback, useEffect } from "react"; import { useSnapshot } from "valtio"; import state from "../../state"; import { + getTxFields, modifyTransaction, prepareState, prepareTransaction, @@ -54,9 +55,7 @@ const Transaction: FC = ({ } = state; const TransactionType = selectedTransaction?.value || null; - const Destination = - selectedDestAccount?.value || - (txFields && "Destination" in txFields ? null : undefined); + const Destination = selectedDestAccount?.value || txFields?.Destination; const Account = selectedAccount?.value || null; return prepareTransaction({ @@ -108,8 +107,9 @@ const Transaction: FC = ({ } const options = prepareOptions(st); - if (options.Destination === null) { - throw Error("Destination account cannot be null"); + const fields = getTxFields(options.TransactionType); + if (fields.Destination && !options.Destination) { + throw Error("Destination account is required!"); } await sendTransaction(account, options, { logPrefix }); diff --git a/components/Transaction/ui.tsx b/components/Transaction/ui.tsx index 0041201..835e987 100644 --- a/components/Transaction/ui.tsx +++ b/components/Transaction/ui.tsx @@ -1,4 +1,4 @@ -import { FC, useCallback, useEffect, useState } from "react"; +import { FC, useCallback, useEffect, useMemo, useState } from "react"; import Container from "../Container"; import Flex from "../Flex"; import Input from "../Input"; @@ -60,7 +60,13 @@ export const TxUI: FC = ({ const resetOptions = useCallback( (tt: string) => { const fields = getTxFields(tt); - if (!fields.Destination) setState({ selectedDestAccount: null }); + + if (fields.Destination !== undefined) { + setState({ selectedDestAccount: null }); + fields.Destination = ""; + } else { + fields.Destination = undefined; + } return setState({ txFields: fields }); }, [setState] @@ -108,12 +114,6 @@ export const TxUI: FC = ({ [handleEstimateFee, resetOptions, setState] ); - const specialFields = ["TransactionType", "Account", "Destination"]; - - const otherFields = Object.keys(txFields).filter( - k => !specialFields.includes(k) - ) as [keyof TxFields]; - const switchToJson = () => setState({ viewType: "json" }); // default tx @@ -128,6 +128,20 @@ export const TxUI: FC = ({ } }, [handleChangeTxType, selectedTransaction?.value, transactionsOptions]); + 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 ( = ({ onChange={(acc: any) => handleSetAccount(acc)} // TODO make react-select have correct types for acc /> - {txFields.Destination !== undefined && ( + {fields.Destination !== undefined && ( { - // Typescript mess here, but is definetly safe! + // Typescript mess here, but is definitely safe! const s = tx.state as any; const p = partialTx as any; // ? Make copy if (!deepEqual(s[k], p[k])) s[k] = p[k]; @@ -130,11 +130,11 @@ export const prepareTransaction = (data: any) => { } // delete unnecessary fields - if (options[field] === undefined) { + if (!options[field]) { delete options[field]; } }); - + return options } @@ -150,7 +150,7 @@ export const prepareState = (value: string, transactionType?: string) => { const { Account, TransactionType, Destination, ...rest } = options; let tx: Partial = {}; - const txFields = getTxFields(transactionType) + const schema = getTxFields(transactionType) if (Account) { const acc = state.accounts.find(acc => acc.address === Account); @@ -178,9 +178,8 @@ export const prepareState = (value: string, transactionType?: string) => { tx.selectedTransaction = null; } - if (txFields.Destination !== undefined) { + if (schema.Destination !== undefined) { const dest = state.accounts.find(acc => acc.address === Destination); - rest.Destination = null if (dest) { tx.selectedDestAccount = { label: dest.name, @@ -197,11 +196,14 @@ export const prepareState = (value: string, transactionType?: string) => { tx.selectedDestAccount = null } } + else if (Destination) { + rest.Destination = Destination + } Object.keys(rest).forEach(field => { const value = rest[field]; - const origValue = txFields[field as keyof TxFields] - const isXrp = typeof value !== 'object' && origValue && typeof origValue === 'object' && origValue.$type === 'xrp' + const schemaVal = schema[field as keyof TxFields] + const isXrp = typeof value !== 'object' && schemaVal && typeof schemaVal === 'object' && schemaVal.$type === 'xrp' if (isXrp) { rest[field] = { $type: "xrp",