diff --git a/components/forms/CreateTxForm/Fields/types.ts b/components/forms/CreateTxForm/Fields/types.ts
new file mode 100644
index 00000000..4ed707c3
--- /dev/null
+++ b/components/forms/CreateTxForm/Fields/types.ts
@@ -0,0 +1,12 @@
+import { ChainInfo } from "@/context/ChainsContext/types";
+import { UseFormReturn } from "react-hook-form";
+
+export interface FieldProps {
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  readonly form: UseFormReturn<any>;
+  readonly fieldFormName: string;
+}
+
+export type FieldSchemaInput = {
+  readonly chain?: ChainInfo;
+};
diff --git a/lib/form.ts b/lib/form.ts
new file mode 100644
index 00000000..d48757cf
--- /dev/null
+++ b/lib/form.ts
@@ -0,0 +1,28 @@
+import { FieldSchemaInput } from "@/components/forms/CreateTxForm/Fields/types";
+import { z } from "zod";
+
+export const prettyFieldName = (fieldName: string) => {
+  const splitName = fieldName.split(/(?=[A-Z])/).join(" ");
+  const capitalizedName = splitName.charAt(0).toUpperCase() + splitName.slice(1);
+
+  return capitalizedName;
+};
+
+export const getField = (_fieldName: string) => {
+  /* Will return a FormField component per fieldName */
+  return () => null;
+};
+
+const getFieldSchema = (_fieldName: string) => {
+  /* Will return a zod schema getter per fieldName */
+  return (_schemaInput: unknown) => null;
+};
+
+export const getMsgSchema = (fieldNames: readonly string[], schemaInput: FieldSchemaInput) => {
+  const fieldEntries = fieldNames.map((fieldName) => [
+    fieldName,
+    getFieldSchema(fieldName)(schemaInput),
+  ]);
+
+  return z.object(Object.fromEntries(fieldEntries));
+};