diff --git a/components/dataViews/TransactionInfo/TxMsgSetWithdrawAddressDetails.tsx b/components/dataViews/TransactionInfo/TxMsgSetWithdrawAddressDetails.tsx new file mode 100644 index 0000000..56d646e --- /dev/null +++ b/components/dataViews/TransactionInfo/TxMsgSetWithdrawAddressDetails.tsx @@ -0,0 +1,47 @@ +import { TxMsgSetWithdrawAddress } from "../../../types/txMsg"; +import HashView from "../HashView"; + +interface TxMsgSetWithdrawAddressDetailsProps { + readonly msg: TxMsgSetWithdrawAddress; +} + +const TxMsgSetWithdrawAddressDetails = ({ msg }: TxMsgSetWithdrawAddressDetailsProps) => ( + <> +
  • +

    MsgSetWithdrawAddress

    +
  • +
  • + +
    + +
    +
  • + + +); + +export default TxMsgSetWithdrawAddressDetails; diff --git a/components/dataViews/TransactionInfo/index.tsx b/components/dataViews/TransactionInfo/index.tsx index 593550b..722746d 100644 --- a/components/dataViews/TransactionInfo/index.tsx +++ b/components/dataViews/TransactionInfo/index.tsx @@ -5,6 +5,7 @@ import { isTxMsgDelegate, isTxMsgRedelegate, isTxMsgSend, + isTxMsgSetWithdrawAddress, isTxMsgUndelegate, } from "../../../lib/txMsgHelpers"; import { DbTransaction } from "../../../types"; @@ -13,6 +14,7 @@ import TxMsgClaimRewardsDetails from "./TxMsgClaimRewardsDetails"; import TxMsgDelegateDetails from "./TxMsgDelegateDetails"; import TxMsgRedelegateDetails from "./TxMsgRedelegateDetails"; import TxMsgSendDetails from "./TxMsgSendDetails"; +import TxMsgSetWithdrawAddressDetails from "./TxMsgSetWithdrawAddressDetails"; import TxMsgUndelegateDetails from "./TxMsgUndelegateDetails"; interface Props { @@ -33,6 +35,7 @@ const TransactionInfo = ({ tx }: Props) => { {isTxMsgUndelegate(msg) ? : null} {isTxMsgRedelegate(msg) ? : null} {isTxMsgClaimRewards(msg) ? : null} + {isTxMsgSetWithdrawAddress(msg) ? : null} ))} diff --git a/components/forms/CreateTxForm/MsgForm/MsgSetWithdrawAddressForm.tsx b/components/forms/CreateTxForm/MsgForm/MsgSetWithdrawAddressForm.tsx new file mode 100644 index 0000000..530ee56 --- /dev/null +++ b/components/forms/CreateTxForm/MsgForm/MsgSetWithdrawAddressForm.tsx @@ -0,0 +1,97 @@ +import { assert } from "@cosmjs/utils"; +import { useEffect, useState } from "react"; +import { MsgGetter } from ".."; +import { useAppContext } from "../../../../context/AppContext"; +import { checkAddress, exampleAddress } from "../../../../lib/displayHelpers"; +import { isTxMsgSetWithdrawAddress } from "../../../../lib/txMsgHelpers"; +import { TxMsg, TxMsgSetWithdrawAddress } from "../../../../types/txMsg"; +import Input from "../../../inputs/Input"; +import StackableContainer from "../../../layout/StackableContainer"; + +interface MsgSetWithdrawAddressFormProps { + readonly delegatorAddress: string; + readonly setMsgGetter: (msgGetter: MsgGetter) => void; + readonly deleteMsg: () => void; +} + +const MsgSetWithdrawAddressForm = ({ + delegatorAddress, + setMsgGetter, + deleteMsg, +}: MsgSetWithdrawAddressFormProps) => { + const { state } = useAppContext(); + assert(state.chain.addressPrefix, "addressPrefix missing"); + + const [withdrawAddress, setWithdrawAddress] = useState(""); + const [withdrawAddressError, setWithdrawAddressError] = useState(""); + + useEffect(() => { + try { + setWithdrawAddressError(""); + + const isMsgValid = (msg: TxMsg): msg is TxMsgSetWithdrawAddress => { + assert(state.chain.addressPrefix, "addressPrefix missing"); + + const addressErrorMsg = checkAddress(withdrawAddress, state.chain.addressPrefix); + if (addressErrorMsg) { + setWithdrawAddressError( + `Invalid address for network ${state.chain.chainId}: ${addressErrorMsg}`, + ); + return false; + } + + return isTxMsgSetWithdrawAddress(msg); + }; + + const msg: TxMsgSetWithdrawAddress = { + typeUrl: "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress", + value: { delegatorAddress, withdrawAddress }, + }; + + setMsgGetter({ isMsgValid, msg }); + } catch {} + }, [ + delegatorAddress, + setMsgGetter, + state.chain.addressPrefix, + state.chain.chainId, + withdrawAddress, + ]); + + return ( + + +

    MsgSetWithdrawAddress

    +
    + setWithdrawAddress(target.value)} + error={withdrawAddressError} + placeholder={`E.g. ${exampleAddress(0, state.chain.addressPrefix)}`} + /> +
    + +
    + ); +}; + +export default MsgSetWithdrawAddressForm; diff --git a/components/forms/CreateTxForm/MsgForm/index.tsx b/components/forms/CreateTxForm/MsgForm/index.tsx index fea65d0..a0f6165 100644 --- a/components/forms/CreateTxForm/MsgForm/index.tsx +++ b/components/forms/CreateTxForm/MsgForm/index.tsx @@ -4,6 +4,7 @@ import MsgClaimRewardsForm from "./MsgClaimRewardsForm"; import MsgDelegateForm from "./MsgDelegateForm"; import MsgRedelegateForm from "./MsgRedelegateForm"; import MsgSendForm from "./MsgSendForm"; +import MsgSetWithdrawAddressForm from "./MsgSetWithdrawAddressForm"; import MsgUndelegateForm from "./MsgUndelegateForm"; type MsgFormProps = { @@ -26,6 +27,8 @@ const MsgForm = ({ txType, senderAddress, ...restProps }: MsgFormProps) => { return ; case "claimRewards": return ; + case "setWithdrawAddress": + return ; default: return null; } diff --git a/components/forms/CreateTxForm/index.tsx b/components/forms/CreateTxForm/index.tsx index 67ff3d8..4fce992 100644 --- a/components/forms/CreateTxForm/index.tsx +++ b/components/forms/CreateTxForm/index.tsx @@ -145,6 +145,7 @@ const CreateTxForm = ({ router, senderAddress, accountOnChain }: CreateTxFormPro