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
+ msg.typeUrl === "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress" &&
+ "value" in msg &&
+ "delegatorAddress" in msg.value &&
+ "withdrawAddress" in msg.value &&
+ !!msg.value.delegatorAddress &&
+ !!msg.value.withdrawAddress;
+
+export {
+ isTxMsgSend,
+ isTxMsgDelegate,
+ isTxMsgUndelegate,
+ isTxMsgRedelegate,
+ isTxMsgClaimRewards,
+ isTxMsgSetWithdrawAddress,
+};
diff --git a/types/txMsg.ts b/types/txMsg.ts
index a3b2a14..e692650 100644
--- a/types/txMsg.ts
+++ b/types/txMsg.ts
@@ -1,11 +1,18 @@
-export type TxType = "send" | "delegate" | "undelegate" | "redelegate" | "claimRewards";
+export type TxType =
+ | "send"
+ | "delegate"
+ | "undelegate"
+ | "redelegate"
+ | "claimRewards"
+ | "setWithdrawAddress";
export type TxMsg =
| TxMsgSend
| TxMsgDelegate
| TxMsgUndelegate
| TxMsgRedelegate
- | TxMsgClaimRewards;
+ | TxMsgClaimRewards
+ | TxMsgSetWithdrawAddress;
export interface TxMsgSend {
readonly typeUrl: "/cosmos.bank.v1beta1.MsgSend";
@@ -51,3 +58,11 @@ export interface TxMsgClaimRewards {
readonly validatorAddress: string;
};
}
+
+export interface TxMsgSetWithdrawAddress {
+ readonly typeUrl: "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress";
+ readonly value: {
+ readonly delegatorAddress: string;
+ readonly withdrawAddress: string;
+ };
+}