Merge pull request #216 from cosmos/feat/msg-fund-cpool

Add fund cpool and tweaks
This commit is contained in:
Abel Fernández
2024-06-11 14:00:52 +02:00
committed by GitHub
23 changed files with 465 additions and 149 deletions
@@ -4,11 +4,11 @@ import { useChains } from "../../../context/ChainsContext";
import { printableCoin } from "../../../lib/displayHelpers";
import HashView from "../HashView";
interface TxMsgRedelegateDetailsProps {
interface TxMsgBeginRedelegateDetailsProps {
readonly msgValue: MsgBeginRedelegate;
}
const TxMsgRedelegateDetails = ({ msgValue }: TxMsgRedelegateDetailsProps) => {
const TxMsgBeginRedelegateDetails = ({ msgValue }: TxMsgBeginRedelegateDetailsProps) => {
const { chain } = useChains();
assert(
msgValue.amount,
@@ -65,4 +65,4 @@ const TxMsgRedelegateDetails = ({ msgValue }: TxMsgRedelegateDetailsProps) => {
);
};
export default TxMsgRedelegateDetails;
export default TxMsgBeginRedelegateDetails;
@@ -0,0 +1,50 @@
import { MsgFundCommunityPool } from "cosmjs-types/cosmos/distribution/v1beta1/tx";
import { useChains } from "../../../context/ChainsContext";
import { printableCoins } from "../../../lib/displayHelpers";
interface TxMsgFundCommunityPoolDetailsProps {
readonly msgValue: MsgFundCommunityPool;
}
const TxMsgFundCommunityPoolDetails = ({ msgValue }: TxMsgFundCommunityPoolDetailsProps) => {
const { chain } = useChains();
return (
<>
<li>
<h3>MsgFundCommunityPool</h3>
</li>
<li>
<label>Amount:</label>
<div>{printableCoins(msgValue.amount, chain) || "None"}</div>
</li>
<style jsx>{`
li:not(:has(h3)) {
background: rgba(255, 255, 255, 0.03);
padding: 6px 10px;
border-radius: 8px;
display: flex;
align-items: center;
}
li + li:nth-child(2) {
margin-top: 25px;
}
li + li {
margin-top: 10px;
}
li div {
padding: 3px 6px;
}
label {
font-size: 12px;
background: rgba(255, 255, 255, 0.1);
padding: 3px 6px;
border-radius: 5px;
display: block;
}
`}</style>
</>
);
};
export default TxMsgFundCommunityPoolDetails;
@@ -1,11 +1,13 @@
import { MsgWithdrawDelegatorReward } from "cosmjs-types/cosmos/distribution/v1beta1/tx";
import HashView from "../HashView";
interface TxMsgClaimRewardsDetailsProps {
interface TxMsgWithdrawDelegatorRewardDetailsProps {
readonly msgValue: MsgWithdrawDelegatorReward;
}
const TxMsgClaimRewardsDetails = ({ msgValue }: TxMsgClaimRewardsDetailsProps) => (
const TxMsgWithdrawDelegatorRewardDetails = ({
msgValue,
}: TxMsgWithdrawDelegatorRewardDetailsProps) => (
<>
<li>
<h3>MsgWithdrawDelegatorReward</h3>
@@ -44,4 +46,4 @@ const TxMsgClaimRewardsDetails = ({ msgValue }: TxMsgClaimRewardsDetailsProps) =
</>
);
export default TxMsgClaimRewardsDetails;
export default TxMsgWithdrawDelegatorRewardDetails;
+21 -11
View File
@@ -4,51 +4,61 @@ import { printableCoins } from "../../../lib/displayHelpers";
import { DbTransaction } from "../../../types";
import { MsgTypeUrls } from "../../../types/txMsg";
import StackableContainer from "../../layout/StackableContainer";
import TxMsgClaimRewardsDetails from "./TxMsgClaimRewardsDetails";
import TxMsgBeginRedelegateDetails from "./TxMsgBeginRedelegateDetails";
import TxMsgCreateVestingAccountDetails from "./TxMsgCreateVestingAccountDetails";
import TxMsgDelegateDetails from "./TxMsgDelegateDetails";
import TxMsgExecuteContractDetails from "./TxMsgExecuteContractDetails";
import TxMsgFundCommunityPoolDetails from "./TxMsgFundCommunityPoolDetails";
import TxMsgInstantiateContract2Details from "./TxMsgInstantiateContract2Details";
import TxMsgInstantiateContractDetails from "./TxMsgInstantiateContractDetails";
import TxMsgMigrateContractDetails from "./TxMsgMigrateContractDetails";
import TxMsgRedelegateDetails from "./TxMsgRedelegateDetails";
import TxMsgSendDetails from "./TxMsgSendDetails";
import TxMsgSetWithdrawAddressDetails from "./TxMsgSetWithdrawAddressDetails";
import TxMsgTransferDetails from "./TxMsgTransferDetails";
import TxMsgUndelegateDetails from "./TxMsgUndelegateDetails";
import TxMsgUpdateAdminDetails from "./TxMsgUpdateAdminDetails";
import TxMsgVoteDetails from "./TxMsgVoteDetails";
import TxMsgWithdrawDelegatorRewardDetails from "./TxMsgWithdrawDelegatorRewardDetails";
const TxMsgDetails = ({ typeUrl, value: msgValue }: EncodeObject) => {
switch (typeUrl) {
// Bank
case MsgTypeUrls.Send:
return <TxMsgSendDetails msgValue={msgValue} />;
// Staking
case MsgTypeUrls.Delegate:
return <TxMsgDelegateDetails msgValue={msgValue} />;
case MsgTypeUrls.Undelegate:
return <TxMsgUndelegateDetails msgValue={msgValue} />;
case MsgTypeUrls.BeginRedelegate:
return <TxMsgRedelegateDetails msgValue={msgValue} />;
case MsgTypeUrls.WithdrawDelegatorReward:
return <TxMsgClaimRewardsDetails msgValue={msgValue} />;
return <TxMsgBeginRedelegateDetails msgValue={msgValue} />;
// Distribution
case MsgTypeUrls.FundCommunityPool:
return <TxMsgFundCommunityPoolDetails msgValue={msgValue} />;
case MsgTypeUrls.SetWithdrawAddress:
return <TxMsgSetWithdrawAddressDetails msgValue={msgValue} />;
case MsgTypeUrls.WithdrawDelegatorReward:
return <TxMsgWithdrawDelegatorRewardDetails msgValue={msgValue} />;
// Vesting
case MsgTypeUrls.CreateVestingAccount:
return <TxMsgCreateVestingAccountDetails msgValue={msgValue} />;
// Governance
case MsgTypeUrls.Vote:
return <TxMsgVoteDetails msgValue={msgValue} />;
// IBC
case MsgTypeUrls.Transfer:
return <TxMsgTransferDetails msgValue={msgValue} />;
case MsgTypeUrls.Execute:
return <TxMsgExecuteContractDetails msgValue={msgValue} />;
case MsgTypeUrls.Instantiate:
// CosmWasm
case MsgTypeUrls.InstantiateContract:
return <TxMsgInstantiateContractDetails msgValue={msgValue} />;
case MsgTypeUrls.Instantiate2:
case MsgTypeUrls.InstantiateContract2:
return <TxMsgInstantiateContract2Details msgValue={msgValue} />;
case MsgTypeUrls.Migrate:
return <TxMsgMigrateContractDetails msgValue={msgValue} />;
case MsgTypeUrls.UpdateAdmin:
return <TxMsgUpdateAdminDetails msgValue={msgValue} />;
case MsgTypeUrls.ExecuteContract:
return <TxMsgExecuteContractDetails msgValue={msgValue} />;
case MsgTypeUrls.MigrateContract:
return <TxMsgMigrateContractDetails msgValue={msgValue} />;
default:
return null;
}
@@ -1,5 +1,5 @@
import SelectValidator from "@/components/SelectValidator";
import { EncodeObject } from "@cosmjs/proto-signing";
import { MsgBeginRedelegateEncodeObject } from "@cosmjs/stargate";
import { useEffect, useState } from "react";
import { MsgGetter } from "..";
import { useChains } from "../../../../context/ChainsContext";
@@ -9,17 +9,17 @@ import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
import Input from "../../../inputs/Input";
import StackableContainer from "../../../layout/StackableContainer";
interface MsgRedelegateFormProps {
readonly delegatorAddress: string;
interface MsgBeginRedelegateFormProps {
readonly senderAddress: string;
readonly setMsgGetter: (msgGetter: MsgGetter) => void;
readonly deleteMsg: () => void;
}
const MsgRedelegateForm = ({
delegatorAddress,
const MsgBeginRedelegateForm = ({
senderAddress,
setMsgGetter,
deleteMsg,
}: MsgRedelegateFormProps) => {
}: MsgBeginRedelegateFormProps) => {
const { chain } = useChains();
const [validatorSrcAddress, setValidatorSrcAddress] = useState("");
@@ -81,13 +81,16 @@ const MsgRedelegateForm = ({
})();
const msgValue = MsgCodecs[MsgTypeUrls.BeginRedelegate].fromPartial({
delegatorAddress,
delegatorAddress: senderAddress,
validatorSrcAddress,
validatorDstAddress,
amount: microCoin,
});
const msg: EncodeObject = { typeUrl: MsgTypeUrls.BeginRedelegate, value: msgValue };
const msg: MsgBeginRedelegateEncodeObject = {
typeUrl: MsgTypeUrls.BeginRedelegate,
value: msgValue,
};
setMsgGetter({ isMsgValid, msg });
}, [
@@ -95,7 +98,7 @@ const MsgRedelegateForm = ({
chain.assets,
chain.chainId,
chain.displayDenom,
delegatorAddress,
senderAddress,
setMsgGetter,
trimmedInputs,
]);
@@ -173,4 +176,4 @@ const MsgRedelegateForm = ({
);
};
export default MsgRedelegateForm;
export default MsgBeginRedelegateForm;
@@ -13,13 +13,13 @@ import Input from "../../../inputs/Input";
import StackableContainer from "../../../layout/StackableContainer";
interface MsgCreateVestingAccountFormProps {
readonly fromAddress: string;
readonly senderAddress: string;
readonly setMsgGetter: (msgGetter: MsgGetter) => void;
readonly deleteMsg: () => void;
}
const MsgCreateVestingAccountForm = ({
fromAddress,
senderAddress,
setMsgGetter,
deleteMsg,
}: MsgCreateVestingAccountFormProps) => {
@@ -87,7 +87,7 @@ const MsgCreateVestingAccountForm = ({
})();
const msgValue = MsgCodecs[MsgTypeUrls.CreateVestingAccount].fromPartial({
fromAddress,
fromAddress: senderAddress,
toAddress,
amount: microCoin ? [microCoin] : [],
endTime: timestampFromDatetimeLocal(endTime, "s"),
@@ -103,7 +103,7 @@ const MsgCreateVestingAccountForm = ({
chain.chainId,
chain.displayDenom,
delayed,
fromAddress,
senderAddress,
setMsgGetter,
trimmedInputs,
]);
@@ -10,12 +10,12 @@ import Input from "../../../inputs/Input";
import StackableContainer from "../../../layout/StackableContainer";
interface MsgDelegateFormProps {
readonly delegatorAddress: string;
readonly senderAddress: string;
readonly setMsgGetter: (msgGetter: MsgGetter) => void;
readonly deleteMsg: () => void;
}
const MsgDelegateForm = ({ delegatorAddress, setMsgGetter, deleteMsg }: MsgDelegateFormProps) => {
const MsgDelegateForm = ({ senderAddress, setMsgGetter, deleteMsg }: MsgDelegateFormProps) => {
const { chain } = useChains();
const [validatorAddress, setValidatorAddress] = useState("");
@@ -66,7 +66,7 @@ const MsgDelegateForm = ({ delegatorAddress, setMsgGetter, deleteMsg }: MsgDeleg
})();
const msgValue = MsgCodecs[MsgTypeUrls.Delegate].fromPartial({
delegatorAddress,
delegatorAddress: senderAddress,
validatorAddress,
amount: microCoin,
});
@@ -79,7 +79,7 @@ const MsgDelegateForm = ({ delegatorAddress, setMsgGetter, deleteMsg }: MsgDeleg
chain.assets,
chain.chainId,
chain.displayDenom,
delegatorAddress,
senderAddress,
setMsgGetter,
trimmedInputs,
]);
@@ -25,13 +25,13 @@ const getDenomOptions = (assets: ChainInfo["assets"]) => {
};
interface MsgExecuteContractFormProps {
readonly fromAddress: string;
readonly senderAddress: string;
readonly setMsgGetter: (msgGetter: MsgGetter) => void;
readonly deleteMsg: () => void;
}
const MsgExecuteContractForm = ({
fromAddress,
senderAddress,
setMsgGetter,
deleteMsg,
}: MsgExecuteContractFormProps) => {
@@ -126,23 +126,26 @@ const MsgExecuteContractForm = ({
}
})();
const msgValue = MsgCodecs[MsgTypeUrls.Execute].fromPartial({
sender: fromAddress,
const msgValue = MsgCodecs[MsgTypeUrls.ExecuteContract].fromPartial({
sender: senderAddress,
contract: contractAddress,
msg: msgContentUtf8Array,
funds: microCoin ? [microCoin] : [],
});
const msg: MsgExecuteContractEncodeObject = { typeUrl: MsgTypeUrls.Execute, value: msgValue };
const msg: MsgExecuteContractEncodeObject = {
typeUrl: MsgTypeUrls.ExecuteContract,
value: msgValue,
};
setMsgGetter({ isMsgValid, msg });
}, [
chain.addressPrefix,
chain.assets,
chain.chainId,
fromAddress,
msgContent,
selectedDenom.value,
senderAddress,
setMsgGetter,
trimmedInputs,
]);
@@ -0,0 +1,194 @@
import { EncodeObject } from "@cosmjs/proto-signing";
import { useEffect, useState } from "react";
import { MsgGetter } from "..";
import { useChains } from "../../../../context/ChainsContext";
import { displayCoinToBaseCoin } from "../../../../lib/coinHelpers";
import { trimStringsObj } from "../../../../lib/displayHelpers";
import { RegistryAsset } from "../../../../types/chainRegistry";
import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
import Input from "../../../inputs/Input";
import Select from "../../../inputs/Select";
import StackableContainer from "../../../layout/StackableContainer";
const customDenomOption = { label: "Custom (enter denom below)", value: "custom" } as const;
const getDenomOptions = (assets: readonly RegistryAsset[]) => {
if (!assets?.length) {
return [customDenomOption];
}
return [...assets.map((asset) => ({ label: asset.symbol, value: asset })), customDenomOption];
};
interface MsgFundCommunityPoolFormProps {
readonly senderAddress: string;
readonly setMsgGetter: (msgGetter: MsgGetter) => void;
readonly deleteMsg: () => void;
}
const MsgFundCommunityPoolForm = ({
senderAddress,
setMsgGetter,
deleteMsg,
}: MsgFundCommunityPoolFormProps) => {
const { chain } = useChains();
const denomOptions = getDenomOptions(chain.assets);
const [selectedDenom, setSelectedDenom] = useState(denomOptions[0]);
const [customDenom, setCustomDenom] = useState("");
const [amount, setAmount] = useState("0");
const [customDenomError, setCustomDenomError] = useState("");
const [amountError, setAmountError] = useState("");
const trimmedInputs = trimStringsObj({ customDenom, amount });
useEffect(() => {
// eslint-disable-next-line no-shadow
const { customDenom, amount } = trimmedInputs;
const isMsgValid = (): boolean => {
setCustomDenomError("");
setAmountError("");
if (
selectedDenom.value === customDenomOption.value &&
!customDenom &&
amount &&
amount !== "0"
) {
setCustomDenomError("Custom denom must be set because of selection above");
return false;
}
if (!amount || Number(amount) <= 0) {
setAmountError("Amount must be greater than 0");
return false;
}
if (selectedDenom.value === customDenomOption.value && !Number.isInteger(Number(amount))) {
setAmountError("Amount cannot be decimal for custom denom");
return false;
}
try {
displayCoinToBaseCoin({ denom, amount }, chain.assets);
} catch (e: unknown) {
setAmountError(e instanceof Error ? e.message : "Could not set decimals");
return false;
}
return true;
};
const denom =
selectedDenom.value === customDenomOption.value ? customDenom : selectedDenom.value.symbol;
const microCoin = (() => {
try {
if (!denom || !amount || amount === "0") {
return null;
}
return displayCoinToBaseCoin({ denom, amount }, chain.assets);
} catch {
return null;
}
})();
const msgValue = MsgCodecs[MsgTypeUrls.FundCommunityPool].fromPartial({
depositor: senderAddress,
amount: microCoin ? [microCoin] : [],
});
const msg: EncodeObject = { typeUrl: MsgTypeUrls.FundCommunityPool, value: msgValue };
setMsgGetter({ isMsgValid, msg });
}, [chain.assets, selectedDenom.value, senderAddress, setMsgGetter, trimmedInputs]);
return (
<StackableContainer lessPadding lessMargin>
<button className="remove" onClick={() => deleteMsg()}>
</button>
<h2>MsgFundCommunityPool</h2>
<div className="form-item form-select">
<label>Choose a denom:</label>
<Select
label="Select denom"
name="denom-select"
options={denomOptions}
value={selectedDenom}
onChange={(option: (typeof denomOptions)[number]) => {
setSelectedDenom(option);
if (option.value !== customDenomOption.value) {
setCustomDenom("");
}
setCustomDenomError("");
}}
/>
</div>
{selectedDenom.value === customDenomOption.value ? (
<div className="form-item">
<Input
label="Custom denom"
name="custom-denom"
value={customDenom}
onChange={({ target }) => {
setCustomDenom(target.value);
setCustomDenomError("");
}}
placeholder={
selectedDenom.value === customDenomOption.value
? "Enter custom denom"
: "Select Custom denom above"
}
disabled={selectedDenom.value !== customDenomOption.value}
error={customDenomError}
/>
</div>
) : null}
<div className="form-item">
<Input
type="number"
label="Amount"
name="amount"
value={amount}
onChange={({ target }) => {
setAmount(target.value);
setAmountError("");
}}
error={amountError}
/>
</div>
<style jsx>{`
.form-item {
margin-top: 1.5em;
}
.form-item label {
font-style: italic;
font-size: 12px;
}
.form-select {
display: flex;
flex-direction: column;
gap: 0.8em;
}
button.remove {
background: rgba(255, 255, 255, 0.2);
width: 30px;
height: 30px;
border-radius: 50%;
border: none;
color: white;
position: absolute;
right: 10px;
top: 10px;
}
`}</style>
</StackableContainer>
);
};
export default MsgFundCommunityPoolForm;
@@ -25,13 +25,13 @@ const getDenomOptions = (assets: ChainInfo["assets"]) => {
};
interface MsgInstantiateContract2FormProps {
readonly fromAddress: string;
readonly senderAddress: string;
readonly setMsgGetter: (msgGetter: MsgGetter) => void;
readonly deleteMsg: () => void;
}
const MsgInstantiateContract2Form = ({
fromAddress,
senderAddress,
setMsgGetter,
deleteMsg,
}: MsgInstantiateContract2FormProps) => {
@@ -163,8 +163,8 @@ const MsgInstantiateContract2Form = ({
}
})();
const msgValue = MsgCodecs[MsgTypeUrls.Instantiate2].fromPartial({
sender: fromAddress,
const msgValue = MsgCodecs[MsgTypeUrls.InstantiateContract2].fromPartial({
sender: senderAddress,
codeId: BigInt(codeId),
label,
admin: adminAddress,
@@ -175,7 +175,7 @@ const MsgInstantiateContract2Form = ({
});
const msg: MsgInstantiateContract2EncodeObject = {
typeUrl: MsgTypeUrls.Instantiate2,
typeUrl: MsgTypeUrls.InstantiateContract2,
value: msgValue,
};
@@ -184,9 +184,9 @@ const MsgInstantiateContract2Form = ({
chain.addressPrefix,
chain.assets,
chain.chainId,
fromAddress,
msgContent,
selectedDenom.value,
senderAddress,
setMsgGetter,
trimmedInputs,
]);
@@ -25,13 +25,13 @@ const getDenomOptions = (assets: ChainInfo["assets"]) => {
};
interface MsgInstantiateContractFormProps {
readonly fromAddress: string;
readonly senderAddress: string;
readonly setMsgGetter: (msgGetter: MsgGetter) => void;
readonly deleteMsg: () => void;
}
const MsgInstantiateContractForm = ({
fromAddress,
senderAddress,
setMsgGetter,
deleteMsg,
}: MsgInstantiateContractFormProps) => {
@@ -141,8 +141,8 @@ const MsgInstantiateContractForm = ({
}
})();
const msgValue = MsgCodecs[MsgTypeUrls.Instantiate].fromPartial({
sender: fromAddress,
const msgValue = MsgCodecs[MsgTypeUrls.InstantiateContract].fromPartial({
sender: senderAddress,
codeId: BigInt(codeId),
label,
admin: adminAddress,
@@ -151,7 +151,7 @@ const MsgInstantiateContractForm = ({
});
const msg: MsgInstantiateContractEncodeObject = {
typeUrl: MsgTypeUrls.Instantiate,
typeUrl: MsgTypeUrls.InstantiateContract,
value: msgValue,
};
@@ -160,9 +160,9 @@ const MsgInstantiateContractForm = ({
chain.addressPrefix,
chain.assets,
chain.chainId,
fromAddress,
msgContent,
selectedDenom.value,
senderAddress,
setMsgGetter,
trimmedInputs,
]);
@@ -12,13 +12,13 @@ import StackableContainer from "../../../layout/StackableContainer";
const JsonEditor = dynamic(() => import("../../../inputs/JsonEditor"), { ssr: false });
interface MsgMigrateContractFormProps {
readonly fromAddress: string;
readonly senderAddress: string;
readonly setMsgGetter: (msgGetter: MsgGetter) => void;
readonly deleteMsg: () => void;
}
const MsgMigrateContractForm = ({
fromAddress,
senderAddress,
setMsgGetter,
deleteMsg,
}: MsgMigrateContractFormProps) => {
@@ -69,17 +69,20 @@ const MsgMigrateContractForm = ({
}
})();
const msgValue = MsgCodecs[MsgTypeUrls.Migrate].fromPartial({
sender: fromAddress,
const msgValue = MsgCodecs[MsgTypeUrls.MigrateContract].fromPartial({
sender: senderAddress,
contract: contractAddress,
codeId: BigInt(codeId),
msg: msgContentUtf8Array,
});
const msg: MsgMigrateContractEncodeObject = { typeUrl: MsgTypeUrls.Migrate, value: msgValue };
const msg: MsgMigrateContractEncodeObject = {
typeUrl: MsgTypeUrls.MigrateContract,
value: msgValue,
};
setMsgGetter({ isMsgValid, msg });
}, [chain.addressPrefix, chain.chainId, fromAddress, msgContent, setMsgGetter, trimmedInputs]);
}, [chain.addressPrefix, chain.chainId, msgContent, senderAddress, setMsgGetter, trimmedInputs]);
return (
<StackableContainer lessPadding lessMargin>
@@ -21,12 +21,12 @@ const getDenomOptions = (assets: readonly RegistryAsset[]) => {
};
interface MsgSendFormProps {
readonly fromAddress: string;
readonly senderAddress: string;
readonly setMsgGetter: (msgGetter: MsgGetter) => void;
readonly deleteMsg: () => void;
}
const MsgSendForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgSendFormProps) => {
const MsgSendForm = ({ senderAddress, setMsgGetter, deleteMsg }: MsgSendFormProps) => {
const { chain } = useChains();
const denomOptions = getDenomOptions(chain.assets);
@@ -103,7 +103,7 @@ const MsgSendForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgSendFormProps)
})();
const msgValue = MsgCodecs[MsgTypeUrls.Send].fromPartial({
fromAddress,
fromAddress: senderAddress,
toAddress,
amount: microCoin ? [microCoin] : [],
});
@@ -115,8 +115,8 @@ const MsgSendForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgSendFormProps)
chain.addressPrefix,
chain.assets,
chain.chainId,
fromAddress,
selectedDenom.value,
senderAddress,
setMsgGetter,
trimmedInputs,
]);
@@ -8,13 +8,13 @@ import Input from "../../../inputs/Input";
import StackableContainer from "../../../layout/StackableContainer";
interface MsgSetWithdrawAddressFormProps {
readonly delegatorAddress: string;
readonly senderAddress: string;
readonly setMsgGetter: (msgGetter: MsgGetter) => void;
readonly deleteMsg: () => void;
}
const MsgSetWithdrawAddressForm = ({
delegatorAddress,
senderAddress,
setMsgGetter,
deleteMsg,
}: MsgSetWithdrawAddressFormProps) => {
@@ -42,13 +42,13 @@ const MsgSetWithdrawAddressForm = ({
};
const msgValue = MsgCodecs[MsgTypeUrls.SetWithdrawAddress].fromPartial({
delegatorAddress,
delegatorAddress: senderAddress,
withdrawAddress,
});
const msg: EncodeObject = { typeUrl: MsgTypeUrls.SetWithdrawAddress, value: msgValue };
setMsgGetter({ isMsgValid, msg });
}, [chain.addressPrefix, chain.chainId, delegatorAddress, setMsgGetter, trimmedInputs]);
}, [chain.addressPrefix, chain.chainId, senderAddress, setMsgGetter, trimmedInputs]);
return (
<StackableContainer lessPadding lessMargin>
@@ -24,12 +24,12 @@ const humanTimestampOptions = [
];
interface MsgTransferFormProps {
readonly fromAddress: string;
readonly senderAddress: string;
readonly setMsgGetter: (msgGetter: MsgGetter) => void;
readonly deleteMsg: () => void;
}
const MsgTransferForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgTransferFormProps) => {
const MsgTransferForm = ({ senderAddress, setMsgGetter, deleteMsg }: MsgTransferFormProps) => {
const { chain } = useChains();
const [toAddress, setToAddress] = useState("");
@@ -107,7 +107,7 @@ const MsgTransferForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgTransferFo
};
const msgValue = MsgCodecs[MsgTypeUrls.Transfer].fromPartial({
sender: fromAddress,
sender: senderAddress,
receiver: toAddress,
token: { denom, amount },
sourcePort,
@@ -119,7 +119,7 @@ const MsgTransferForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgTransferFo
const msg: MsgTransferEncodeObject = { typeUrl: MsgTypeUrls.Transfer, value: msgValue };
setMsgGetter({ isMsgValid, msg });
}, [chain.chainId, fromAddress, setMsgGetter, trimmedInputs]);
}, [chain.chainId, senderAddress, setMsgGetter, trimmedInputs]);
return (
<StackableContainer lessPadding lessMargin>
@@ -10,16 +10,12 @@ import Input from "../../../inputs/Input";
import StackableContainer from "../../../layout/StackableContainer";
interface MsgUndelegateFormProps {
readonly delegatorAddress: string;
readonly senderAddress: string;
readonly setMsgGetter: (msgGetter: MsgGetter) => void;
readonly deleteMsg: () => void;
}
const MsgUndelegateForm = ({
delegatorAddress,
setMsgGetter,
deleteMsg,
}: MsgUndelegateFormProps) => {
const MsgUndelegateForm = ({ senderAddress, setMsgGetter, deleteMsg }: MsgUndelegateFormProps) => {
const { chain } = useChains();
const [validatorAddress, setValidatorAddress] = useState("");
@@ -70,7 +66,7 @@ const MsgUndelegateForm = ({
})();
const msgValue = MsgCodecs[MsgTypeUrls.Undelegate].fromPartial({
delegatorAddress,
delegatorAddress: senderAddress,
validatorAddress,
amount: microCoin,
});
@@ -83,7 +79,7 @@ const MsgUndelegateForm = ({
chain.assets,
chain.chainId,
chain.displayDenom,
delegatorAddress,
senderAddress,
setMsgGetter,
trimmedInputs,
]);
@@ -8,12 +8,16 @@ import Input from "../../../inputs/Input";
import StackableContainer from "../../../layout/StackableContainer";
interface MsgUpdateAdminFormProps {
readonly fromAddress: string;
readonly senderAddress: string;
readonly setMsgGetter: (msgGetter: MsgGetter) => void;
readonly deleteMsg: () => void;
}
const MsgUpdateAdminForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgUpdateAdminFormProps) => {
const MsgUpdateAdminForm = ({
senderAddress,
setMsgGetter,
deleteMsg,
}: MsgUpdateAdminFormProps) => {
const { chain } = useChains();
const [contractAddress, setContractAddress] = useState("");
@@ -52,7 +56,7 @@ const MsgUpdateAdminForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgUpdateA
};
const msgValue = MsgCodecs[MsgTypeUrls.UpdateAdmin].fromPartial({
sender: fromAddress,
sender: senderAddress,
contract: contractAddress,
newAdmin: newAdminAddress,
});
@@ -60,7 +64,7 @@ const MsgUpdateAdminForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgUpdateA
const msg: MsgUpdateAdminEncodeObject = { typeUrl: MsgTypeUrls.UpdateAdmin, value: msgValue };
setMsgGetter({ isMsgValid, msg });
}, [chain.addressPrefix, chain.chainId, fromAddress, setMsgGetter, trimmedInputs]);
}, [chain.addressPrefix, chain.chainId, senderAddress, setMsgGetter, trimmedInputs]);
return (
<StackableContainer lessPadding lessMargin>
@@ -20,12 +20,12 @@ const selectVoteOptions = voteOptions.map((opt) => {
});
interface MsgVoteFormProps {
readonly fromAddress: string;
readonly senderAddress: string;
readonly setMsgGetter: (msgGetter: MsgGetter) => void;
readonly deleteMsg: () => void;
}
const MsgVoteForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgVoteFormProps) => {
const MsgVoteForm = ({ senderAddress, setMsgGetter, deleteMsg }: MsgVoteFormProps) => {
const [proposalId, setProposalId] = useState("0");
const [selectedVote, setSelectedVote] = useState(selectVoteOptions[0]);
@@ -64,7 +64,7 @@ const MsgVoteForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgVoteFormProps)
})();
const msgValue = MsgCodecs[MsgTypeUrls.Vote].fromPartial({
voter: fromAddress,
voter: senderAddress,
proposalId: proposalIdBigInt,
option: selectedVote.value,
});
@@ -72,7 +72,7 @@ const MsgVoteForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgVoteFormProps)
const msg: MsgVoteEncodeObject = { typeUrl: MsgTypeUrls.Vote, value: msgValue };
setMsgGetter({ isMsgValid, msg });
}, [fromAddress, selectedVote.value, setMsgGetter, trimmedInputs]);
}, [selectedVote.value, senderAddress, setMsgGetter, trimmedInputs]);
return (
<StackableContainer lessPadding lessMargin>
@@ -8,17 +8,17 @@ import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
import Input from "../../../inputs/Input";
import StackableContainer from "../../../layout/StackableContainer";
interface MsgClaimRewardsFormProps {
readonly delegatorAddress: string;
interface MsgWithdrawDelegatorRewardFormProps {
readonly senderAddress: string;
readonly setMsgGetter: (msgGetter: MsgGetter) => void;
readonly deleteMsg: () => void;
}
const MsgClaimRewardsForm = ({
delegatorAddress,
const MsgWithdrawDelegatorRewardForm = ({
senderAddress,
setMsgGetter,
deleteMsg,
}: MsgClaimRewardsFormProps) => {
}: MsgWithdrawDelegatorRewardFormProps) => {
const { chain } = useChains();
const [validatorAddress, setValidatorAddress] = useState("");
@@ -45,7 +45,7 @@ const MsgClaimRewardsForm = ({
};
const msgValue = MsgCodecs[MsgTypeUrls.WithdrawDelegatorReward].fromPartial({
delegatorAddress,
delegatorAddress: senderAddress,
validatorAddress,
});
@@ -55,7 +55,7 @@ const MsgClaimRewardsForm = ({
};
setMsgGetter({ isMsgValid, msg });
}, [chain.addressPrefix, chain.chainId, delegatorAddress, setMsgGetter, trimmedInputs]);
}, [chain.addressPrefix, chain.chainId, senderAddress, setMsgGetter, trimmedInputs]);
return (
<StackableContainer lessPadding lessMargin>
@@ -100,4 +100,4 @@ const MsgClaimRewardsForm = ({
);
};
export default MsgClaimRewardsForm;
export default MsgWithdrawDelegatorRewardForm;
+32 -22
View File
@@ -1,19 +1,20 @@
import { MsgGetter } from "..";
import { MsgTypeUrl, MsgTypeUrls } from "../../../../types/txMsg";
import MsgClaimRewardsForm from "./MsgClaimRewardsForm";
import MsgBeginRedelegateForm from "./MsgBeginRedelegateForm";
import MsgCreateVestingAccountForm from "./MsgCreateVestingAccountForm";
import MsgDelegateForm from "./MsgDelegateForm";
import MsgExecuteContractForm from "./MsgExecuteContractForm";
import MsgFundCommunityPoolForm from "./MsgFundCommunityPoolForm";
import MsgInstantiateContract2Form from "./MsgInstantiateContract2Form";
import MsgInstantiateContractForm from "./MsgInstantiateContractForm";
import MsgMigrateContractForm from "./MsgMigrateContractForm";
import MsgRedelegateForm from "./MsgRedelegateForm";
import MsgSendForm from "./MsgSendForm";
import MsgSetWithdrawAddressForm from "./MsgSetWithdrawAddressForm";
import MsgTransferForm from "./MsgTransferForm";
import MsgUndelegateForm from "./MsgUndelegateForm";
import MsgUpdateAdminForm from "./MsgUpdateAdminForm";
import MsgVoteForm from "./MsgVoteForm";
import MsgWithdrawDelegatorRewardForm from "./MsgWithdrawDelegatorRewardForm";
interface MsgFormProps {
readonly msgType: MsgTypeUrl;
@@ -22,36 +23,45 @@ interface MsgFormProps {
readonly deleteMsg: () => void;
}
const MsgForm = ({ msgType, senderAddress, ...restProps }: MsgFormProps) => {
const MsgForm = ({ msgType, ...restProps }: MsgFormProps) => {
switch (msgType) {
// Bank
case MsgTypeUrls.Send:
return <MsgSendForm fromAddress={senderAddress} {...restProps} />;
return <MsgSendForm {...restProps} />;
// Staking
case MsgTypeUrls.Delegate:
return <MsgDelegateForm delegatorAddress={senderAddress} {...restProps} />;
return <MsgDelegateForm {...restProps} />;
case MsgTypeUrls.Undelegate:
return <MsgUndelegateForm delegatorAddress={senderAddress} {...restProps} />;
return <MsgUndelegateForm {...restProps} />;
case MsgTypeUrls.BeginRedelegate:
return <MsgRedelegateForm delegatorAddress={senderAddress} {...restProps} />;
case MsgTypeUrls.WithdrawDelegatorReward:
return <MsgClaimRewardsForm delegatorAddress={senderAddress} {...restProps} />;
return <MsgBeginRedelegateForm {...restProps} />;
// Distribution
case MsgTypeUrls.FundCommunityPool:
return <MsgFundCommunityPoolForm {...restProps} />;
case MsgTypeUrls.SetWithdrawAddress:
return <MsgSetWithdrawAddressForm delegatorAddress={senderAddress} {...restProps} />;
return <MsgSetWithdrawAddressForm {...restProps} />;
case MsgTypeUrls.WithdrawDelegatorReward:
return <MsgWithdrawDelegatorRewardForm {...restProps} />;
// Vesting
case MsgTypeUrls.CreateVestingAccount:
return <MsgCreateVestingAccountForm fromAddress={senderAddress} {...restProps} />;
return <MsgCreateVestingAccountForm {...restProps} />;
// Governance
case MsgTypeUrls.Vote:
return <MsgVoteForm fromAddress={senderAddress} {...restProps} />;
return <MsgVoteForm {...restProps} />;
// IBC
case MsgTypeUrls.Transfer:
return <MsgTransferForm fromAddress={senderAddress} {...restProps} />;
case MsgTypeUrls.Execute:
return <MsgExecuteContractForm fromAddress={senderAddress} {...restProps} />;
case MsgTypeUrls.Instantiate:
return <MsgInstantiateContractForm fromAddress={senderAddress} {...restProps} />;
case MsgTypeUrls.Instantiate2:
return <MsgInstantiateContract2Form fromAddress={senderAddress} {...restProps} />;
case MsgTypeUrls.Migrate:
return <MsgMigrateContractForm fromAddress={senderAddress} {...restProps} />;
return <MsgTransferForm {...restProps} />;
// CosmWasm
case MsgTypeUrls.InstantiateContract:
return <MsgInstantiateContractForm {...restProps} />;
case MsgTypeUrls.InstantiateContract2:
return <MsgInstantiateContract2Form {...restProps} />;
case MsgTypeUrls.UpdateAdmin:
return <MsgUpdateAdminForm fromAddress={senderAddress} {...restProps} />;
return <MsgUpdateAdminForm {...restProps} />;
case MsgTypeUrls.ExecuteContract:
return <MsgExecuteContractForm {...restProps} />;
case MsgTypeUrls.MigrateContract:
return <MsgMigrateContractForm {...restProps} />;
default:
return null;
}
+21 -6
View File
@@ -229,11 +229,14 @@ const CreateTxForm = ({ router, senderAddress, accountOnChain }: CreateTxFormPro
/>
</li>
</ul>
</div>
<div className="btn-cluster">
<label>Distribution</label>
<ul>
<li>
<Button
label="WithdrawDelegatorReward"
onClick={() => addMsgWithValidator(MsgTypeUrls.WithdrawDelegatorReward)}
label="FundCommunityPool"
onClick={() => addMsgType(MsgTypeUrls.FundCommunityPool)}
/>
</li>
<li>
@@ -242,6 +245,12 @@ const CreateTxForm = ({ router, senderAddress, accountOnChain }: CreateTxFormPro
onClick={() => addMsgType(MsgTypeUrls.SetWithdrawAddress)}
/>
</li>
<li>
<Button
label="WithdrawDelegatorReward"
onClick={() => addMsgWithValidator(MsgTypeUrls.WithdrawDelegatorReward)}
/>
</li>
</ul>
</div>
<div className="btn-cluster">
@@ -250,20 +259,26 @@ const CreateTxForm = ({ router, senderAddress, accountOnChain }: CreateTxFormPro
<li>
<Button
label="InstantiateContract"
onClick={() => addMsgType(MsgTypeUrls.Instantiate)}
onClick={() => addMsgType(MsgTypeUrls.InstantiateContract)}
/>
</li>
<li>
<Button
label="InstantiateContract2"
onClick={() => addMsgType(MsgTypeUrls.Instantiate2)}
onClick={() => addMsgType(MsgTypeUrls.InstantiateContract2)}
/>
</li>
<li>
<Button label="ExecuteContract" onClick={() => addMsgType(MsgTypeUrls.Execute)} />
<Button
label="ExecuteContract"
onClick={() => addMsgType(MsgTypeUrls.ExecuteContract)}
/>
</li>
<li>
<Button label="MigrateContract" onClick={() => addMsgType(MsgTypeUrls.Migrate)} />
<Button
label="MigrateContract"
onClick={() => addMsgType(MsgTypeUrls.MigrateContract)}
/>
</li>
<li>
<Button
+21 -12
View File
@@ -4,36 +4,45 @@ import { MsgCodecs, MsgTypeUrl, MsgTypeUrls } from "../types/txMsg";
const gasOfMsg = (msgType: MsgTypeUrl): number => {
switch (msgType) {
// Bank
case MsgTypeUrls.Send:
return 100_000;
case MsgTypeUrls.SetWithdrawAddress:
return 100_000;
case MsgTypeUrls.WithdrawDelegatorReward:
return 100_000;
case MsgTypeUrls.BeginRedelegate:
return 400_000;
// Staking
case MsgTypeUrls.Delegate:
// This is enough for 1 delegation and 1 autoclaim. But it is probably too low for
// a lot of auto-claims. See https://github.com/cosmos/cosmos-multisig-ui/issues/177.
return 400_000;
case MsgTypeUrls.Undelegate:
return 400_000;
case MsgTypeUrls.BeginRedelegate:
return 400_000;
// Distribution
case MsgTypeUrls.FundCommunityPool:
return 100_000;
case MsgTypeUrls.SetWithdrawAddress:
return 100_000;
case MsgTypeUrls.WithdrawDelegatorReward:
return 100_000;
// Vesting
case MsgTypeUrls.CreateVestingAccount:
return 100_000;
// Governance
case MsgTypeUrls.Vote:
return 100_000;
// IBC
case MsgTypeUrls.Transfer:
return 180_000;
case MsgTypeUrls.Execute:
// CosmWasm
case MsgTypeUrls.InstantiateContract:
return 150_000;
case MsgTypeUrls.Instantiate:
return 150_000;
case MsgTypeUrls.Instantiate2:
return 150_000;
case MsgTypeUrls.Migrate:
case MsgTypeUrls.InstantiateContract2:
return 150_000;
case MsgTypeUrls.UpdateAdmin:
return 150_000;
case MsgTypeUrls.ExecuteContract:
return 150_000;
case MsgTypeUrls.MigrateContract:
return 150_000;
default:
throw new Error("Unknown msg type");
}
+31 -14
View File
@@ -1,5 +1,6 @@
import { MsgSend } from "cosmjs-types/cosmos/bank/v1beta1/tx";
import {
MsgFundCommunityPool,
MsgSetWithdrawAddress,
MsgWithdrawDelegatorReward,
} from "cosmjs-types/cosmos/distribution/v1beta1/tx";
@@ -20,37 +21,53 @@ import {
import { MsgTransfer } from "cosmjs-types/ibc/applications/transfer/v1/tx";
export const MsgTypeUrls = {
// Bank
Send: "/cosmos.bank.v1beta1.MsgSend",
SetWithdrawAddress: "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress",
WithdrawDelegatorReward: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward",
BeginRedelegate: "/cosmos.staking.v1beta1.MsgBeginRedelegate",
// Staking
Delegate: "/cosmos.staking.v1beta1.MsgDelegate",
Undelegate: "/cosmos.staking.v1beta1.MsgUndelegate",
BeginRedelegate: "/cosmos.staking.v1beta1.MsgBeginRedelegate",
// Distribution
FundCommunityPool: "/cosmos.distribution.v1beta1.MsgFundCommunityPool",
SetWithdrawAddress: "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress",
WithdrawDelegatorReward: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward",
// Vesting
CreateVestingAccount: "/cosmos.vesting.v1beta1.MsgCreateVestingAccount",
// Governance
Vote: "/cosmos.gov.v1beta1.MsgVote",
// IBC
Transfer: "/ibc.applications.transfer.v1.MsgTransfer",
Execute: "/cosmwasm.wasm.v1.MsgExecuteContract",
Instantiate: "/cosmwasm.wasm.v1.MsgInstantiateContract",
Instantiate2: "/cosmwasm.wasm.v1.MsgInstantiateContract2",
Migrate: "/cosmwasm.wasm.v1.MsgMigrateContract",
// CosmWasm
InstantiateContract: "/cosmwasm.wasm.v1.MsgInstantiateContract",
InstantiateContract2: "/cosmwasm.wasm.v1.MsgInstantiateContract2",
UpdateAdmin: "/cosmwasm.wasm.v1.MsgUpdateAdmin",
ExecuteContract: "/cosmwasm.wasm.v1.MsgExecuteContract",
MigrateContract: "/cosmwasm.wasm.v1.MsgMigrateContract",
} as const;
export type MsgTypeUrl = (typeof MsgTypeUrls)[keyof typeof MsgTypeUrls];
export const MsgCodecs = {
// Bank
[MsgTypeUrls.Send]: MsgSend,
[MsgTypeUrls.SetWithdrawAddress]: MsgSetWithdrawAddress,
[MsgTypeUrls.WithdrawDelegatorReward]: MsgWithdrawDelegatorReward,
[MsgTypeUrls.BeginRedelegate]: MsgBeginRedelegate,
// Staking
[MsgTypeUrls.Delegate]: MsgDelegate,
[MsgTypeUrls.Undelegate]: MsgUndelegate,
[MsgTypeUrls.BeginRedelegate]: MsgBeginRedelegate,
// Distribution
[MsgTypeUrls.FundCommunityPool]: MsgFundCommunityPool,
[MsgTypeUrls.SetWithdrawAddress]: MsgSetWithdrawAddress,
[MsgTypeUrls.WithdrawDelegatorReward]: MsgWithdrawDelegatorReward,
// Vesting
[MsgTypeUrls.CreateVestingAccount]: MsgCreateVestingAccount,
// Governance
[MsgTypeUrls.Vote]: MsgVote,
// IBC
[MsgTypeUrls.Transfer]: MsgTransfer,
[MsgTypeUrls.Execute]: MsgExecuteContract,
[MsgTypeUrls.Instantiate]: MsgInstantiateContract,
[MsgTypeUrls.Instantiate2]: MsgInstantiateContract2,
[MsgTypeUrls.Migrate]: MsgMigrateContract,
// CosmWasm
[MsgTypeUrls.InstantiateContract]: MsgInstantiateContract,
[MsgTypeUrls.InstantiateContract2]: MsgInstantiateContract2,
[MsgTypeUrls.UpdateAdmin]: MsgUpdateAdmin,
[MsgTypeUrls.ExecuteContract]: MsgExecuteContract,
[MsgTypeUrls.MigrateContract]: MsgMigrateContract,
};