diff --git a/components/forms/CreateTxForm/Fields/FieldAddress.tsx b/components/forms/CreateTxForm/Fields/FieldAddress.tsx index a6fe54f8..af70d39f 100644 --- a/components/forms/CreateTxForm/Fields/FieldAddress.tsx +++ b/components/forms/CreateTxForm/Fields/FieldAddress.tsx @@ -3,19 +3,43 @@ import { Input } from "@/components/ui/input"; import { useChains } from "@/context/ChainsContext"; import { exampleAddress } from "@/lib/displayHelpers"; import { prettyFieldName } from "@/lib/form"; +import { assert } from "@cosmjs/utils"; import * as z from "zod"; import type { FieldProps, FieldSchemaInput } from "./types"; -export const getFieldAddressSchema = ({ chain }: FieldSchemaInput) => { - if (!chain) { - throw new Error("Could not get field address schema because of missing chain parameter"); +const isFieldAddress = (fieldName: string) => + fieldName.toLowerCase().includes("address") || + ["depositor", "proposer", "voter", "sender", "receiver", "contract", "newAdmin"].includes( + fieldName, + ); + +const isOptionalFieldAddress = (fieldName: string) => fieldName === "admin"; + +export const getFieldAddress = (fieldName: string) => + isFieldAddress(fieldName) || isOptionalFieldAddress(fieldName) ? FieldAddress : null; + +export const getFieldAddressSchema = (fieldName: string, { chain }: FieldSchemaInput) => { + assert(chain, "Could not get field address schema because of missing chain parameter"); + + if (!isFieldAddress(fieldName) && !isOptionalFieldAddress(fieldName)) { + return null; } - return z + const zodString = z .string({ invalid_type_error: "Must be a string", required_error: "Required" }) .trim() .min(1, "Required") .startsWith(chain.addressPrefix, `Invalid prefix for ${chain.chainDisplayName}`); + + if (isFieldAddress(fieldName)) { + return zodString; + } + + if (isOptionalFieldAddress(fieldName)) { + return z.optional(zodString); + } + + return null; }; export default function FieldAddress({ form, fieldFormName }: FieldProps) { diff --git a/components/forms/CreateTxForm/Fields/FieldAmount.tsx b/components/forms/CreateTxForm/Fields/FieldAmount.tsx index f6e12feb..8149f5a4 100644 --- a/components/forms/CreateTxForm/Fields/FieldAmount.tsx +++ b/components/forms/CreateTxForm/Fields/FieldAmount.tsx @@ -4,18 +4,28 @@ import { prettyFieldName } from "@/lib/form"; import * as z from "zod"; import type { FieldProps } from "./types"; -export const getFieldAmountSchema = () => - z.object({ - denom: z - .string({ invalid_type_error: "Must be a string", required_error: "Required" }) - .trim() - .min(1, "Required"), - amount: z - .number({ invalid_type_error: "Must be a number", required_error: "Required" }) - .positive("Must be positive"), - }); +const isFieldAmount = (fieldName: string) => + ["amount", "initialDeposit", "value", "token", "funds"].includes(fieldName); + +export const getFieldAmount = (fieldName: string) => + isFieldAmount(fieldName) ? FieldAmount : null; + +export const getFieldAmountSchema = (fieldName: string) => + isFieldAmount(fieldName) + ? z.object({ + denom: z + .string({ invalid_type_error: "Must be a string", required_error: "Required" }) + .trim() + .min(1, "Required"), + amount: z.coerce + .number({ invalid_type_error: "Must be a number", required_error: "Required" }) + .positive("Must be positive"), + }) + : null; export default function FieldAmount({ form, fieldFormName }: FieldProps) { + const prettyLabel = prettyFieldName(fieldFormName); + return ( <> ( - {"Denom" + prettyFieldName(fieldFormName)} + {`${prettyLabel} denom`} @@ -36,7 +46,9 @@ export default function FieldAmount({ form, fieldFormName }: FieldProps) { name={`${fieldFormName}.amount`} render={({ field }) => ( - {prettyFieldName(fieldFormName)} + + {prettyLabel === "Amount" ? "Amount quantity" : `${prettyLabel} amount`} + diff --git a/components/forms/CreateTxForm/Fields/index.ts b/components/forms/CreateTxForm/Fields/index.ts new file mode 100644 index 00000000..65c8cff4 --- /dev/null +++ b/components/forms/CreateTxForm/Fields/index.ts @@ -0,0 +1,2 @@ +export * from "./FieldAddress"; +export * from "./FieldAmount"; diff --git a/components/forms/CreateTxForm/index.tsx b/components/forms/CreateTxForm/index.tsx index 3a05b03b..4eb8f92b 100644 --- a/components/forms/CreateTxForm/index.tsx +++ b/components/forms/CreateTxForm/index.tsx @@ -68,7 +68,16 @@ export default function CreateTxForm() { {Object.values(msgRegistry) .filter((msg) => msg.category === category) .map((msg) => ( - ))} @@ -83,7 +92,7 @@ export default function CreateTxForm() {

{msg.name}

{msg.fields.map((fieldName: string) => { - const Field = getField(fieldName); + const Field = getField(fieldName) || (() => null); return ( { - const splitName = fieldName.split(/(?=[A-Z])/).join(" "); + const truncatedName = fieldName.slice(fieldName.indexOf(".", "msgs.".length) + 1); + const splitName = truncatedName.split(/(?=[A-Z])/).join(" "); const capitalizedName = splitName.charAt(0).toUpperCase() + splitName.slice(1); return capitalizedName; }; -export const getField = (fieldName: string) => { - switch (fieldName) { - case "fromAddress": - case "toAddress": - case "delegatorAddress": - case "validatorAddress": - return FieldAddress; - case "amount": - return FieldAmount; - default: - return () => null; - } -}; +export const getField = (fieldName: string) => + getFieldAddress(fieldName) || getFieldAmount(fieldName) || null; -const getFieldSchema = (fieldName: string) => { - switch (fieldName) { - case "fromAddress": - case "toAddress": - case "delegatorAddress": - case "validatorAddress": - return getFieldAddressSchema; - case "amount": - return getFieldAmountSchema; - default: - throw new Error(`No schema found for ${fieldName} field`); - } -}; +const getFieldSchema = (fieldName: string, schemaInput: FieldSchemaInput) => + getFieldAddressSchema(fieldName, schemaInput) || getFieldAmountSchema(fieldName) || null; export const getMsgSchema = (fieldNames: readonly string[], schemaInput: FieldSchemaInput) => { const fieldEntries = fieldNames.map((fieldName) => [ fieldName, - getFieldSchema(fieldName)(schemaInput), + getFieldSchema(fieldName, schemaInput), ]); return z.object(Object.fromEntries(fieldEntries));