Merge pull request #142 from cosmos/feat/use-fromjson-tojson
Use toJSON/fromJSON
This commit is contained in:
@@ -1,19 +1,19 @@
|
||||
import { TxMsgClaimRewards } from "../../../types/txMsg";
|
||||
import { MsgWithdrawDelegatorReward } from "cosmjs-types/cosmos/distribution/v1beta1/tx";
|
||||
import HashView from "../HashView";
|
||||
|
||||
interface TxMsgClaimRewardsDetailsProps {
|
||||
readonly msg: TxMsgClaimRewards;
|
||||
readonly msgValue: MsgWithdrawDelegatorReward;
|
||||
}
|
||||
|
||||
const TxMsgClaimRewardsDetails = ({ msg }: TxMsgClaimRewardsDetailsProps) => (
|
||||
const TxMsgClaimRewardsDetails = ({ msgValue }: TxMsgClaimRewardsDetailsProps) => (
|
||||
<>
|
||||
<li>
|
||||
<h3>MsgWithdrawDelegatorReward</h3>
|
||||
</li>
|
||||
<li>
|
||||
<label>Validator Address:</label>
|
||||
<div title={msg.value.validatorAddress}>
|
||||
<HashView hash={msg.value.validatorAddress} />
|
||||
<div title={msgValue.validatorAddress}>
|
||||
<HashView hash={msgValue.validatorAddress} />
|
||||
</div>
|
||||
</li>
|
||||
<style jsx>{`
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { MsgCreateVestingAccount } from "cosmjs-types/cosmos/vesting/v1beta1/tx";
|
||||
import { useAppContext } from "../../../context/AppContext";
|
||||
import { printableCoins } from "../../../lib/displayHelpers";
|
||||
import { TxMsgCreateVestingAccount } from "../../../types/txMsg";
|
||||
import HashView from "../HashView";
|
||||
|
||||
interface TxMsgCreateVestingAccountDetailsProps {
|
||||
readonly msg: TxMsgCreateVestingAccount;
|
||||
readonly msgValue: MsgCreateVestingAccount;
|
||||
}
|
||||
|
||||
const TxMsgCreateVestingAccountDetails = ({ msg }: TxMsgCreateVestingAccountDetailsProps) => {
|
||||
const TxMsgCreateVestingAccountDetails = ({ msgValue }: TxMsgCreateVestingAccountDetailsProps) => {
|
||||
const { state } = useAppContext();
|
||||
const endTimeDateObj = new Date(msg.value.endTime.multiply(1000).toNumber());
|
||||
const endTimeDateObj = new Date(msgValue.endTime.multiply(1000).toNumber());
|
||||
const endTimeDate = endTimeDateObj.toLocaleDateString();
|
||||
const endTimeHours = endTimeDateObj.toLocaleTimeString().slice(0, -3);
|
||||
|
||||
@@ -20,23 +20,23 @@ const TxMsgCreateVestingAccountDetails = ({ msg }: TxMsgCreateVestingAccountDeta
|
||||
</li>
|
||||
<li>
|
||||
<label>Amount:</label>
|
||||
<div>{printableCoins(msg.value.amount, state.chain)}</div>
|
||||
<div>{printableCoins(msgValue.amount, state.chain)}</div>
|
||||
</li>
|
||||
<li>
|
||||
<label>From:</label>
|
||||
<div title={msg.value.fromAddress}>
|
||||
<HashView hash={msg.value.fromAddress} />
|
||||
<div title={msgValue.fromAddress}>
|
||||
<HashView hash={msgValue.fromAddress} />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<label>To:</label>
|
||||
<div title={msg.value.toAddress}>
|
||||
<HashView hash={msg.value.toAddress} />
|
||||
<div title={msgValue.toAddress}>
|
||||
<HashView hash={msgValue.toAddress} />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<label>End time:</label>
|
||||
<div title={String(msg.value.endTime)}>
|
||||
<div title={String(msgValue.endTime)}>
|
||||
<p>
|
||||
{endTimeDate} {endTimeHours}
|
||||
</p>
|
||||
@@ -44,8 +44,8 @@ const TxMsgCreateVestingAccountDetails = ({ msg }: TxMsgCreateVestingAccountDeta
|
||||
</li>
|
||||
<li>
|
||||
<label>Delayed:</label>
|
||||
<div title={String(msg.value.endTime)}>
|
||||
<p>{msg.value.delayed ? "Yes" : "No"}</p>
|
||||
<div title={String(msgValue.endTime)}>
|
||||
<p>{msgValue.delayed ? "Yes" : "No"}</p>
|
||||
</div>
|
||||
</li>
|
||||
<style jsx>{`
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import { assert } from "@cosmjs/utils";
|
||||
import { MsgDelegate } from "cosmjs-types/cosmos/staking/v1beta1/tx";
|
||||
import { useAppContext } from "../../../context/AppContext";
|
||||
import { printableCoin } from "../../../lib/displayHelpers";
|
||||
import { TxMsgDelegate } from "../../../types/txMsg";
|
||||
import HashView from "../HashView";
|
||||
|
||||
interface TxMsgDelegateDetailsProps {
|
||||
readonly msg: TxMsgDelegate;
|
||||
readonly msgValue: MsgDelegate;
|
||||
}
|
||||
|
||||
const TxMsgDelegateDetails = ({ msg }: TxMsgDelegateDetailsProps) => {
|
||||
const TxMsgDelegateDetails = ({ msgValue }: TxMsgDelegateDetailsProps) => {
|
||||
const { state } = useAppContext();
|
||||
assert(msg.value.amount, "Amount must be set, see https://github.com/osmosis-labs/telescope/issues/386");
|
||||
assert(
|
||||
msgValue.amount,
|
||||
"Amount must be set, see https://github.com/osmosis-labs/telescope/issues/386",
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -19,12 +22,12 @@ const TxMsgDelegateDetails = ({ msg }: TxMsgDelegateDetailsProps) => {
|
||||
</li>
|
||||
<li>
|
||||
<label>Amount:</label>
|
||||
<div>{printableCoin(msg.value.amount, state.chain)}</div>
|
||||
<div>{printableCoin(msgValue.amount, state.chain)}</div>
|
||||
</li>
|
||||
<li>
|
||||
<label>Validator Address:</label>
|
||||
<div title={msg.value.validatorAddress}>
|
||||
<HashView hash={msg.value.validatorAddress} />
|
||||
<div title={msgValue.validatorAddress}>
|
||||
<HashView hash={msgValue.validatorAddress} />
|
||||
</div>
|
||||
</li>
|
||||
<style jsx>{`
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import { assert } from "@cosmjs/utils";
|
||||
import { MsgBeginRedelegate } from "cosmjs-types/cosmos/staking/v1beta1/tx";
|
||||
import { useAppContext } from "../../../context/AppContext";
|
||||
import { printableCoin } from "../../../lib/displayHelpers";
|
||||
import { TxMsgRedelegate } from "../../../types/txMsg";
|
||||
import HashView from "../HashView";
|
||||
|
||||
interface TxMsgRedelegateDetailsProps {
|
||||
readonly msg: TxMsgRedelegate;
|
||||
readonly msgValue: MsgBeginRedelegate;
|
||||
}
|
||||
|
||||
const TxMsgRedelegateDetails = ({ msg }: TxMsgRedelegateDetailsProps) => {
|
||||
const TxMsgRedelegateDetails = ({ msgValue }: TxMsgRedelegateDetailsProps) => {
|
||||
const { state } = useAppContext();
|
||||
assert(msg.value.amount, "Amount must be set, same as https://github.com/osmosis-labs/telescope/issues/386");
|
||||
assert(
|
||||
msgValue.amount,
|
||||
"Amount must be set, same as https://github.com/osmosis-labs/telescope/issues/386",
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -19,18 +22,18 @@ const TxMsgRedelegateDetails = ({ msg }: TxMsgRedelegateDetailsProps) => {
|
||||
</li>
|
||||
<li>
|
||||
<label>Amount:</label>
|
||||
<div>{printableCoin(msg.value.amount, state.chain)}</div>
|
||||
<div>{printableCoin(msgValue.amount, state.chain)}</div>
|
||||
</li>
|
||||
<li>
|
||||
<label>Src Validator Address:</label>
|
||||
<div title={msg.value.validatorSrcAddress}>
|
||||
<HashView hash={msg.value.validatorSrcAddress} />
|
||||
<div title={msgValue.validatorSrcAddress}>
|
||||
<HashView hash={msgValue.validatorSrcAddress} />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<label>Dst Validator Address:</label>
|
||||
<div title={msg.value.validatorDstAddress}>
|
||||
<HashView hash={msg.value.validatorDstAddress} />
|
||||
<div title={msgValue.validatorDstAddress}>
|
||||
<HashView hash={msgValue.validatorDstAddress} />
|
||||
</div>
|
||||
</li>
|
||||
<style jsx>{`
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { MsgSend } from "cosmjs-types/cosmos/bank/v1beta1/tx";
|
||||
import { useAppContext } from "../../../context/AppContext";
|
||||
import { printableCoins } from "../../../lib/displayHelpers";
|
||||
import { TxMsgSend } from "../../../types/txMsg";
|
||||
import HashView from "../HashView";
|
||||
|
||||
interface TxMsgSendDetailsProps {
|
||||
readonly msg: TxMsgSend;
|
||||
readonly msgValue: MsgSend;
|
||||
}
|
||||
|
||||
const TxMsgSendDetails = ({ msg }: TxMsgSendDetailsProps) => {
|
||||
const TxMsgSendDetails = ({ msgValue }: TxMsgSendDetailsProps) => {
|
||||
const { state } = useAppContext();
|
||||
|
||||
return (
|
||||
@@ -17,12 +17,12 @@ const TxMsgSendDetails = ({ msg }: TxMsgSendDetailsProps) => {
|
||||
</li>
|
||||
<li>
|
||||
<label>Amount:</label>
|
||||
<div>{printableCoins(msg.value.amount, state.chain)}</div>
|
||||
<div>{printableCoins(msgValue.amount, state.chain)}</div>
|
||||
</li>
|
||||
<li>
|
||||
<label>To:</label>
|
||||
<div title={msg.value.toAddress}>
|
||||
<HashView hash={msg.value.toAddress} />
|
||||
<div title={msgValue.toAddress}>
|
||||
<HashView hash={msgValue.toAddress} />
|
||||
</div>
|
||||
</li>
|
||||
<style jsx>{`
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { TxMsgSetWithdrawAddress } from "../../../types/txMsg";
|
||||
import { MsgSetWithdrawAddress } from "cosmjs-types/cosmos/distribution/v1beta1/tx";
|
||||
import HashView from "../HashView";
|
||||
|
||||
interface TxMsgSetWithdrawAddressDetailsProps {
|
||||
readonly msg: TxMsgSetWithdrawAddress;
|
||||
readonly msgValue: MsgSetWithdrawAddress;
|
||||
}
|
||||
|
||||
const TxMsgSetWithdrawAddressDetails = ({ msg }: TxMsgSetWithdrawAddressDetailsProps) => (
|
||||
const TxMsgSetWithdrawAddressDetails = ({ msgValue }: TxMsgSetWithdrawAddressDetailsProps) => (
|
||||
<>
|
||||
<li>
|
||||
<h3>MsgSetWithdrawAddress</h3>
|
||||
</li>
|
||||
<li>
|
||||
<label>Withdraw Address:</label>
|
||||
<div title={msg.value.withdrawAddress}>
|
||||
<HashView hash={msg.value.withdrawAddress} />
|
||||
<div title={msgValue.withdrawAddress}>
|
||||
<HashView hash={msgValue.withdrawAddress} />
|
||||
</div>
|
||||
</li>
|
||||
<style jsx>{`
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
import { assert } from "@cosmjs/utils";
|
||||
import { MsgTransfer } from "cosmjs-types/ibc/applications/transfer/v1/tx";
|
||||
import { thinSpace } from "../../../lib/displayHelpers";
|
||||
import { TxMsgTransfer } from "../../../types/txMsg";
|
||||
import HashView from "../HashView";
|
||||
|
||||
interface TxMsgTransferDetailsProps {
|
||||
readonly msg: TxMsgTransfer;
|
||||
readonly msgValue: MsgTransfer;
|
||||
}
|
||||
|
||||
const TxMsgTransferDetails = ({ msg }: TxMsgTransferDetailsProps) => {
|
||||
assert(msg.value.token, "Token must be set, same as https://github.com/osmosis-labs/telescope/issues/386");
|
||||
const timeoutDateObj = new Date(msg.value.timeoutTimestamp.divide(1_000_000).toNumber());
|
||||
const TxMsgTransferDetails = ({ msgValue }: TxMsgTransferDetailsProps) => {
|
||||
assert(
|
||||
msgValue.token,
|
||||
"Token must be set, same as https://github.com/osmosis-labs/telescope/issues/386",
|
||||
);
|
||||
const timeoutDateObj = new Date(msgValue.timeoutTimestamp.divide(1_000_000).toNumber());
|
||||
const timeoutDate = timeoutDateObj.toLocaleDateString();
|
||||
const timeoutTime = timeoutDateObj.toLocaleTimeString();
|
||||
|
||||
@@ -20,20 +23,20 @@ const TxMsgTransferDetails = ({ msg }: TxMsgTransferDetailsProps) => {
|
||||
</li>
|
||||
<li>
|
||||
<label>Source Port:</label>
|
||||
<div>{msg.value.sourcePort}</div>
|
||||
<div>{msgValue.sourcePort}</div>
|
||||
</li>
|
||||
<li>
|
||||
<label>Source Channel:</label>
|
||||
<div>{msg.value.sourceChannel}</div>
|
||||
<div>{msgValue.sourceChannel}</div>
|
||||
</li>
|
||||
<li>
|
||||
<label>Token:</label>
|
||||
<div>{msg.value.token.amount + thinSpace + msg.value.token.denom}</div>
|
||||
<div>{msgValue.token.amount + thinSpace + msgValue.token.denom}</div>
|
||||
</li>
|
||||
<li>
|
||||
<label>To:</label>
|
||||
<div title={msg.value.receiver}>
|
||||
<HashView hash={msg.value.receiver} />
|
||||
<div title={msgValue.receiver}>
|
||||
<HashView hash={msgValue.receiver} />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
@@ -44,7 +47,7 @@ const TxMsgTransferDetails = ({ msg }: TxMsgTransferDetailsProps) => {
|
||||
</li>
|
||||
<li>
|
||||
<label>Memo:</label>
|
||||
<div>{msg.value.memo}</div>
|
||||
<div>{msgValue.memo}</div>
|
||||
</li>
|
||||
<style jsx>{`
|
||||
li:not(:has(h3)) {
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import { assert } from "@cosmjs/utils";
|
||||
import { MsgUndelegate } from "cosmjs-types/cosmos/staking/v1beta1/tx";
|
||||
import { useAppContext } from "../../../context/AppContext";
|
||||
import { printableCoin } from "../../../lib/displayHelpers";
|
||||
import { TxMsgUndelegate } from "../../../types/txMsg";
|
||||
import HashView from "../HashView";
|
||||
|
||||
interface TxMsgUndelegateDetailsProps {
|
||||
readonly msg: TxMsgUndelegate;
|
||||
readonly msgValue: MsgUndelegate;
|
||||
}
|
||||
|
||||
const TxMsgUndelegateDetails = ({ msg }: TxMsgUndelegateDetailsProps) => {
|
||||
const TxMsgUndelegateDetails = ({ msgValue: msg }: TxMsgUndelegateDetailsProps) => {
|
||||
const { state } = useAppContext();
|
||||
assert(msg.value.amount, "Amount must be set, same as https://github.com/osmosis-labs/telescope/issues/386");
|
||||
assert(
|
||||
msg.amount,
|
||||
"Amount must be set, same as https://github.com/osmosis-labs/telescope/issues/386",
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -19,12 +22,12 @@ const TxMsgUndelegateDetails = ({ msg }: TxMsgUndelegateDetailsProps) => {
|
||||
</li>
|
||||
<li>
|
||||
<label>Amount:</label>
|
||||
<div>{printableCoin(msg.value.amount, state.chain)}</div>
|
||||
<div>{printableCoin(msg.amount, state.chain)}</div>
|
||||
</li>
|
||||
<li>
|
||||
<label>Validator Address:</label>
|
||||
<div title={msg.value.validatorAddress}>
|
||||
<HashView hash={msg.value.validatorAddress} />
|
||||
<div title={msg.validatorAddress}>
|
||||
<HashView hash={msg.validatorAddress} />
|
||||
</div>
|
||||
</li>
|
||||
<style jsx>{`
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
import { EncodeObject } from "@cosmjs/proto-signing";
|
||||
import { useAppContext } from "../../../context/AppContext";
|
||||
import { printableCoins } from "../../../lib/displayHelpers";
|
||||
import {
|
||||
isTxMsgClaimRewards,
|
||||
isTxMsgCreateVestingAccount,
|
||||
isTxMsgDelegate,
|
||||
isTxMsgRedelegate,
|
||||
isTxMsgSend,
|
||||
isTxMsgSetWithdrawAddress,
|
||||
isTxMsgTransfer,
|
||||
isTxMsgUndelegate,
|
||||
} from "../../../lib/txMsgHelpers";
|
||||
import { DbTransaction } from "../../../types";
|
||||
import { MsgTypeUrls } from "../../../types/txMsg";
|
||||
import StackableContainer from "../../layout/StackableContainer";
|
||||
import TxMsgClaimRewardsDetails from "./TxMsgClaimRewardsDetails";
|
||||
import TxMsgCreateVestingAccountDetails from "./TxMsgCreateVestingAccountDetails";
|
||||
@@ -21,11 +13,34 @@ import TxMsgSetWithdrawAddressDetails from "./TxMsgSetWithdrawAddressDetails";
|
||||
import TxMsgTransferDetails from "./TxMsgTransferDetails";
|
||||
import TxMsgUndelegateDetails from "./TxMsgUndelegateDetails";
|
||||
|
||||
interface Props {
|
||||
const TxMsgDetails = ({ typeUrl, value: msgValue }: EncodeObject) => {
|
||||
switch (typeUrl) {
|
||||
case MsgTypeUrls.Send:
|
||||
return <TxMsgSendDetails msgValue={msgValue} />;
|
||||
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} />;
|
||||
case MsgTypeUrls.SetWithdrawAddress:
|
||||
return <TxMsgSetWithdrawAddressDetails msgValue={msgValue} />;
|
||||
case MsgTypeUrls.CreateVestingAccount:
|
||||
return <TxMsgCreateVestingAccountDetails msgValue={msgValue} />;
|
||||
case MsgTypeUrls.Transfer:
|
||||
return <TxMsgTransferDetails msgValue={msgValue} />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
interface TransactionInfoProps {
|
||||
readonly tx: DbTransaction;
|
||||
}
|
||||
|
||||
const TransactionInfo = ({ tx }: Props) => {
|
||||
const TransactionInfo = ({ tx }: TransactionInfoProps) => {
|
||||
const { state } = useAppContext();
|
||||
|
||||
return (
|
||||
@@ -55,14 +70,7 @@ const TransactionInfo = ({ tx }: Props) => {
|
||||
<StackableContainer lessPadding lessMargin>
|
||||
{tx.msgs.map((msg, index) => (
|
||||
<StackableContainer key={index} lessPadding lessMargin>
|
||||
{isTxMsgSend(msg) ? <TxMsgSendDetails msg={msg} /> : null}
|
||||
{isTxMsgDelegate(msg) ? <TxMsgDelegateDetails msg={msg} /> : null}
|
||||
{isTxMsgUndelegate(msg) ? <TxMsgUndelegateDetails msg={msg} /> : null}
|
||||
{isTxMsgRedelegate(msg) ? <TxMsgRedelegateDetails msg={msg} /> : null}
|
||||
{isTxMsgClaimRewards(msg) ? <TxMsgClaimRewardsDetails msg={msg} /> : null}
|
||||
{isTxMsgSetWithdrawAddress(msg) ? (<TxMsgSetWithdrawAddressDetails msg={msg} />) : null}
|
||||
{isTxMsgCreateVestingAccount(msg) ? (<TxMsgCreateVestingAccountDetails msg={msg} />) : null}
|
||||
{isTxMsgTransfer(msg) ? <TxMsgTransferDetails msg={msg} /> : null}
|
||||
<TxMsgDetails {...msg} />
|
||||
</StackableContainer>
|
||||
))}
|
||||
</StackableContainer>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { MsgWithdrawDelegatorRewardEncodeObject } from "@cosmjs/stargate";
|
||||
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 { isTxMsgClaimRewards } from "../../../../lib/txMsgHelpers";
|
||||
import { TxMsg, TxMsgClaimRewards } from "../../../../types/txMsg";
|
||||
import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
|
||||
import Input from "../../../inputs/Input";
|
||||
import StackableContainer from "../../../layout/StackableContainer";
|
||||
|
||||
@@ -29,7 +29,7 @@ const MsgClaimRewardsForm = ({
|
||||
try {
|
||||
setValidatorAddressError("");
|
||||
|
||||
const isMsgValid = (msg: TxMsg): msg is TxMsgClaimRewards => {
|
||||
const isMsgValid = (): boolean => {
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
|
||||
const addressErrorMsg = checkAddress(validatorAddress, state.chain.addressPrefix);
|
||||
@@ -40,12 +40,17 @@ const MsgClaimRewardsForm = ({
|
||||
return false;
|
||||
}
|
||||
|
||||
return isTxMsgClaimRewards(msg);
|
||||
return true;
|
||||
};
|
||||
|
||||
const msg: TxMsgClaimRewards = {
|
||||
typeUrl: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward",
|
||||
value: { delegatorAddress, validatorAddress },
|
||||
const msgValue = MsgCodecs[MsgTypeUrls.WithdrawDelegatorReward].fromPartial({
|
||||
delegatorAddress,
|
||||
validatorAddress,
|
||||
});
|
||||
|
||||
const msg: MsgWithdrawDelegatorRewardEncodeObject = {
|
||||
typeUrl: MsgTypeUrls.WithdrawDelegatorReward,
|
||||
value: msgValue,
|
||||
};
|
||||
|
||||
setMsgGetter({ isMsgValid, msg });
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Decimal } from "@cosmjs/math";
|
||||
import { EncodeObject } from "@cosmjs/proto-signing";
|
||||
import { assert } from "@cosmjs/utils";
|
||||
import { useEffect, useState } from "react";
|
||||
import { MsgGetter } from "..";
|
||||
import { useAppContext } from "../../../../context/AppContext";
|
||||
import { timestampFromDatetimeLocal } from "../../../../lib/dateHelpers";
|
||||
import { checkAddress, exampleAddress } from "../../../../lib/displayHelpers";
|
||||
import { isTxMsgCreateVestingAccount } from "../../../../lib/txMsgHelpers";
|
||||
import { TxMsg, TxMsgCreateVestingAccount } from "../../../../types/txMsg";
|
||||
import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
|
||||
import Input from "../../../inputs/Input";
|
||||
import StackableContainer from "../../../layout/StackableContainer";
|
||||
|
||||
@@ -66,7 +66,7 @@ const MsgCreateVestingAccountForm = ({
|
||||
setAmountError("");
|
||||
setEndTimeError("");
|
||||
|
||||
const isMsgValid = (msg: TxMsg): msg is TxMsgCreateVestingAccount => {
|
||||
const isMsgValid = (): boolean => {
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
|
||||
const addressErrorMsg = checkAddress(toAddress, state.chain.addressPrefix);
|
||||
@@ -87,23 +87,22 @@ const MsgCreateVestingAccountForm = ({
|
||||
return false;
|
||||
}
|
||||
|
||||
return isTxMsgCreateVestingAccount(msg);
|
||||
return true;
|
||||
};
|
||||
|
||||
const amountInAtomics = amount
|
||||
? Decimal.fromUserInput(amount, Number(state.chain.displayDenomExponent)).atomics
|
||||
: "0";
|
||||
|
||||
const msg: TxMsgCreateVestingAccount = {
|
||||
typeUrl: "/cosmos.vesting.v1beta1.MsgCreateVestingAccount",
|
||||
value: {
|
||||
fromAddress,
|
||||
toAddress,
|
||||
amount: [{ amount: amountInAtomics, denom: state.chain.denom }],
|
||||
endTime: timestampFromDatetimeLocal(endTime),
|
||||
delayed,
|
||||
},
|
||||
};
|
||||
const msgValue = MsgCodecs[MsgTypeUrls.CreateVestingAccount].fromPartial({
|
||||
fromAddress,
|
||||
toAddress,
|
||||
amount: [{ amount: amountInAtomics, denom: state.chain.denom }],
|
||||
endTime: timestampFromDatetimeLocal(endTime),
|
||||
delayed,
|
||||
});
|
||||
|
||||
const msg: EncodeObject = { typeUrl: MsgTypeUrls.CreateVestingAccount, value: msgValue };
|
||||
|
||||
setMsgGetter({ isMsgValid, msg });
|
||||
} catch {}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Decimal } from "@cosmjs/math";
|
||||
import { MsgDelegateEncodeObject } from "@cosmjs/stargate";
|
||||
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 { isTxMsgDelegate } from "../../../../lib/txMsgHelpers";
|
||||
import { TxMsg, TxMsgDelegate } from "../../../../types/txMsg";
|
||||
import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
|
||||
import Input from "../../../inputs/Input";
|
||||
import StackableContainer from "../../../layout/StackableContainer";
|
||||
|
||||
@@ -32,7 +32,7 @@ const MsgDelegateForm = ({ delegatorAddress, setMsgGetter, deleteMsg }: MsgDeleg
|
||||
setValidatorAddressError("");
|
||||
setAmountError("");
|
||||
|
||||
const isMsgValid = (msg: TxMsg): msg is TxMsgDelegate => {
|
||||
const isMsgValid = (): boolean => {
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
|
||||
const addressErrorMsg = checkAddress(validatorAddress, state.chain.addressPrefix);
|
||||
@@ -48,7 +48,7 @@ const MsgDelegateForm = ({ delegatorAddress, setMsgGetter, deleteMsg }: MsgDeleg
|
||||
return false;
|
||||
}
|
||||
|
||||
return isTxMsgDelegate(msg);
|
||||
return true;
|
||||
};
|
||||
|
||||
const amountInAtomics = Decimal.fromUserInput(
|
||||
@@ -56,14 +56,13 @@ const MsgDelegateForm = ({ delegatorAddress, setMsgGetter, deleteMsg }: MsgDeleg
|
||||
Number(state.chain.displayDenomExponent),
|
||||
).atomics;
|
||||
|
||||
const msg: TxMsgDelegate = {
|
||||
typeUrl: "/cosmos.staking.v1beta1.MsgDelegate",
|
||||
value: {
|
||||
delegatorAddress,
|
||||
validatorAddress,
|
||||
amount: { amount: amountInAtomics, denom: state.chain.denom },
|
||||
},
|
||||
};
|
||||
const msgValue = MsgCodecs[MsgTypeUrls.Delegate].fromPartial({
|
||||
delegatorAddress,
|
||||
validatorAddress,
|
||||
amount: { amount: amountInAtomics, denom: state.chain.denom },
|
||||
});
|
||||
|
||||
const msg: MsgDelegateEncodeObject = { typeUrl: MsgTypeUrls.Delegate, value: msgValue };
|
||||
|
||||
setMsgGetter({ isMsgValid, msg });
|
||||
} catch {}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Decimal } from "@cosmjs/math";
|
||||
import { EncodeObject } from "@cosmjs/proto-signing";
|
||||
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 { isTxMsgRedelegate } from "../../../../lib/txMsgHelpers";
|
||||
import { TxMsg, TxMsgRedelegate } from "../../../../types/txMsg";
|
||||
import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
|
||||
import Input from "../../../inputs/Input";
|
||||
import StackableContainer from "../../../layout/StackableContainer";
|
||||
|
||||
@@ -39,7 +39,7 @@ const MsgRedelegateForm = ({
|
||||
setValidatorDstAddressError("");
|
||||
setAmountError("");
|
||||
|
||||
const isMsgValid = (msg: TxMsg): msg is TxMsgRedelegate => {
|
||||
const isMsgValid = (): boolean => {
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
|
||||
const srcAddressErrorMsg = checkAddress(validatorSrcAddress, state.chain.addressPrefix);
|
||||
@@ -63,7 +63,7 @@ const MsgRedelegateForm = ({
|
||||
return false;
|
||||
}
|
||||
|
||||
return isTxMsgRedelegate(msg);
|
||||
return true;
|
||||
};
|
||||
|
||||
const amountInAtomics = Decimal.fromUserInput(
|
||||
@@ -71,15 +71,14 @@ const MsgRedelegateForm = ({
|
||||
Number(state.chain.displayDenomExponent),
|
||||
).atomics;
|
||||
|
||||
const msg: TxMsgRedelegate = {
|
||||
typeUrl: "/cosmos.staking.v1beta1.MsgBeginRedelegate",
|
||||
value: {
|
||||
delegatorAddress,
|
||||
validatorSrcAddress,
|
||||
validatorDstAddress,
|
||||
amount: { amount: amountInAtomics, denom: state.chain.denom },
|
||||
},
|
||||
};
|
||||
const msgValue = MsgCodecs[MsgTypeUrls.BeginRedelegate].fromPartial({
|
||||
delegatorAddress,
|
||||
validatorSrcAddress,
|
||||
validatorDstAddress,
|
||||
amount: { amount: amountInAtomics, denom: state.chain.denom },
|
||||
});
|
||||
|
||||
const msg: EncodeObject = { typeUrl: MsgTypeUrls.BeginRedelegate, value: msgValue };
|
||||
|
||||
setMsgGetter({ isMsgValid, msg });
|
||||
} catch {}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Decimal } from "@cosmjs/math";
|
||||
import { MsgSendEncodeObject } from "@cosmjs/stargate";
|
||||
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 { isTxMsgSend } from "../../../../lib/txMsgHelpers";
|
||||
import { TxMsg, TxMsgSend } from "../../../../types/txMsg";
|
||||
import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
|
||||
import Input from "../../../inputs/Input";
|
||||
import StackableContainer from "../../../layout/StackableContainer";
|
||||
|
||||
@@ -32,7 +32,7 @@ const MsgSendForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgSendFormProps)
|
||||
setToAddressError("");
|
||||
setAmountError("");
|
||||
|
||||
const isMsgValid = (msg: TxMsg): msg is TxMsgSend => {
|
||||
const isMsgValid = (): boolean => {
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
|
||||
const addressErrorMsg = checkAddress(toAddress, state.chain.addressPrefix);
|
||||
@@ -48,21 +48,20 @@ const MsgSendForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgSendFormProps)
|
||||
return false;
|
||||
}
|
||||
|
||||
return isTxMsgSend(msg);
|
||||
return true;
|
||||
};
|
||||
|
||||
const amountInAtomics = amount
|
||||
? Decimal.fromUserInput(amount, Number(state.chain.displayDenomExponent)).atomics
|
||||
: "0";
|
||||
|
||||
const msg: TxMsgSend = {
|
||||
typeUrl: "/cosmos.bank.v1beta1.MsgSend",
|
||||
value: {
|
||||
fromAddress,
|
||||
toAddress,
|
||||
amount: [{ amount: amountInAtomics, denom: state.chain.denom }],
|
||||
},
|
||||
};
|
||||
const msgValue = MsgCodecs[MsgTypeUrls.Send].fromPartial({
|
||||
fromAddress,
|
||||
toAddress,
|
||||
amount: [{ amount: amountInAtomics, denom: state.chain.denom }],
|
||||
});
|
||||
|
||||
const msg: MsgSendEncodeObject = { typeUrl: MsgTypeUrls.Send, value: msgValue };
|
||||
|
||||
setMsgGetter({ isMsgValid, msg });
|
||||
} catch {}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { EncodeObject } from "@cosmjs/proto-signing";
|
||||
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 { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
|
||||
import Input from "../../../inputs/Input";
|
||||
import StackableContainer from "../../../layout/StackableContainer";
|
||||
|
||||
@@ -29,7 +29,7 @@ const MsgSetWithdrawAddressForm = ({
|
||||
try {
|
||||
setWithdrawAddressError("");
|
||||
|
||||
const isMsgValid = (msg: TxMsg): msg is TxMsgSetWithdrawAddress => {
|
||||
const isMsgValid = (): boolean => {
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
|
||||
const addressErrorMsg = checkAddress(withdrawAddress, state.chain.addressPrefix);
|
||||
@@ -40,13 +40,14 @@ const MsgSetWithdrawAddressForm = ({
|
||||
return false;
|
||||
}
|
||||
|
||||
return isTxMsgSetWithdrawAddress(msg);
|
||||
return true;
|
||||
};
|
||||
|
||||
const msg: TxMsgSetWithdrawAddress = {
|
||||
typeUrl: "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress",
|
||||
value: { delegatorAddress, withdrawAddress },
|
||||
};
|
||||
const msgValue = MsgCodecs[MsgTypeUrls.SetWithdrawAddress].fromPartial({
|
||||
delegatorAddress,
|
||||
withdrawAddress,
|
||||
});
|
||||
const msg: EncodeObject = { typeUrl: MsgTypeUrls.SetWithdrawAddress, value: msgValue };
|
||||
|
||||
setMsgGetter({ isMsgValid, msg });
|
||||
} catch {}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { MsgTransferEncodeObject } from "@cosmjs/stargate";
|
||||
import { assert } from "@cosmjs/utils";
|
||||
import Long from "long";
|
||||
import { useEffect, useState } from "react";
|
||||
import { MsgGetter } from "..";
|
||||
import { useAppContext } from "../../../../context/AppContext";
|
||||
import { checkAddress, exampleAddress } from "../../../../lib/displayHelpers";
|
||||
import { isTxMsgTransfer } from "../../../../lib/txMsgHelpers";
|
||||
import { TxMsg, TxMsgTransfer } from "../../../../types/txMsg";
|
||||
import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
|
||||
import Input from "../../../inputs/Input";
|
||||
import StackableContainer from "../../../layout/StackableContainer";
|
||||
|
||||
@@ -54,7 +54,7 @@ const MsgTransferForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgTransferFo
|
||||
setToAddressError("");
|
||||
setTimeoutError("");
|
||||
|
||||
const isMsgValid = (msg: TxMsg): msg is TxMsgTransfer => {
|
||||
const isMsgValid = (): boolean => {
|
||||
if (!sourcePort) {
|
||||
setSourcePortError("Source port is required");
|
||||
return false;
|
||||
@@ -89,7 +89,7 @@ const MsgTransferForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgTransferFo
|
||||
setTimeoutError("Timeout must be a valid timestamp in the future");
|
||||
}
|
||||
|
||||
return isTxMsgTransfer(msg);
|
||||
return true;
|
||||
};
|
||||
|
||||
const timeoutTimestamp = (() => {
|
||||
@@ -105,18 +105,17 @@ const MsgTransferForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgTransferFo
|
||||
}
|
||||
})();
|
||||
|
||||
const msg: TxMsgTransfer = {
|
||||
typeUrl: "/ibc.applications.transfer.v1.MsgTransfer",
|
||||
value: {
|
||||
sender: fromAddress,
|
||||
receiver: toAddress,
|
||||
token: { denom, amount },
|
||||
sourcePort,
|
||||
sourceChannel,
|
||||
timeoutTimestamp,
|
||||
memo,
|
||||
},
|
||||
};
|
||||
const msgValue = MsgCodecs[MsgTypeUrls.Transfer].fromPartial({
|
||||
sender: fromAddress,
|
||||
receiver: toAddress,
|
||||
token: { denom, amount },
|
||||
sourcePort,
|
||||
sourceChannel,
|
||||
timeoutTimestamp,
|
||||
memo,
|
||||
});
|
||||
|
||||
const msg: MsgTransferEncodeObject = { typeUrl: MsgTypeUrls.Transfer, value: msgValue };
|
||||
|
||||
setMsgGetter({ isMsgValid, msg });
|
||||
}, [
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Decimal } from "@cosmjs/math";
|
||||
import { MsgUndelegateEncodeObject } from "@cosmjs/stargate";
|
||||
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 { isTxMsgUndelegate } from "../../../../lib/txMsgHelpers";
|
||||
import { TxMsg, TxMsgUndelegate } from "../../../../types/txMsg";
|
||||
import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
|
||||
import Input from "../../../inputs/Input";
|
||||
import StackableContainer from "../../../layout/StackableContainer";
|
||||
|
||||
@@ -36,7 +36,7 @@ const MsgUndelegateForm = ({
|
||||
setValidatorAddressError("");
|
||||
setAmountError("");
|
||||
|
||||
const isMsgValid = (msg: TxMsg): msg is TxMsgUndelegate => {
|
||||
const isMsgValid = (): boolean => {
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
|
||||
const addressErrorMsg = checkAddress(validatorAddress, state.chain.addressPrefix);
|
||||
@@ -52,7 +52,7 @@ const MsgUndelegateForm = ({
|
||||
return false;
|
||||
}
|
||||
|
||||
return isTxMsgUndelegate(msg);
|
||||
return true;
|
||||
};
|
||||
|
||||
const amountInAtomics = Decimal.fromUserInput(
|
||||
@@ -60,14 +60,13 @@ const MsgUndelegateForm = ({
|
||||
Number(state.chain.displayDenomExponent),
|
||||
).atomics;
|
||||
|
||||
const msg: TxMsgUndelegate = {
|
||||
typeUrl: "/cosmos.staking.v1beta1.MsgUndelegate",
|
||||
value: {
|
||||
delegatorAddress,
|
||||
validatorAddress,
|
||||
amount: { amount: amountInAtomics, denom: state.chain.denom },
|
||||
},
|
||||
};
|
||||
const msgValue = MsgCodecs[MsgTypeUrls.Undelegate].fromPartial({
|
||||
delegatorAddress,
|
||||
validatorAddress,
|
||||
amount: { amount: amountInAtomics, denom: state.chain.denom },
|
||||
});
|
||||
|
||||
const msg: MsgUndelegateEncodeObject = { typeUrl: MsgTypeUrls.Undelegate, value: msgValue };
|
||||
|
||||
setMsgGetter({ isMsgValid, msg });
|
||||
} catch {}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MsgGetter } from "..";
|
||||
import { MsgType } from "../../../../types/txMsg";
|
||||
import { MsgTypeUrl, MsgTypeUrls } from "../../../../types/txMsg";
|
||||
import MsgClaimRewardsForm from "./MsgClaimRewardsForm";
|
||||
import MsgCreateVestingAccountForm from "./MsgCreateVestingAccountForm";
|
||||
import MsgDelegateForm from "./MsgDelegateForm";
|
||||
@@ -10,7 +10,7 @@ import MsgTransferForm from "./MsgTransferForm";
|
||||
import MsgUndelegateForm from "./MsgUndelegateForm";
|
||||
|
||||
interface MsgFormProps {
|
||||
readonly msgType: MsgType;
|
||||
readonly msgType: MsgTypeUrl;
|
||||
readonly senderAddress: string;
|
||||
readonly setMsgGetter: (msgGetter: MsgGetter) => void;
|
||||
readonly deleteMsg: () => void;
|
||||
@@ -18,21 +18,21 @@ interface MsgFormProps {
|
||||
|
||||
const MsgForm = ({ msgType, senderAddress, ...restProps }: MsgFormProps) => {
|
||||
switch (msgType) {
|
||||
case "send":
|
||||
case MsgTypeUrls.Send:
|
||||
return <MsgSendForm fromAddress={senderAddress} {...restProps} />;
|
||||
case "delegate":
|
||||
case MsgTypeUrls.Delegate:
|
||||
return <MsgDelegateForm delegatorAddress={senderAddress} {...restProps} />;
|
||||
case "undelegate":
|
||||
case MsgTypeUrls.Undelegate:
|
||||
return <MsgUndelegateForm delegatorAddress={senderAddress} {...restProps} />;
|
||||
case "redelegate":
|
||||
case MsgTypeUrls.BeginRedelegate:
|
||||
return <MsgRedelegateForm delegatorAddress={senderAddress} {...restProps} />;
|
||||
case "claimRewards":
|
||||
case MsgTypeUrls.WithdrawDelegatorReward:
|
||||
return <MsgClaimRewardsForm delegatorAddress={senderAddress} {...restProps} />;
|
||||
case "setWithdrawAddress":
|
||||
case MsgTypeUrls.SetWithdrawAddress:
|
||||
return <MsgSetWithdrawAddressForm delegatorAddress={senderAddress} {...restProps} />;
|
||||
case "createVestingAccount":
|
||||
case MsgTypeUrls.CreateVestingAccount:
|
||||
return <MsgCreateVestingAccountForm fromAddress={senderAddress} {...restProps} />;
|
||||
case "msgTransfer":
|
||||
case MsgTypeUrls.Transfer:
|
||||
return <MsgTransferForm fromAddress={senderAddress} {...restProps} />;
|
||||
default:
|
||||
return null;
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
import { EncodeObject } from "@cosmjs/proto-signing";
|
||||
import { Account, calculateFee } from "@cosmjs/stargate";
|
||||
import { assert } from "@cosmjs/utils";
|
||||
import axios from "axios";
|
||||
import { NextRouter, withRouter } from "next/router";
|
||||
import { useRef, useState } from "react";
|
||||
import { useAppContext } from "../../../context/AppContext";
|
||||
import { gasOfTx } from "../../../lib/txMsgHelpers";
|
||||
import { MsgType, TxMsg } from "../../../types/txMsg";
|
||||
import { exportMsgToJson, gasOfTx } from "../../../lib/txMsgHelpers";
|
||||
import { DbTransaction } from "../../../types";
|
||||
import { MsgTypeUrl, MsgTypeUrls } from "../../../types/txMsg";
|
||||
import Button from "../../inputs/Button";
|
||||
import Input from "../../inputs/Input";
|
||||
import StackableContainer from "../../layout/StackableContainer";
|
||||
import MsgForm from "./MsgForm";
|
||||
|
||||
export interface MsgGetter {
|
||||
readonly isMsgValid: (msg: TxMsg) => msg is TxMsg;
|
||||
readonly msg: TxMsg;
|
||||
readonly isMsgValid: () => boolean;
|
||||
readonly msg: EncodeObject;
|
||||
}
|
||||
|
||||
interface CreateTxFormProps {
|
||||
@@ -26,7 +28,7 @@ const CreateTxForm = ({ router, senderAddress, accountOnChain }: CreateTxFormPro
|
||||
const { state } = useAppContext();
|
||||
|
||||
const [processing, setProcessing] = useState(false);
|
||||
const [msgTypes, setMsgTypes] = useState<readonly MsgType[]>([]);
|
||||
const [msgTypes, setMsgTypes] = useState<readonly MsgTypeUrl[]>([]);
|
||||
const [msgKeys, setMsgKeys] = useState<readonly string[]>([]);
|
||||
const msgGetters = useRef<MsgGetter[]>([]);
|
||||
const [memo, setMemo] = useState("");
|
||||
@@ -37,7 +39,7 @@ const CreateTxForm = ({ router, senderAddress, accountOnChain }: CreateTxFormPro
|
||||
const gasPrice = state.chain.gasPrice;
|
||||
assert(gasPrice, "gasPrice missing");
|
||||
|
||||
const addMsgType = (newMsgType: MsgType) => {
|
||||
const addMsgType = (newMsgType: MsgTypeUrl) => {
|
||||
setMsgKeys((oldMsgKeys) => [...oldMsgKeys, crypto.randomUUID()]);
|
||||
setMsgTypes((oldMsgTypes) => {
|
||||
const newMsgTypes = [...oldMsgTypes, newMsgType];
|
||||
@@ -52,10 +54,11 @@ const CreateTxForm = ({ router, senderAddress, accountOnChain }: CreateTxFormPro
|
||||
|
||||
assert(typeof accountOnChain.accountNumber === "number", "accountNumber missing");
|
||||
assert(msgGetters.current.length, "form filled incorrectly");
|
||||
assert(state.chain.chainId, "chainId missing");
|
||||
|
||||
const msgs = msgGetters.current
|
||||
.filter(({ isMsgValid, msg }) => isMsgValid(msg))
|
||||
.map(({ msg }) => msg);
|
||||
.filter(({ isMsgValid }) => isMsgValid())
|
||||
.map(({ msg }) => exportMsgToJson(msg));
|
||||
|
||||
if (!msgs.length || msgs.length !== msgTypes.length) return;
|
||||
|
||||
@@ -66,7 +69,7 @@ const CreateTxForm = ({ router, senderAddress, accountOnChain }: CreateTxFormPro
|
||||
|
||||
setProcessing(true);
|
||||
|
||||
const tx = {
|
||||
const tx: DbTransaction = {
|
||||
accountNumber: accountOnChain.accountNumber,
|
||||
sequence: accountOnChain.sequence,
|
||||
chainId: state.chain.chainId,
|
||||
@@ -112,7 +115,7 @@ const CreateTxForm = ({ router, senderAddress, accountOnChain }: CreateTxFormPro
|
||||
...oldMsgKeys.slice(index + 1),
|
||||
]);
|
||||
setMsgTypes((oldMsgTypes) => {
|
||||
const newMsgTypes: MsgType[] = oldMsgTypes.slice();
|
||||
const newMsgTypes: MsgTypeUrl[] = oldMsgTypes.slice();
|
||||
newMsgTypes.splice(index, 1);
|
||||
setGasLimit(gasOfTx(newMsgTypes));
|
||||
return newMsgTypes;
|
||||
@@ -147,20 +150,26 @@ const CreateTxForm = ({ router, senderAddress, accountOnChain }: CreateTxFormPro
|
||||
/>
|
||||
</div>
|
||||
<StackableContainer>
|
||||
<Button label="Add MsgSend" onClick={() => addMsgType("send")} />
|
||||
<Button label="Add MsgDelegate" onClick={() => addMsgType("delegate")} />
|
||||
<Button label="Add MsgUndelegate" onClick={() => addMsgType("undelegate")} />
|
||||
<Button label="Add MsgBeginRedelegate" onClick={() => addMsgType("redelegate")} />
|
||||
<Button label="Add MsgWithdrawDelegatorReward" onClick={() => addMsgType("claimRewards")} />
|
||||
<Button label="Add MsgSend" onClick={() => addMsgType(MsgTypeUrls.Send)} />
|
||||
<Button label="Add MsgDelegate" onClick={() => addMsgType(MsgTypeUrls.Delegate)} />
|
||||
<Button label="Add MsgUndelegate" onClick={() => addMsgType(MsgTypeUrls.Undelegate)} />
|
||||
<Button
|
||||
label="Add MsgBeginRedelegate"
|
||||
onClick={() => addMsgType(MsgTypeUrls.BeginRedelegate)}
|
||||
/>
|
||||
<Button
|
||||
label="Add MsgWithdrawDelegatorReward"
|
||||
onClick={() => addMsgType(MsgTypeUrls.WithdrawDelegatorReward)}
|
||||
/>
|
||||
<Button
|
||||
label="Add MsgSetWithdrawAddress"
|
||||
onClick={() => addMsgType("setWithdrawAddress")}
|
||||
onClick={() => addMsgType(MsgTypeUrls.SetWithdrawAddress)}
|
||||
/>
|
||||
<Button
|
||||
label="Add MsgCreateVestingAccount"
|
||||
onClick={() => addMsgType("createVestingAccount")}
|
||||
onClick={() => addMsgType(MsgTypeUrls.CreateVestingAccount)}
|
||||
/>
|
||||
<Button label="Add MsgTransfer" onClick={() => addMsgType("msgTransfer")} />
|
||||
<Button label="Add MsgTransfer" onClick={() => addMsgType(MsgTypeUrls.Transfer)} />
|
||||
</StackableContainer>
|
||||
{showCreateTxError ? (
|
||||
<StackableContainer lessMargin lessPadding>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MultisigThresholdPubkey, makeCosmoshubPath } from "@cosmjs/amino";
|
||||
import { toBase64, toHex } from "@cosmjs/encoding";
|
||||
import { toBase64 } from "@cosmjs/encoding";
|
||||
import { LedgerSigner } from "@cosmjs/ledger-amino";
|
||||
import { SigningStargateClient } from "@cosmjs/stargate";
|
||||
import { assert } from "@cosmjs/utils";
|
||||
@@ -155,8 +155,6 @@ const TransactionSigning = (props: Props) => {
|
||||
chainId: state.chain.chainId,
|
||||
};
|
||||
|
||||
console.log({ msgs: props.tx.msgs });
|
||||
|
||||
const { bodyBytes, signatures } = await signingClient.sign(
|
||||
signerAddress,
|
||||
props.tx.msgs,
|
||||
@@ -165,8 +163,6 @@ const TransactionSigning = (props: Props) => {
|
||||
signerData,
|
||||
);
|
||||
|
||||
console.log({ bodyBytes: toHex(bodyBytes) });
|
||||
|
||||
// check existing signatures
|
||||
const bases64EncodedSignature = toBase64(signatures[0]);
|
||||
const bases64EncodedBodyBytes = toBase64(bodyBytes);
|
||||
|
||||
+31
-138
@@ -1,153 +1,60 @@
|
||||
import { EncodeObject } from "@cosmjs/proto-signing";
|
||||
import Long from "long";
|
||||
import { DbTransaction } from "../types";
|
||||
import {
|
||||
MsgType,
|
||||
TxMsg,
|
||||
TxMsgClaimRewards,
|
||||
TxMsgCreateVestingAccount,
|
||||
TxMsgDelegate,
|
||||
TxMsgRedelegate,
|
||||
TxMsgSend,
|
||||
TxMsgSetWithdrawAddress,
|
||||
TxMsgTransfer,
|
||||
TxMsgUndelegate,
|
||||
} from "../types/txMsg";
|
||||
import { MsgCodecs, MsgTypeUrl, MsgTypeUrls } from "../types/txMsg";
|
||||
|
||||
const isTxMsgSend = (msg: TxMsg | EncodeObject): msg is TxMsgSend =>
|
||||
msg.typeUrl === "/cosmos.bank.v1beta1.MsgSend" &&
|
||||
"value" in msg &&
|
||||
"fromAddress" in msg.value &&
|
||||
"toAddress" in msg.value &&
|
||||
"amount" in msg.value &&
|
||||
!!msg.value.fromAddress &&
|
||||
!!msg.value.toAddress &&
|
||||
!!msg.value.amount.length;
|
||||
|
||||
const isTxMsgDelegate = (msg: TxMsg | EncodeObject): msg is TxMsgDelegate =>
|
||||
msg.typeUrl === "/cosmos.staking.v1beta1.MsgDelegate" &&
|
||||
"value" in msg &&
|
||||
"delegatorAddress" in msg.value &&
|
||||
"validatorAddress" in msg.value &&
|
||||
"amount" in msg.value &&
|
||||
!!msg.value.delegatorAddress &&
|
||||
!!msg.value.validatorAddress &&
|
||||
!!msg.value.amount;
|
||||
|
||||
const isTxMsgUndelegate = (msg: TxMsg | EncodeObject): msg is TxMsgUndelegate =>
|
||||
msg.typeUrl === "/cosmos.staking.v1beta1.MsgUndelegate" &&
|
||||
"value" in msg &&
|
||||
"delegatorAddress" in msg.value &&
|
||||
"validatorAddress" in msg.value &&
|
||||
"amount" in msg.value &&
|
||||
!!msg.value.delegatorAddress &&
|
||||
!!msg.value.validatorAddress &&
|
||||
!!msg.value.amount;
|
||||
|
||||
const isTxMsgRedelegate = (msg: TxMsg | EncodeObject): msg is TxMsgRedelegate =>
|
||||
msg.typeUrl === "/cosmos.staking.v1beta1.MsgBeginRedelegate" &&
|
||||
"value" in msg &&
|
||||
"delegatorAddress" in msg.value &&
|
||||
"validatorSrcAddress" in msg.value &&
|
||||
"validatorDstAddress" in msg.value &&
|
||||
"amount" in msg.value &&
|
||||
!!msg.value.delegatorAddress &&
|
||||
!!msg.value.validatorSrcAddress &&
|
||||
!!msg.value.validatorDstAddress &&
|
||||
!!msg.value.amount;
|
||||
|
||||
const isTxMsgClaimRewards = (msg: TxMsg | EncodeObject): msg is TxMsgClaimRewards =>
|
||||
msg.typeUrl === "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward" &&
|
||||
"value" in msg &&
|
||||
"delegatorAddress" in msg.value &&
|
||||
"validatorAddress" in msg.value &&
|
||||
!!msg.value.delegatorAddress &&
|
||||
!!msg.value.validatorAddress;
|
||||
|
||||
const isTxMsgSetWithdrawAddress = (msg: TxMsg | EncodeObject): msg is TxMsgSetWithdrawAddress =>
|
||||
msg.typeUrl === "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress" &&
|
||||
"value" in msg &&
|
||||
"delegatorAddress" in msg.value &&
|
||||
"withdrawAddress" in msg.value &&
|
||||
!!msg.value.delegatorAddress &&
|
||||
!!msg.value.withdrawAddress;
|
||||
|
||||
const isTxMsgCreateVestingAccount = (msg: TxMsg | EncodeObject): msg is TxMsgCreateVestingAccount =>
|
||||
msg.typeUrl === "/cosmos.vesting.v1beta1.MsgCreateVestingAccount" &&
|
||||
"value" in msg &&
|
||||
"fromAddress" in msg.value &&
|
||||
"toAddress" in msg.value &&
|
||||
"amount" in msg.value &&
|
||||
"endTime" in msg.value &&
|
||||
"delayed" in msg.value &&
|
||||
!!msg.value.fromAddress &&
|
||||
!!msg.value.toAddress &&
|
||||
!!msg.value.amount.length &&
|
||||
!!msg.value.endTime &&
|
||||
typeof msg.value.delayed === "boolean";
|
||||
|
||||
const isTxMsgTransfer = (msg: TxMsg | EncodeObject): msg is TxMsgTransfer =>
|
||||
msg.typeUrl === "/ibc.applications.transfer.v1.MsgTransfer" &&
|
||||
"value" in msg &&
|
||||
"sourcePort" in msg.value &&
|
||||
"sourceChannel" in msg.value &&
|
||||
"sender" in msg.value &&
|
||||
"receiver" in msg.value &&
|
||||
!!msg.value.sourcePort &&
|
||||
!!msg.value.sourceChannel &&
|
||||
!!msg.value.sender &&
|
||||
!!msg.value.receiver;
|
||||
|
||||
const gasOfMsg = (msgType: MsgType): number => {
|
||||
const gasOfMsg = (msgType: MsgTypeUrl): number => {
|
||||
switch (msgType) {
|
||||
case "send":
|
||||
case MsgTypeUrls.Send:
|
||||
return 100_000;
|
||||
case "delegate":
|
||||
case MsgTypeUrls.SetWithdrawAddress:
|
||||
return 100_000;
|
||||
case "undelegate":
|
||||
case MsgTypeUrls.WithdrawDelegatorReward:
|
||||
return 100_000;
|
||||
case "redelegate":
|
||||
case MsgTypeUrls.BeginRedelegate:
|
||||
return 150_000;
|
||||
case MsgTypeUrls.Delegate:
|
||||
return 150_000;
|
||||
case MsgTypeUrls.Undelegate:
|
||||
return 150_000;
|
||||
case MsgTypeUrls.CreateVestingAccount:
|
||||
return 100_000;
|
||||
case "claimRewards":
|
||||
return 100_000;
|
||||
case "setWithdrawAddress":
|
||||
return 100_000;
|
||||
case "createVestingAccount":
|
||||
return 100_000;
|
||||
case "msgTransfer":
|
||||
case MsgTypeUrls.Transfer:
|
||||
return 100_000;
|
||||
default:
|
||||
throw new Error("Unknown msg type");
|
||||
}
|
||||
};
|
||||
|
||||
const gasOfTx = (msgTypes: readonly MsgType[]): number => {
|
||||
export const gasOfTx = (msgTypes: readonly MsgTypeUrl[]): number => {
|
||||
const txFlatGas = 100_000;
|
||||
const totalTxGas = msgTypes.reduce((acc, msgType) => acc + gasOfMsg(msgType), txFlatGas);
|
||||
return totalTxGas;
|
||||
};
|
||||
|
||||
const importMsgType = (msg: EncodeObject): EncodeObject => {
|
||||
if (isTxMsgCreateVestingAccount(msg)) {
|
||||
return { ...msg, value: { ...msg.value, endTime: Long.fromValue(msg.value.endTime) } };
|
||||
export const isKnownMsgTypeUrl = (typeUrl: string): typeUrl is MsgTypeUrl =>
|
||||
Object.values(MsgTypeUrls).includes(typeUrl as MsgTypeUrl);
|
||||
|
||||
export const exportMsgToJson = (msg: EncodeObject): EncodeObject => {
|
||||
if (isKnownMsgTypeUrl(msg.typeUrl)) {
|
||||
return { ...msg, value: MsgCodecs[msg.typeUrl].toJSON(msg.value) };
|
||||
}
|
||||
|
||||
if (isTxMsgTransfer(msg)) {
|
||||
return {
|
||||
...msg,
|
||||
value: { ...msg.value, timeoutTimestamp: Long.fromValue(msg.value.timeoutTimestamp) },
|
||||
};
|
||||
}
|
||||
|
||||
return msg;
|
||||
throw new Error("Unknown msg type");
|
||||
};
|
||||
|
||||
const importMsgTypes = (msgs: readonly EncodeObject[]): EncodeObject[] => msgs.map(importMsgType);
|
||||
const importMsgFromJson = (msg: EncodeObject): EncodeObject => {
|
||||
if (isKnownMsgTypeUrl(msg.typeUrl)) {
|
||||
const parsedValue = MsgCodecs[msg.typeUrl].fromJSON(msg.value);
|
||||
return { ...msg, value: parsedValue };
|
||||
}
|
||||
|
||||
const dbTxFromJson = (txJson: string): DbTransaction | null => {
|
||||
throw new Error("Unknown msg type");
|
||||
};
|
||||
|
||||
export const dbTxFromJson = (txJson: string): DbTransaction | null => {
|
||||
try {
|
||||
const dbTx: DbTransaction = JSON.parse(txJson);
|
||||
dbTx.msgs = importMsgTypes(dbTx.msgs);
|
||||
dbTx.msgs = dbTx.msgs.map(importMsgFromJson);
|
||||
|
||||
return dbTx;
|
||||
} catch (error) {
|
||||
@@ -160,17 +67,3 @@ const dbTxFromJson = (txJson: string): DbTransaction | null => {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export {
|
||||
isTxMsgSend,
|
||||
isTxMsgDelegate,
|
||||
isTxMsgUndelegate,
|
||||
isTxMsgRedelegate,
|
||||
isTxMsgClaimRewards,
|
||||
isTxMsgSetWithdrawAddress,
|
||||
isTxMsgCreateVestingAccount,
|
||||
isTxMsgTransfer,
|
||||
gasOfMsg,
|
||||
gasOfTx,
|
||||
dbTxFromJson,
|
||||
};
|
||||
|
||||
+30
-59
@@ -1,65 +1,36 @@
|
||||
import { MsgSend } from "cosmjs-types/cosmos/bank/v1beta1/tx";
|
||||
import { MsgSetWithdrawAddress, MsgWithdrawDelegatorReward } from "cosmjs-types/cosmos/distribution/v1beta1/tx";
|
||||
import { MsgBeginRedelegate, MsgDelegate, MsgUndelegate } from "cosmjs-types/cosmos/staking/v1beta1/tx";
|
||||
import {
|
||||
MsgSetWithdrawAddress,
|
||||
MsgWithdrawDelegatorReward,
|
||||
} from "cosmjs-types/cosmos/distribution/v1beta1/tx";
|
||||
import {
|
||||
MsgBeginRedelegate,
|
||||
MsgDelegate,
|
||||
MsgUndelegate,
|
||||
} from "cosmjs-types/cosmos/staking/v1beta1/tx";
|
||||
import { MsgCreateVestingAccount } from "cosmjs-types/cosmos/vesting/v1beta1/tx";
|
||||
import { MsgTransfer } from "cosmjs-types/ibc/applications/transfer/v1/tx";
|
||||
|
||||
export type MsgType =
|
||||
| "send"
|
||||
| "delegate"
|
||||
| "undelegate"
|
||||
| "redelegate"
|
||||
| "claimRewards"
|
||||
| "setWithdrawAddress"
|
||||
| "createVestingAccount"
|
||||
| "msgTransfer";
|
||||
export const MsgTypeUrls = {
|
||||
Send: "/cosmos.bank.v1beta1.MsgSend",
|
||||
SetWithdrawAddress: "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress",
|
||||
WithdrawDelegatorReward: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward",
|
||||
BeginRedelegate: "/cosmos.staking.v1beta1.MsgBeginRedelegate",
|
||||
Delegate: "/cosmos.staking.v1beta1.MsgDelegate",
|
||||
Undelegate: "/cosmos.staking.v1beta1.MsgUndelegate",
|
||||
CreateVestingAccount: "/cosmos.vesting.v1beta1.MsgCreateVestingAccount",
|
||||
Transfer: "/ibc.applications.transfer.v1.MsgTransfer",
|
||||
} as const;
|
||||
|
||||
export type TxMsg =
|
||||
| TxMsgSend
|
||||
| TxMsgDelegate
|
||||
| TxMsgUndelegate
|
||||
| TxMsgRedelegate
|
||||
| TxMsgClaimRewards
|
||||
| TxMsgSetWithdrawAddress
|
||||
| TxMsgCreateVestingAccount
|
||||
| TxMsgTransfer;
|
||||
export type MsgTypeUrl = (typeof MsgTypeUrls)[keyof typeof MsgTypeUrls];
|
||||
|
||||
export interface TxMsgSend {
|
||||
readonly typeUrl: "/cosmos.bank.v1beta1.MsgSend";
|
||||
readonly value: MsgSend;
|
||||
}
|
||||
|
||||
export interface TxMsgDelegate {
|
||||
readonly typeUrl: "/cosmos.staking.v1beta1.MsgDelegate";
|
||||
readonly value: MsgDelegate;
|
||||
}
|
||||
|
||||
export interface TxMsgUndelegate {
|
||||
readonly typeUrl: "/cosmos.staking.v1beta1.MsgUndelegate";
|
||||
readonly value: MsgUndelegate;
|
||||
}
|
||||
|
||||
export interface TxMsgRedelegate {
|
||||
readonly typeUrl: "/cosmos.staking.v1beta1.MsgBeginRedelegate";
|
||||
readonly value: MsgBeginRedelegate;
|
||||
}
|
||||
|
||||
export interface TxMsgClaimRewards {
|
||||
readonly typeUrl: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward";
|
||||
readonly value: MsgWithdrawDelegatorReward;
|
||||
}
|
||||
|
||||
export interface TxMsgSetWithdrawAddress {
|
||||
readonly typeUrl: "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress";
|
||||
readonly value: MsgSetWithdrawAddress;
|
||||
}
|
||||
|
||||
export interface TxMsgCreateVestingAccount {
|
||||
readonly typeUrl: "/cosmos.vesting.v1beta1.MsgCreateVestingAccount";
|
||||
readonly value: MsgCreateVestingAccount;
|
||||
}
|
||||
|
||||
export interface TxMsgTransfer {
|
||||
readonly typeUrl: "/ibc.applications.transfer.v1.MsgTransfer";
|
||||
readonly value: MsgTransfer;
|
||||
}
|
||||
export const MsgCodecs = {
|
||||
[MsgTypeUrls.Send]: MsgSend,
|
||||
[MsgTypeUrls.SetWithdrawAddress]: MsgSetWithdrawAddress,
|
||||
[MsgTypeUrls.WithdrawDelegatorReward]: MsgWithdrawDelegatorReward,
|
||||
[MsgTypeUrls.BeginRedelegate]: MsgBeginRedelegate,
|
||||
[MsgTypeUrls.Delegate]: MsgDelegate,
|
||||
[MsgTypeUrls.Undelegate]: MsgUndelegate,
|
||||
[MsgTypeUrls.CreateVestingAccount]: MsgCreateVestingAccount,
|
||||
[MsgTypeUrls.Transfer]: MsgTransfer,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user