From 272b053edf00bf7cc752062de1c6bb07845c100c Mon Sep 17 00:00:00 2001 From: abefernan <44572727+abefernan@users.noreply.github.com> Date: Tue, 11 Jun 2024 11:24:16 +0200 Subject: [PATCH] Add new msg vote form --- .../CreateTxForm/MsgForm/MsgVoteForm.tsx | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 components/forms/CreateTxForm/MsgForm/MsgVoteForm.tsx diff --git a/components/forms/CreateTxForm/MsgForm/MsgVoteForm.tsx b/components/forms/CreateTxForm/MsgForm/MsgVoteForm.tsx new file mode 100644 index 0000000..7618e25 --- /dev/null +++ b/components/forms/CreateTxForm/MsgForm/MsgVoteForm.tsx @@ -0,0 +1,137 @@ +import { printVoteOption, voteOptions } from "@/lib/gov"; +import { MsgVoteEncodeObject } from "@cosmjs/stargate"; +import { longify } from "@cosmjs/stargate/build/queryclient"; +import { voteOptionFromJSON } from "cosmjs-types/cosmos/gov/v1beta1/gov"; +import { useEffect, useState } from "react"; +import { MsgGetter } from ".."; +import { trimStringsObj } from "../../../../lib/displayHelpers"; +import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg"; +import Input from "../../../inputs/Input"; +import Select from "../../../inputs/Select"; +import StackableContainer from "../../../layout/StackableContainer"; + +const selectVoteOptions = voteOptions.map((opt) => { + const voteOptionObj = voteOptionFromJSON(opt); + + return { + label: printVoteOption(voteOptionObj), + value: voteOptionObj, + }; +}); + +interface MsgVoteFormProps { + readonly fromAddress: string; + readonly setMsgGetter: (msgGetter: MsgGetter) => void; + readonly deleteMsg: () => void; +} + +const MsgVoteForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgVoteFormProps) => { + const [proposalId, setProposalId] = useState("0"); + const [selectedVote, setSelectedVote] = useState(selectVoteOptions[0]); + + const [proposalIdError, setProposalIdError] = useState(""); + + const trimmedInputs = trimStringsObj({ proposalId }); + + useEffect(() => { + // eslint-disable-next-line no-shadow + const { proposalId } = trimmedInputs; + + const isMsgValid = (): boolean => { + setProposalIdError(""); + + if (!proposalId || Number(proposalId) <= 0 || !Number.isSafeInteger(Number(proposalId))) { + setProposalIdError("Proposal ID must be an integer greater than 0"); + return false; + } + + try { + longify(proposalId); + } catch (e: unknown) { + setProposalIdError(e instanceof Error ? e.message : "Proposal ID is not a valid Big Int"); + return false; + } + + return true; + }; + + const proposalIdBigInt = (() => { + try { + return longify(proposalId); + } catch { + return 0n; + } + })(); + + const msgValue = MsgCodecs[MsgTypeUrls.Vote].fromPartial({ + voter: fromAddress, + proposalId: proposalIdBigInt, + option: selectedVote.value, + }); + + const msg: MsgVoteEncodeObject = { typeUrl: MsgTypeUrls.Vote, value: msgValue }; + + setMsgGetter({ isMsgValid, msg }); + }, [fromAddress, selectedVote.value, setMsgGetter, trimmedInputs]); + + return ( + + +

MsgVote

+
+ { + setProposalId(target.value); + setProposalIdError(""); + }} + error={proposalIdError} + /> +
+
+ +