import { useChains } from "@/context/ChainsContext"; import { setNewConnection } from "@/context/ChainsContext/helpers"; import { RegistryAsset } from "@/types/chainRegistry"; import { zodResolver } from "@hookform/resolvers/zod"; import dynamic from "next/dynamic"; import { useForm } from "react-hook-form"; import * as z from "zod"; import { Button } from "../ui/button"; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "../ui/form"; import { Input } from "../ui/input"; const JsonEditor = dynamic(() => import("../inputs/JsonEditor"), { ssr: false }); export default function CustomChainForm() { const { chain, chains, newConnection, chainsDispatch } = useChains(); const formSchema = z .object({ localRegistryName: z .string({ required_error: "Local registry name is required" }) .refine((val) => !chains.mainnets.has(val) && !chains.testnets.has(val), { message: "Name already exists in remote registry", }), chainName: z.string({ required_error: "Chain name is required" }), chainId: z.string({ required_error: "Chain ID is required" }), baseDenom: z.string({ required_error: "Base denom is required" }), displayDenom: z.string({ required_error: "Display denom is required" }), denomExponent: z.string({ required_error: "Denom exponent is required" }), bech32Prefix: z.string({ required_error: "Address prefix is required" }), gasPrice: z.string({ required_error: "Gas price is required" }), rpcNodes: z.string({ required_error: "Comma separated rpc nodes are required" }), explorerTxLink: z.string({ required_error: "Explorer tx url is required" }), explorerAccountLink: z.string({ required_error: "Explorer account url is required" }), logo: z.string({ required_error: "Logo url is required" }), assets: z.string({ required_error: "Assets json is required" }), }) .required(); const defaultChain = newConnection.chain ?? chain; const form = useForm>({ resolver: zodResolver(formSchema), defaultValues: { localRegistryName: defaultChain.registryName, chainName: defaultChain.chainDisplayName, chainId: defaultChain.chainId, baseDenom: defaultChain.denom, displayDenom: defaultChain.displayDenom, denomExponent: String(defaultChain.displayDenomExponent), bech32Prefix: defaultChain.addressPrefix, gasPrice: defaultChain.gasPrice, rpcNodes: defaultChain.nodeAddresses.join(", "), explorerTxLink: defaultChain.explorerLinks.tx, explorerAccountLink: defaultChain.explorerLinks.account, logo: defaultChain.logo, assets: JSON.stringify(defaultChain.assets), }, }); function onSubmit(chainFromForm: z.infer) { const rpcNodes = chainFromForm.rpcNodes.split(", "); setNewConnection(chainsDispatch, { action: "confirm", chain: { registryName: chainFromForm.localRegistryName, logo: chainFromForm.logo, chainId: chainFromForm.chainId, chainDisplayName: chainFromForm.chainName, nodeAddress: "", nodeAddresses: rpcNodes, denom: chainFromForm.baseDenom, displayDenom: chainFromForm.displayDenom, displayDenomExponent: Number(chainFromForm.denomExponent), assets: JSON.parse(chainFromForm.assets) as RegistryAsset[], gasPrice: chainFromForm.gasPrice, addressPrefix: chainFromForm.bech32Prefix, explorerLinks: { tx: chainFromForm.explorerTxLink, account: chainFromForm.explorerAccountLink, }, }, }); } return (
( Local Registry Name A unique key to store this chain on your local registry )} /> ( Chain Name )} /> ( Chain ID )} /> ( Base Denom )} /> ( Display Denom )} /> ( Denom Exponent )} /> ( Address Prefix Needs to be bech32 )} /> ( Gas Price )} /> ( Explorer Tx Link with {"'${txHash}'"} included )} /> ( Explorer Account Link with {"'${accountAddress}'"} included )} />
( RPC nodes Can be one or more, separated by commas )} /> ( Logo URI )} /> ( Assets
{ field.onChange("text" in newMsgContent ? newMsgContent.text ?? "{}" : "{}"); }} />
)} /> ); }