diff --git a/components/dataViews/TransactionInfo/TxMsgUpdateAdminDetails.tsx b/components/dataViews/TransactionInfo/TxMsgUpdateAdminDetails.tsx new file mode 100644 index 0000000..9a7c1d8 --- /dev/null +++ b/components/dataViews/TransactionInfo/TxMsgUpdateAdminDetails.tsx @@ -0,0 +1,61 @@ +import { MsgUpdateAdmin } from "cosmjs-types/cosmwasm/wasm/v1/tx"; +import HashView from "../HashView"; + +interface TxMsgUpdateAdminDetailsProps { + readonly msgValue: MsgUpdateAdmin; +} + +const TxMsgUpdateAdminDetails = ({ msgValue }: TxMsgUpdateAdminDetailsProps) => { + return ( + <> +
  • +

    MsgUpdateAdmin

    +
  • +
  • + +
    + +
    +
  • +
  • + +
    + +
    +
  • + + + ); +}; + +export default TxMsgUpdateAdminDetails; diff --git a/components/dataViews/TransactionInfo/index.tsx b/components/dataViews/TransactionInfo/index.tsx index e0a959b..d0737fa 100644 --- a/components/dataViews/TransactionInfo/index.tsx +++ b/components/dataViews/TransactionInfo/index.tsx @@ -16,6 +16,7 @@ import TxMsgSendDetails from "./TxMsgSendDetails"; import TxMsgSetWithdrawAddressDetails from "./TxMsgSetWithdrawAddressDetails"; import TxMsgTransferDetails from "./TxMsgTransferDetails"; import TxMsgUndelegateDetails from "./TxMsgUndelegateDetails"; +import TxMsgUpdateAdminDetails from "./TxMsgUpdateAdminDetails"; const TxMsgDetails = ({ typeUrl, value: msgValue }: EncodeObject) => { switch (typeUrl) { @@ -43,6 +44,8 @@ const TxMsgDetails = ({ typeUrl, value: msgValue }: EncodeObject) => { return ; case MsgTypeUrls.Migrate: return ; + case MsgTypeUrls.UpdateAdmin: + return ; default: return null; } diff --git a/components/forms/CreateTxForm/MsgForm/MsgUpdateAdminForm.tsx b/components/forms/CreateTxForm/MsgForm/MsgUpdateAdminForm.tsx new file mode 100644 index 0000000..ced812b --- /dev/null +++ b/components/forms/CreateTxForm/MsgForm/MsgUpdateAdminForm.tsx @@ -0,0 +1,129 @@ +import { MsgUpdateAdminEncodeObject } from "@cosmjs/cosmwasm-stargate"; +import { useEffect, useState } from "react"; +import { MsgGetter } from ".."; +import { useChains } from "../../../../context/ChainsContext"; +import { checkAddress, exampleAddress, trimStringsObj } from "../../../../lib/displayHelpers"; +import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg"; +import Input from "../../../inputs/Input"; +import StackableContainer from "../../../layout/StackableContainer"; + +interface MsgUpdateAdminFormProps { + readonly fromAddress: string; + readonly setMsgGetter: (msgGetter: MsgGetter) => void; + readonly deleteMsg: () => void; +} + +const MsgUpdateAdminForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgUpdateAdminFormProps) => { + const { chain } = useChains(); + + const [contractAddress, setContractAddress] = useState(""); + const [newAdminAddress, setNewAdminAddress] = useState(""); + + const [contractAddressError, setContractAddressError] = useState(""); + const [newAdminAddressError, setNewAdminAddressError] = useState(""); + + const trimmedInputs = trimStringsObj({ contractAddress, newAdminAddress }); + + useEffect(() => { + // eslint-disable-next-line no-shadow + const { contractAddress, newAdminAddress } = trimmedInputs; + + const isMsgValid = (): boolean => { + setContractAddressError(""); + setNewAdminAddressError(""); + + const contractAddressErrorMsg = checkAddress(contractAddress, chain.addressPrefix); + if (contractAddressErrorMsg) { + setContractAddressError( + `Invalid address for network ${chain.chainId}: ${contractAddressErrorMsg}`, + ); + return false; + } + + const newAdminAddressErrorMsg = checkAddress(newAdminAddress, chain.addressPrefix); + if (newAdminAddressErrorMsg) { + setNewAdminAddressError( + `Invalid address for network ${chain.chainId}: ${newAdminAddressErrorMsg}`, + ); + return false; + } + + return true; + }; + + const msgValue = MsgCodecs[MsgTypeUrls.UpdateAdmin].fromPartial({ + sender: fromAddress, + contract: contractAddress, + newAdmin: newAdminAddress, + }); + + const msg: MsgUpdateAdminEncodeObject = { typeUrl: MsgTypeUrls.UpdateAdmin, value: msgValue }; + + setMsgGetter({ isMsgValid, msg }); + }, [chain.addressPrefix, chain.chainId, fromAddress, setMsgGetter, trimmedInputs]); + + return ( + + +

    MsgUpdateAdmin

    +
    + { + setContractAddress(target.value); + setContractAddressError(""); + }} + error={contractAddressError} + placeholder={`E.g. ${exampleAddress(0, chain.addressPrefix)}`} + /> +
    +
    + { + setNewAdminAddress(target.value); + setNewAdminAddressError(""); + }} + error={newAdminAddressError} + placeholder={`E.g. ${exampleAddress(0, chain.addressPrefix)}`} + /> +
    + +
    + ); +}; + +export default MsgUpdateAdminForm; diff --git a/components/forms/CreateTxForm/MsgForm/index.tsx b/components/forms/CreateTxForm/MsgForm/index.tsx index 21f048f..82c840a 100644 --- a/components/forms/CreateTxForm/MsgForm/index.tsx +++ b/components/forms/CreateTxForm/MsgForm/index.tsx @@ -12,6 +12,7 @@ import MsgSendForm from "./MsgSendForm"; import MsgSetWithdrawAddressForm from "./MsgSetWithdrawAddressForm"; import MsgTransferForm from "./MsgTransferForm"; import MsgUndelegateForm from "./MsgUndelegateForm"; +import MsgUpdateAdminForm from "./MsgUpdateAdminForm"; interface MsgFormProps { readonly msgType: MsgTypeUrl; @@ -46,6 +47,8 @@ const MsgForm = ({ msgType, senderAddress, ...restProps }: MsgFormProps) => { return ; case MsgTypeUrls.Migrate: return ; + case MsgTypeUrls.UpdateAdmin: + return ; default: return null; } diff --git a/components/forms/CreateTxForm/index.tsx b/components/forms/CreateTxForm/index.tsx index f5aca87..10e50a4 100644 --- a/components/forms/CreateTxForm/index.tsx +++ b/components/forms/CreateTxForm/index.tsx @@ -254,6 +254,12 @@ const CreateTxForm = ({ router, senderAddress, accountOnChain }: CreateTxFormPro
  • +
  • +
  • diff --git a/lib/txMsgHelpers.ts b/lib/txMsgHelpers.ts index 5f365b3..3fa8f2c 100644 --- a/lib/txMsgHelpers.ts +++ b/lib/txMsgHelpers.ts @@ -30,6 +30,8 @@ const gasOfMsg = (msgType: MsgTypeUrl): number => { return 150_000; case MsgTypeUrls.Migrate: return 150_000; + case MsgTypeUrls.UpdateAdmin: + return 150_000; default: throw new Error("Unknown msg type"); } diff --git a/types/txMsg.ts b/types/txMsg.ts index 6a1ccb2..00a4f0c 100644 --- a/types/txMsg.ts +++ b/types/txMsg.ts @@ -14,6 +14,7 @@ import { MsgInstantiateContract, MsgInstantiateContract2, MsgMigrateContract, + MsgUpdateAdmin, } from "cosmjs-types/cosmwasm/wasm/v1/tx"; import { MsgTransfer } from "cosmjs-types/ibc/applications/transfer/v1/tx"; @@ -30,6 +31,7 @@ export const MsgTypeUrls = { Instantiate: "/cosmwasm.wasm.v1.MsgInstantiateContract", Instantiate2: "/cosmwasm.wasm.v1.MsgInstantiateContract2", Migrate: "/cosmwasm.wasm.v1.MsgMigrateContract", + UpdateAdmin: "/cosmwasm.wasm.v1.MsgUpdateAdmin", } as const; export type MsgTypeUrl = (typeof MsgTypeUrls)[keyof typeof MsgTypeUrls]; @@ -47,4 +49,5 @@ export const MsgCodecs = { [MsgTypeUrls.Instantiate]: MsgInstantiateContract, [MsgTypeUrls.Instantiate2]: MsgInstantiateContract2, [MsgTypeUrls.Migrate]: MsgMigrateContract, + [MsgTypeUrls.UpdateAdmin]: MsgUpdateAdmin, };