Use new hook in forms
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
import { MsgWithdrawDelegatorRewardEncodeObject } from "@cosmjs/stargate";
|
||||
import { assert } from "@cosmjs/utils";
|
||||
import { useEffect, useState } from "react";
|
||||
import { MsgGetter } from "..";
|
||||
import { useAppContext } from "../../../../context/AppContext";
|
||||
import { useChains } from "../../../../context/ChainsContext";
|
||||
import { checkAddress, exampleAddress } from "../../../../lib/displayHelpers";
|
||||
import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
|
||||
import Input from "../../../inputs/Input";
|
||||
@@ -19,8 +18,7 @@ const MsgClaimRewardsForm = ({
|
||||
setMsgGetter,
|
||||
deleteMsg,
|
||||
}: MsgClaimRewardsFormProps) => {
|
||||
const { state } = useAppContext();
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
const { chain } = useChains();
|
||||
|
||||
const [validatorAddress, setValidatorAddress] = useState("");
|
||||
const [validatorAddressError, setValidatorAddressError] = useState("");
|
||||
@@ -30,12 +28,10 @@ const MsgClaimRewardsForm = ({
|
||||
setValidatorAddressError("");
|
||||
|
||||
const isMsgValid = (): boolean => {
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
|
||||
const addressErrorMsg = checkAddress(validatorAddress, state.chain.addressPrefix);
|
||||
const addressErrorMsg = checkAddress(validatorAddress, chain.addressPrefix);
|
||||
if (addressErrorMsg) {
|
||||
setValidatorAddressError(
|
||||
`Invalid address for network ${state.chain.chainId}: ${addressErrorMsg}`,
|
||||
`Invalid address for network ${chain.chainId}: ${addressErrorMsg}`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@@ -55,13 +51,7 @@ const MsgClaimRewardsForm = ({
|
||||
|
||||
setMsgGetter({ isMsgValid, msg });
|
||||
} catch {}
|
||||
}, [
|
||||
delegatorAddress,
|
||||
setMsgGetter,
|
||||
state.chain.addressPrefix,
|
||||
state.chain.chainId,
|
||||
validatorAddress,
|
||||
]);
|
||||
}, [chain.addressPrefix, chain.chainId, delegatorAddress, setMsgGetter, validatorAddress]);
|
||||
|
||||
return (
|
||||
<StackableContainer lessPadding lessMargin>
|
||||
@@ -76,7 +66,7 @@ const MsgClaimRewardsForm = ({
|
||||
value={validatorAddress}
|
||||
onChange={({ target }) => setValidatorAddress(target.value)}
|
||||
error={validatorAddressError}
|
||||
placeholder={`E.g. ${exampleAddress(0, state.chain.addressPrefix)}`}
|
||||
placeholder={`E.g. ${exampleAddress(0, chain.addressPrefix)}`}
|
||||
/>
|
||||
</div>
|
||||
<style jsx>{`
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
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 { useChains } from "../../../../context/ChainsContext";
|
||||
import {
|
||||
datetimeLocalFromTimestamp,
|
||||
timestampFromDatetimeLocal,
|
||||
@@ -24,8 +23,7 @@ const MsgCreateVestingAccountForm = ({
|
||||
setMsgGetter,
|
||||
deleteMsg,
|
||||
}: MsgCreateVestingAccountFormProps) => {
|
||||
const { state } = useAppContext();
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
const { chain } = useChains();
|
||||
|
||||
const [toAddress, setToAddress] = useState("");
|
||||
const [amount, setAmount] = useState("0");
|
||||
@@ -40,20 +38,14 @@ const MsgCreateVestingAccountForm = ({
|
||||
|
||||
useEffect(() => {
|
||||
try {
|
||||
assert(state.chain.denom, "denom missing");
|
||||
|
||||
setToAddressError("");
|
||||
setAmountError("");
|
||||
setEndTimeError("");
|
||||
|
||||
const isMsgValid = (): boolean => {
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
|
||||
const addressErrorMsg = checkAddress(toAddress, state.chain.addressPrefix);
|
||||
const addressErrorMsg = checkAddress(toAddress, chain.addressPrefix);
|
||||
if (addressErrorMsg) {
|
||||
setToAddressError(
|
||||
`Invalid address for network ${state.chain.chainId}: ${addressErrorMsg}`,
|
||||
);
|
||||
setToAddressError(`Invalid address for network ${chain.chainId}: ${addressErrorMsg}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -72,13 +64,13 @@ const MsgCreateVestingAccountForm = ({
|
||||
};
|
||||
|
||||
const amountInAtomics = amount
|
||||
? Decimal.fromUserInput(amount, Number(state.chain.displayDenomExponent)).atomics
|
||||
? Decimal.fromUserInput(amount, Number(chain.displayDenomExponent)).atomics
|
||||
: "0";
|
||||
|
||||
const msgValue = MsgCodecs[MsgTypeUrls.CreateVestingAccount].fromPartial({
|
||||
fromAddress,
|
||||
toAddress,
|
||||
amount: [{ amount: amountInAtomics, denom: state.chain.denom }],
|
||||
amount: [{ amount: amountInAtomics, denom: chain.denom }],
|
||||
endTime: timestampFromDatetimeLocal(endTime, "s"),
|
||||
delayed,
|
||||
});
|
||||
@@ -89,14 +81,14 @@ const MsgCreateVestingAccountForm = ({
|
||||
} catch {}
|
||||
}, [
|
||||
amount,
|
||||
chain.addressPrefix,
|
||||
chain.chainId,
|
||||
chain.denom,
|
||||
chain.displayDenomExponent,
|
||||
delayed,
|
||||
endTime,
|
||||
fromAddress,
|
||||
setMsgGetter,
|
||||
state.chain.addressPrefix,
|
||||
state.chain.chainId,
|
||||
state.chain.denom,
|
||||
state.chain.displayDenomExponent,
|
||||
toAddress,
|
||||
]);
|
||||
|
||||
@@ -113,13 +105,13 @@ const MsgCreateVestingAccountForm = ({
|
||||
value={toAddress}
|
||||
onChange={({ target }) => setToAddress(target.value)}
|
||||
error={toAddressError}
|
||||
placeholder={`E.g. ${exampleAddress(0, state.chain.addressPrefix)}`}
|
||||
placeholder={`E.g. ${exampleAddress(0, chain.addressPrefix)}`}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-item">
|
||||
<Input
|
||||
type="number"
|
||||
label={`Amount (${state.chain.displayDenom})`}
|
||||
label={`Amount (${chain.displayDenom})`}
|
||||
name="amount"
|
||||
value={amount}
|
||||
onChange={({ target }) => setAmount(target.value)}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
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 { useChains } from "../../../../context/ChainsContext";
|
||||
import { checkAddress, exampleAddress } from "../../../../lib/displayHelpers";
|
||||
import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
|
||||
import Input from "../../../inputs/Input";
|
||||
@@ -16,8 +15,7 @@ interface MsgDelegateFormProps {
|
||||
}
|
||||
|
||||
const MsgDelegateForm = ({ delegatorAddress, setMsgGetter, deleteMsg }: MsgDelegateFormProps) => {
|
||||
const { state } = useAppContext();
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
const { chain } = useChains();
|
||||
|
||||
const [validatorAddress, setValidatorAddress] = useState("");
|
||||
const [amount, setAmount] = useState("0");
|
||||
@@ -27,18 +25,14 @@ const MsgDelegateForm = ({ delegatorAddress, setMsgGetter, deleteMsg }: MsgDeleg
|
||||
|
||||
useEffect(() => {
|
||||
try {
|
||||
assert(state.chain.denom, "denom missing");
|
||||
|
||||
setValidatorAddressError("");
|
||||
setAmountError("");
|
||||
|
||||
const isMsgValid = (): boolean => {
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
|
||||
const addressErrorMsg = checkAddress(validatorAddress, state.chain.addressPrefix);
|
||||
const addressErrorMsg = checkAddress(validatorAddress, chain.addressPrefix);
|
||||
if (addressErrorMsg) {
|
||||
setValidatorAddressError(
|
||||
`Invalid address for network ${state.chain.chainId}: ${addressErrorMsg}`,
|
||||
`Invalid address for network ${chain.chainId}: ${addressErrorMsg}`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@@ -53,13 +47,13 @@ const MsgDelegateForm = ({ delegatorAddress, setMsgGetter, deleteMsg }: MsgDeleg
|
||||
|
||||
const amountInAtomics = Decimal.fromUserInput(
|
||||
amount || "0",
|
||||
Number(state.chain.displayDenomExponent),
|
||||
Number(chain.displayDenomExponent),
|
||||
).atomics;
|
||||
|
||||
const msgValue = MsgCodecs[MsgTypeUrls.Delegate].fromPartial({
|
||||
delegatorAddress,
|
||||
validatorAddress,
|
||||
amount: { amount: amountInAtomics, denom: state.chain.denom },
|
||||
amount: { amount: amountInAtomics, denom: chain.denom },
|
||||
});
|
||||
|
||||
const msg: MsgDelegateEncodeObject = { typeUrl: MsgTypeUrls.Delegate, value: msgValue };
|
||||
@@ -68,12 +62,12 @@ const MsgDelegateForm = ({ delegatorAddress, setMsgGetter, deleteMsg }: MsgDeleg
|
||||
} catch {}
|
||||
}, [
|
||||
amount,
|
||||
chain.addressPrefix,
|
||||
chain.chainId,
|
||||
chain.denom,
|
||||
chain.displayDenomExponent,
|
||||
delegatorAddress,
|
||||
setMsgGetter,
|
||||
state.chain.addressPrefix,
|
||||
state.chain.chainId,
|
||||
state.chain.denom,
|
||||
state.chain.displayDenomExponent,
|
||||
validatorAddress,
|
||||
]);
|
||||
|
||||
@@ -90,13 +84,13 @@ const MsgDelegateForm = ({ delegatorAddress, setMsgGetter, deleteMsg }: MsgDeleg
|
||||
value={validatorAddress}
|
||||
onChange={({ target }) => setValidatorAddress(target.value)}
|
||||
error={validatorAddressError}
|
||||
placeholder={`E.g. ${exampleAddress(0, state.chain.addressPrefix)}`}
|
||||
placeholder={`E.g. ${exampleAddress(0, chain.addressPrefix)}`}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-item">
|
||||
<Input
|
||||
type="number"
|
||||
label={`Amount (${state.chain.displayDenom})`}
|
||||
label={`Amount (${chain.displayDenom})`}
|
||||
name="amount"
|
||||
value={amount}
|
||||
onChange={({ target }) => setAmount(target.value)}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
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 { useChains } from "../../../../context/ChainsContext";
|
||||
import { checkAddress, exampleAddress } from "../../../../lib/displayHelpers";
|
||||
import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
|
||||
import Input from "../../../inputs/Input";
|
||||
@@ -20,8 +19,7 @@ const MsgRedelegateForm = ({
|
||||
setMsgGetter,
|
||||
deleteMsg,
|
||||
}: MsgRedelegateFormProps) => {
|
||||
const { state } = useAppContext();
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
const { chain } = useChains();
|
||||
|
||||
const [validatorSrcAddress, setValidatorSrcAddress] = useState("");
|
||||
const [validatorDstAddress, setValidatorDstAddress] = useState("");
|
||||
@@ -33,27 +31,23 @@ const MsgRedelegateForm = ({
|
||||
|
||||
useEffect(() => {
|
||||
try {
|
||||
assert(state.chain.denom, "denom missing");
|
||||
|
||||
setValidatorSrcAddressError("");
|
||||
setValidatorDstAddressError("");
|
||||
setAmountError("");
|
||||
|
||||
const isMsgValid = (): boolean => {
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
|
||||
const srcAddressErrorMsg = checkAddress(validatorSrcAddress, state.chain.addressPrefix);
|
||||
const srcAddressErrorMsg = checkAddress(validatorSrcAddress, chain.addressPrefix);
|
||||
if (srcAddressErrorMsg) {
|
||||
setValidatorSrcAddressError(
|
||||
`Invalid address for network ${state.chain.chainId}: ${srcAddressErrorMsg}`,
|
||||
`Invalid address for network ${chain.chainId}: ${srcAddressErrorMsg}`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
const dstAddressErrorMsg = checkAddress(validatorDstAddress, state.chain.addressPrefix);
|
||||
const dstAddressErrorMsg = checkAddress(validatorDstAddress, chain.addressPrefix);
|
||||
if (dstAddressErrorMsg) {
|
||||
setValidatorDstAddressError(
|
||||
`Invalid address for network ${state.chain.chainId}: ${dstAddressErrorMsg}`,
|
||||
`Invalid address for network ${chain.chainId}: ${dstAddressErrorMsg}`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@@ -68,14 +62,14 @@ const MsgRedelegateForm = ({
|
||||
|
||||
const amountInAtomics = Decimal.fromUserInput(
|
||||
amount || "0",
|
||||
Number(state.chain.displayDenomExponent),
|
||||
Number(chain.displayDenomExponent),
|
||||
).atomics;
|
||||
|
||||
const msgValue = MsgCodecs[MsgTypeUrls.BeginRedelegate].fromPartial({
|
||||
delegatorAddress,
|
||||
validatorSrcAddress,
|
||||
validatorDstAddress,
|
||||
amount: { amount: amountInAtomics, denom: state.chain.denom },
|
||||
amount: { amount: amountInAtomics, denom: chain.denom },
|
||||
});
|
||||
|
||||
const msg: EncodeObject = { typeUrl: MsgTypeUrls.BeginRedelegate, value: msgValue };
|
||||
@@ -84,12 +78,12 @@ const MsgRedelegateForm = ({
|
||||
} catch {}
|
||||
}, [
|
||||
amount,
|
||||
chain.addressPrefix,
|
||||
chain.chainId,
|
||||
chain.denom,
|
||||
chain.displayDenomExponent,
|
||||
delegatorAddress,
|
||||
setMsgGetter,
|
||||
state.chain.addressPrefix,
|
||||
state.chain.chainId,
|
||||
state.chain.denom,
|
||||
state.chain.displayDenomExponent,
|
||||
validatorDstAddress,
|
||||
validatorSrcAddress,
|
||||
]);
|
||||
@@ -107,7 +101,7 @@ const MsgRedelegateForm = ({
|
||||
value={validatorSrcAddress}
|
||||
onChange={({ target }) => setValidatorSrcAddress(target.value)}
|
||||
error={validatorSrcAddressError}
|
||||
placeholder={`E.g. ${exampleAddress(0, state.chain.addressPrefix)}`}
|
||||
placeholder={`E.g. ${exampleAddress(0, chain.addressPrefix)}`}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-item">
|
||||
@@ -117,13 +111,13 @@ const MsgRedelegateForm = ({
|
||||
value={validatorDstAddress}
|
||||
onChange={({ target }) => setValidatorDstAddress(target.value)}
|
||||
error={validatorDstAddressError}
|
||||
placeholder={`E.g. ${exampleAddress(0, state.chain.addressPrefix)}`}
|
||||
placeholder={`E.g. ${exampleAddress(0, chain.addressPrefix)}`}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-item">
|
||||
<Input
|
||||
type="number"
|
||||
label={`Amount (${state.chain.displayDenom})`}
|
||||
label={`Amount (${chain.displayDenom})`}
|
||||
name="amount"
|
||||
value={amount}
|
||||
onChange={({ target }) => setAmount(target.value)}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
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 { useChains } from "../../../../context/ChainsContext";
|
||||
import { checkAddress, exampleAddress } from "../../../../lib/displayHelpers";
|
||||
import { ChainInfo } from "../../../../types";
|
||||
import { RegistryAsset } from "../../../../types/chainRegistry";
|
||||
import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
|
||||
import Input from "../../../inputs/Input";
|
||||
import Select from "../../../inputs/Select";
|
||||
@@ -13,7 +12,7 @@ import StackableContainer from "../../../layout/StackableContainer";
|
||||
|
||||
const customDenomOption = { label: "Custom (enter denom below)", value: "custom" } as const;
|
||||
|
||||
const getDenomOptions = (assets: ChainInfo["assets"]) => {
|
||||
const getDenomOptions = (assets: readonly RegistryAsset[]) => {
|
||||
if (!assets?.length) {
|
||||
return [customDenomOption];
|
||||
}
|
||||
@@ -28,10 +27,9 @@ interface MsgSendFormProps {
|
||||
}
|
||||
|
||||
const MsgSendForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgSendFormProps) => {
|
||||
const { state } = useAppContext();
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
const { chain } = useChains();
|
||||
|
||||
const denomOptions = getDenomOptions(state.chain.assets);
|
||||
const denomOptions = getDenomOptions(chain.assets);
|
||||
|
||||
const [toAddress, setToAddress] = useState("");
|
||||
const [selectedDenom, setSelectedDenom] = useState(denomOptions[0]);
|
||||
@@ -43,18 +41,14 @@ const MsgSendForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgSendFormProps)
|
||||
const [amountError, setAmountError] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
assert(state.chain.denom, "denom missing");
|
||||
|
||||
setToAddressError("");
|
||||
setCustomDenomError("");
|
||||
setAmountError("");
|
||||
|
||||
const isMsgValid = (): boolean => {
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
|
||||
const addressErrorMsg = checkAddress(toAddress, state.chain.addressPrefix);
|
||||
const addressErrorMsg = checkAddress(toAddress, chain.addressPrefix);
|
||||
if (addressErrorMsg) {
|
||||
setToAddressError(`Invalid address for network ${state.chain.chainId}: ${addressErrorMsg}`);
|
||||
setToAddressError(`Invalid address for network ${chain.chainId}: ${addressErrorMsg}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -85,7 +79,7 @@ const MsgSendForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgSendFormProps)
|
||||
return Decimal.fromUserInput(amount, 0).atomics;
|
||||
}
|
||||
|
||||
const foundAsset = state.chain.assets?.find((asset) => asset.symbol === denom);
|
||||
const foundAsset = chain.assets.find((asset) => asset.symbol === denom);
|
||||
const exponent =
|
||||
foundAsset?.denom_units.find((unit) => unit.denom === foundAsset.symbol.toLowerCase())
|
||||
?.exponent ?? 0;
|
||||
@@ -107,14 +101,13 @@ const MsgSendForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgSendFormProps)
|
||||
setMsgGetter({ isMsgValid, msg });
|
||||
}, [
|
||||
amount,
|
||||
chain.addressPrefix,
|
||||
chain.assets,
|
||||
chain.chainId,
|
||||
customDenom,
|
||||
fromAddress,
|
||||
selectedDenom.value,
|
||||
setMsgGetter,
|
||||
state.chain.addressPrefix,
|
||||
state.chain.assets,
|
||||
state.chain.chainId,
|
||||
state.chain.denom,
|
||||
toAddress,
|
||||
]);
|
||||
|
||||
@@ -131,7 +124,7 @@ const MsgSendForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgSendFormProps)
|
||||
value={toAddress}
|
||||
onChange={({ target }) => setToAddress(target.value)}
|
||||
error={toAddressError}
|
||||
placeholder={`E.g. ${exampleAddress(0, state.chain.addressPrefix)}`}
|
||||
placeholder={`E.g. ${exampleAddress(0, chain.addressPrefix)}`}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-item form-select">
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
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 { useChains } from "../../../../context/ChainsContext";
|
||||
import { checkAddress, exampleAddress } from "../../../../lib/displayHelpers";
|
||||
import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
|
||||
import Input from "../../../inputs/Input";
|
||||
@@ -19,8 +18,7 @@ const MsgSetWithdrawAddressForm = ({
|
||||
setMsgGetter,
|
||||
deleteMsg,
|
||||
}: MsgSetWithdrawAddressFormProps) => {
|
||||
const { state } = useAppContext();
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
const { chain } = useChains();
|
||||
|
||||
const [withdrawAddress, setWithdrawAddress] = useState("");
|
||||
const [withdrawAddressError, setWithdrawAddressError] = useState("");
|
||||
@@ -30,12 +28,10 @@ const MsgSetWithdrawAddressForm = ({
|
||||
setWithdrawAddressError("");
|
||||
|
||||
const isMsgValid = (): boolean => {
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
|
||||
const addressErrorMsg = checkAddress(withdrawAddress, state.chain.addressPrefix);
|
||||
const addressErrorMsg = checkAddress(withdrawAddress, chain.addressPrefix);
|
||||
if (addressErrorMsg) {
|
||||
setWithdrawAddressError(
|
||||
`Invalid address for network ${state.chain.chainId}: ${addressErrorMsg}`,
|
||||
`Invalid address for network ${chain.chainId}: ${addressErrorMsg}`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@@ -51,13 +47,7 @@ const MsgSetWithdrawAddressForm = ({
|
||||
|
||||
setMsgGetter({ isMsgValid, msg });
|
||||
} catch {}
|
||||
}, [
|
||||
delegatorAddress,
|
||||
setMsgGetter,
|
||||
state.chain.addressPrefix,
|
||||
state.chain.chainId,
|
||||
withdrawAddress,
|
||||
]);
|
||||
}, [chain.addressPrefix, chain.chainId, delegatorAddress, setMsgGetter, withdrawAddress]);
|
||||
|
||||
return (
|
||||
<StackableContainer lessPadding lessMargin>
|
||||
@@ -72,7 +62,7 @@ const MsgSetWithdrawAddressForm = ({
|
||||
value={withdrawAddress}
|
||||
onChange={({ target }) => setWithdrawAddress(target.value)}
|
||||
error={withdrawAddressError}
|
||||
placeholder={`E.g. ${exampleAddress(0, state.chain.addressPrefix)}`}
|
||||
placeholder={`E.g. ${exampleAddress(0, chain.addressPrefix)}`}
|
||||
/>
|
||||
</div>
|
||||
<style jsx>{`
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { MsgTransferEncodeObject } from "@cosmjs/stargate";
|
||||
import { assert } from "@cosmjs/utils";
|
||||
import { useEffect, useState } from "react";
|
||||
import { MsgGetter } from "..";
|
||||
import { useAppContext } from "../../../../context/AppContext";
|
||||
import { useChains } from "../../../../context/ChainsContext";
|
||||
import {
|
||||
datetimeLocalFromTimestamp,
|
||||
timestampFromDatetimeLocal,
|
||||
@@ -31,8 +30,7 @@ interface MsgTransferFormProps {
|
||||
}
|
||||
|
||||
const MsgTransferForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgTransferFormProps) => {
|
||||
const { state } = useAppContext();
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
const { chain } = useChains();
|
||||
|
||||
const [sourcePort, setSourcePort] = useState("transfer");
|
||||
const [sourceChannel, setSourceChannel] = useState("");
|
||||
@@ -82,7 +80,7 @@ const MsgTransferForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgTransferFo
|
||||
|
||||
const addressErrorMsg = checkAddress(toAddress, null); // Allow address from any chain
|
||||
if (addressErrorMsg) {
|
||||
setToAddressError(`Invalid address for network ${state.chain.chainId}: ${addressErrorMsg}`);
|
||||
setToAddressError(`Invalid address for network ${chain.chainId}: ${addressErrorMsg}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -110,13 +108,13 @@ const MsgTransferForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgTransferFo
|
||||
setMsgGetter({ isMsgValid, msg });
|
||||
}, [
|
||||
amount,
|
||||
chain.chainId,
|
||||
denom,
|
||||
fromAddress,
|
||||
memo,
|
||||
setMsgGetter,
|
||||
sourceChannel,
|
||||
sourcePort,
|
||||
state.chain.chainId,
|
||||
timeout,
|
||||
toAddress,
|
||||
]);
|
||||
@@ -134,7 +132,7 @@ const MsgTransferForm = ({ fromAddress, setMsgGetter, deleteMsg }: MsgTransferFo
|
||||
value={toAddress}
|
||||
onChange={({ target }) => setToAddress(target.value)}
|
||||
error={toAddressError}
|
||||
placeholder={`E.g. ${exampleAddress(0, state.chain.addressPrefix)}`}
|
||||
placeholder={`E.g. ${exampleAddress(0, chain.addressPrefix)}`}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-item">
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
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 { useChains } from "../../../../context/ChainsContext";
|
||||
import { checkAddress, exampleAddress } from "../../../../lib/displayHelpers";
|
||||
import { MsgCodecs, MsgTypeUrls } from "../../../../types/txMsg";
|
||||
import Input from "../../../inputs/Input";
|
||||
@@ -20,8 +19,7 @@ const MsgUndelegateForm = ({
|
||||
setMsgGetter,
|
||||
deleteMsg,
|
||||
}: MsgUndelegateFormProps) => {
|
||||
const { state } = useAppContext();
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
const { chain } = useChains();
|
||||
|
||||
const [validatorAddress, setValidatorAddress] = useState("");
|
||||
const [amount, setAmount] = useState("0");
|
||||
@@ -31,18 +29,14 @@ const MsgUndelegateForm = ({
|
||||
|
||||
useEffect(() => {
|
||||
try {
|
||||
assert(state.chain.denom, "denom missing");
|
||||
|
||||
setValidatorAddressError("");
|
||||
setAmountError("");
|
||||
|
||||
const isMsgValid = (): boolean => {
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
|
||||
const addressErrorMsg = checkAddress(validatorAddress, state.chain.addressPrefix);
|
||||
const addressErrorMsg = checkAddress(validatorAddress, chain.addressPrefix);
|
||||
if (addressErrorMsg) {
|
||||
setValidatorAddressError(
|
||||
`Invalid address for network ${state.chain.chainId}: ${addressErrorMsg}`,
|
||||
`Invalid address for network ${chain.chainId}: ${addressErrorMsg}`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@@ -57,13 +51,13 @@ const MsgUndelegateForm = ({
|
||||
|
||||
const amountInAtomics = Decimal.fromUserInput(
|
||||
amount || "0",
|
||||
Number(state.chain.displayDenomExponent),
|
||||
Number(chain.displayDenomExponent),
|
||||
).atomics;
|
||||
|
||||
const msgValue = MsgCodecs[MsgTypeUrls.Undelegate].fromPartial({
|
||||
delegatorAddress,
|
||||
validatorAddress,
|
||||
amount: { amount: amountInAtomics, denom: state.chain.denom },
|
||||
amount: { amount: amountInAtomics, denom: chain.denom },
|
||||
});
|
||||
|
||||
const msg: MsgUndelegateEncodeObject = { typeUrl: MsgTypeUrls.Undelegate, value: msgValue };
|
||||
@@ -72,12 +66,12 @@ const MsgUndelegateForm = ({
|
||||
} catch {}
|
||||
}, [
|
||||
amount,
|
||||
chain.addressPrefix,
|
||||
chain.chainId,
|
||||
chain.denom,
|
||||
chain.displayDenomExponent,
|
||||
delegatorAddress,
|
||||
setMsgGetter,
|
||||
state.chain.addressPrefix,
|
||||
state.chain.chainId,
|
||||
state.chain.denom,
|
||||
state.chain.displayDenomExponent,
|
||||
validatorAddress,
|
||||
]);
|
||||
|
||||
@@ -94,13 +88,13 @@ const MsgUndelegateForm = ({
|
||||
value={validatorAddress}
|
||||
onChange={({ target }) => setValidatorAddress(target.value)}
|
||||
error={validatorAddressError}
|
||||
placeholder={`E.g. ${exampleAddress(0, state.chain.addressPrefix)}`}
|
||||
placeholder={`E.g. ${exampleAddress(0, chain.addressPrefix)}`}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-item">
|
||||
<Input
|
||||
type="number"
|
||||
label={`Amount (${state.chain.displayDenom})`}
|
||||
label={`Amount (${chain.displayDenom})`}
|
||||
name="amount"
|
||||
value={amount}
|
||||
onChange={({ target }) => setAmount(target.value)}
|
||||
|
||||
@@ -4,7 +4,7 @@ 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 { useChains } from "../../../context/ChainsContext";
|
||||
import { exportMsgToJson, gasOfTx } from "../../../lib/txMsgHelpers";
|
||||
import { DbTransaction } from "../../../types";
|
||||
import { MsgTypeUrl, MsgTypeUrls } from "../../../types/txMsg";
|
||||
@@ -25,7 +25,7 @@ interface CreateTxFormProps {
|
||||
}
|
||||
|
||||
const CreateTxForm = ({ router, senderAddress, accountOnChain }: CreateTxFormProps) => {
|
||||
const { state } = useAppContext();
|
||||
const { chain } = useChains();
|
||||
|
||||
const [processing, setProcessing] = useState(false);
|
||||
const [msgTypes, setMsgTypes] = useState<readonly MsgTypeUrl[]>([]);
|
||||
@@ -36,9 +36,6 @@ const CreateTxForm = ({ router, senderAddress, accountOnChain }: CreateTxFormPro
|
||||
const [gasLimitError, setGasLimitError] = useState("");
|
||||
const [showCreateTxError, setShowTxError] = useState(false);
|
||||
|
||||
const gasPrice = state.chain.gasPrice;
|
||||
assert(gasPrice, "gasPrice missing");
|
||||
|
||||
const addMsgType = (newMsgType: MsgTypeUrl) => {
|
||||
setMsgKeys((oldMsgKeys) => [...oldMsgKeys, crypto.randomUUID()]);
|
||||
setMsgTypes((oldMsgTypes) => {
|
||||
@@ -54,7 +51,6 @@ 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 }) => isMsgValid())
|
||||
@@ -72,9 +68,9 @@ const CreateTxForm = ({ router, senderAddress, accountOnChain }: CreateTxFormPro
|
||||
const tx: DbTransaction = {
|
||||
accountNumber: accountOnChain.accountNumber,
|
||||
sequence: accountOnChain.sequence,
|
||||
chainId: state.chain.chainId,
|
||||
chainId: chain.chainId,
|
||||
msgs,
|
||||
fee: calculateFee(gasLimit, gasPrice),
|
||||
fee: calculateFee(gasLimit, chain.gasPrice),
|
||||
memo,
|
||||
};
|
||||
|
||||
@@ -84,7 +80,7 @@ const CreateTxForm = ({ router, senderAddress, accountOnChain }: CreateTxFormPro
|
||||
dataJSON: JSON.stringify(tx),
|
||||
});
|
||||
|
||||
router.push(`/multi/${senderAddress}/transaction/${transactionID}`);
|
||||
router.push(`/${chain.registryName}/${senderAddress}/transaction/${transactionID}`);
|
||||
} catch (error) {
|
||||
console.error("Creat transaction error:", error);
|
||||
setShowTxError(true);
|
||||
@@ -145,7 +141,7 @@ const CreateTxForm = ({ router, senderAddress, accountOnChain }: CreateTxFormPro
|
||||
<Input
|
||||
label="Gas Price"
|
||||
name="gas-price"
|
||||
value={gasPrice}
|
||||
value={chain.gasPrice}
|
||||
disabled={true}
|
||||
error={gasLimitError}
|
||||
/>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { StargateClient } from "@cosmjs/stargate";
|
||||
import { assert } from "@cosmjs/utils";
|
||||
import { NextRouter, withRouter } from "next/router";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useAppContext } from "../../context/AppContext";
|
||||
import { useChains } from "../../context/ChainsContext";
|
||||
import { exampleAddress } from "../../lib/displayHelpers";
|
||||
import { getMultisigAccount } from "../../lib/multisigHelpers";
|
||||
import Button from "../inputs/Button";
|
||||
@@ -14,12 +13,12 @@ interface Props {
|
||||
}
|
||||
|
||||
const FindMultisigForm = (props: Props) => {
|
||||
const { state } = useAppContext();
|
||||
const { chain } = useChains();
|
||||
const [address, setAddress] = useState("");
|
||||
const [multisigError, setMultisigError] = useState("");
|
||||
|
||||
const handleSearch = () => {
|
||||
props.router.push(`/multi/${address}`);
|
||||
props.router.push(`/${chain.registryName}/${address}`);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -30,10 +29,8 @@ const FindMultisigForm = (props: Props) => {
|
||||
}
|
||||
|
||||
try {
|
||||
assert(state.chain.nodeAddress, "Node address missing");
|
||||
const client = await StargateClient.connect(state.chain.nodeAddress);
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
await getMultisigAccount(address, state.chain.addressPrefix, client);
|
||||
const client = await StargateClient.connect(chain.nodeAddress);
|
||||
await getMultisigAccount(address, chain.addressPrefix, client);
|
||||
setMultisigError("");
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
@@ -44,9 +41,7 @@ const FindMultisigForm = (props: Props) => {
|
||||
console.error("Multisig error:", error);
|
||||
}
|
||||
})();
|
||||
}, [address, state.chain.addressPrefix, state.chain.nodeAddress]);
|
||||
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
}, [address, chain.addressPrefix, chain.nodeAddress]);
|
||||
|
||||
return (
|
||||
<StackableContainer>
|
||||
@@ -62,7 +57,7 @@ const FindMultisigForm = (props: Props) => {
|
||||
value={address}
|
||||
label="Multisig Address"
|
||||
name="address"
|
||||
placeholder={`E.g. ${exampleAddress(0, state.chain.addressPrefix)}`}
|
||||
placeholder={`E.g. ${exampleAddress(0, chain.addressPrefix)}`}
|
||||
error={multisigError}
|
||||
/>
|
||||
<Button
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { StargateClient } from "@cosmjs/stargate";
|
||||
import { assert } from "@cosmjs/utils";
|
||||
import { NextRouter, withRouter } from "next/router";
|
||||
import { useState } from "react";
|
||||
import { useAppContext } from "../../context/AppContext";
|
||||
import { useChains } from "../../context/ChainsContext";
|
||||
import { exampleAddress, examplePubkey } from "../../lib/displayHelpers";
|
||||
import { createMultisigFromCompressedSecp256k1Pubkeys } from "../../lib/multisigHelpers";
|
||||
import Button from "../inputs/Button";
|
||||
@@ -19,7 +18,7 @@ interface Props {
|
||||
}
|
||||
|
||||
const MultiSigForm = (props: Props) => {
|
||||
const { state } = useAppContext();
|
||||
const { chain } = useChains();
|
||||
const [pubkeys, setPubkeys] = useState([emptyPubKeyGroup(), emptyPubKeyGroup()]);
|
||||
const [threshold, setThreshold] = useState(2);
|
||||
const [processing, setProcessing] = useState(false);
|
||||
@@ -57,8 +56,7 @@ const MultiSigForm = (props: Props) => {
|
||||
};
|
||||
|
||||
const getPubkeyFromNode = async (address: string) => {
|
||||
assert(state.chain.nodeAddress, "nodeAddress missing");
|
||||
const client = await StargateClient.connect(state.chain.nodeAddress);
|
||||
const client = await StargateClient.connect(chain.nodeAddress);
|
||||
const accountOnChain = await client.getAccount(address);
|
||||
console.log(accountOnChain);
|
||||
if (!accountOnChain || !accountOnChain.pubkey) {
|
||||
@@ -105,15 +103,13 @@ const MultiSigForm = (props: Props) => {
|
||||
const compressedPubkeys = pubkeys.map((item) => item.compressedPubkey);
|
||||
let multisigAddress;
|
||||
try {
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
assert(state.chain.chainId, "chainId missing");
|
||||
multisigAddress = await createMultisigFromCompressedSecp256k1Pubkeys(
|
||||
compressedPubkeys,
|
||||
threshold,
|
||||
state.chain.addressPrefix,
|
||||
state.chain.chainId,
|
||||
chain.addressPrefix,
|
||||
chain.chainId,
|
||||
);
|
||||
props.router.push(`/multi/${multisigAddress}`);
|
||||
props.router.push(`/${chain.registryName}/${multisigAddress}`);
|
||||
} catch (error) {
|
||||
console.log("Failed to creat multisig: ", error);
|
||||
}
|
||||
@@ -132,7 +128,6 @@ const MultiSigForm = (props: Props) => {
|
||||
<p>Add the addresses that will make up this multisig.</p>
|
||||
</StackableContainer>
|
||||
{pubkeys.map((pubkeyGroup, index) => {
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
return (
|
||||
<StackableContainer lessPadding lessMargin key={index}>
|
||||
<div className="key-row">
|
||||
@@ -160,7 +155,7 @@ const MultiSigForm = (props: Props) => {
|
||||
placeholder={`E.g. ${
|
||||
pubkeyGroup.isPubkey
|
||||
? examplePubkey(index)
|
||||
: exampleAddress(index, state.chain.addressPrefix)
|
||||
: exampleAddress(index, chain.addressPrefix)
|
||||
}`}
|
||||
error={pubkeyGroup.keyError}
|
||||
onBlur={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
|
||||
@@ -6,7 +6,7 @@ import { assert } from "@cosmjs/utils";
|
||||
import TransportWebUSB from "@ledgerhq/hw-transport-webusb";
|
||||
import axios from "axios";
|
||||
import { useCallback, useLayoutEffect, useState } from "react";
|
||||
import { useAppContext } from "../../context/AppContext";
|
||||
import { useChains } from "../../context/ChainsContext";
|
||||
import { getConnectError } from "../../lib/errorHelpers";
|
||||
import { DbSignature, DbTransaction, WalletAccount } from "../../types";
|
||||
import HashView from "../dataViews/HashView";
|
||||
@@ -21,18 +21,18 @@ interface LoadingStates {
|
||||
readonly ledger?: boolean;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
signatures: DbSignature[];
|
||||
tx: DbTransaction;
|
||||
pubkey: MultisigThresholdPubkey;
|
||||
transactionID: string;
|
||||
addSignature: (signature: DbSignature) => void;
|
||||
interface TransactionSigningProps {
|
||||
readonly signatures: DbSignature[];
|
||||
readonly tx: DbTransaction;
|
||||
readonly pubkey: MultisigThresholdPubkey;
|
||||
readonly transactionID: string;
|
||||
readonly addSignature: (signature: DbSignature) => void;
|
||||
}
|
||||
|
||||
const TransactionSigning = (props: Props) => {
|
||||
const TransactionSigning = (props: TransactionSigningProps) => {
|
||||
const memberPubkeys = props.pubkey.value.pubkeys.map(({ value }) => value);
|
||||
|
||||
const { state } = useAppContext();
|
||||
const { chain } = useChains();
|
||||
const [walletAccount, setWalletAccount] = useState<WalletAccount>();
|
||||
const [sigError, setSigError] = useState("");
|
||||
const [connectError, setConnectError] = useState("");
|
||||
@@ -44,13 +44,12 @@ const TransactionSigning = (props: Props) => {
|
||||
const connectKeplr = useCallback(async () => {
|
||||
try {
|
||||
setLoading((oldLoading) => ({ ...oldLoading, keplr: true }));
|
||||
assert(state.chain.chainId, "chainId missing");
|
||||
|
||||
await window.keplr.enable(state.chain.chainId);
|
||||
await window.keplr.enable(chain.chainId);
|
||||
window.keplr.defaultOptions = {
|
||||
sign: { preferNoSetFee: true, preferNoSetMemo: true, disableBalanceCheck: true },
|
||||
};
|
||||
const tempWalletAccount = await window.keplr.getKey(state.chain.chainId);
|
||||
const tempWalletAccount = await window.keplr.getKey(chain.chainId);
|
||||
setWalletAccount(tempWalletAccount);
|
||||
|
||||
const pubkey = toBase64(tempWalletAccount.pubKey);
|
||||
@@ -76,7 +75,7 @@ const TransactionSigning = (props: Props) => {
|
||||
} finally {
|
||||
setLoading((newLoading) => ({ ...newLoading, keplr: false }));
|
||||
}
|
||||
}, [memberPubkeys, props.signatures, state.chain.chainId]);
|
||||
}, [chain.chainId, memberPubkeys, props.signatures]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const accountChangeKey = "keplr_keystorechange";
|
||||
@@ -91,7 +90,6 @@ const TransactionSigning = (props: Props) => {
|
||||
const connectLedger = async () => {
|
||||
try {
|
||||
setLoading((newLoading) => ({ ...newLoading, ledger: true }));
|
||||
assert(state.chain.addressPrefix, "addressPrefix missing");
|
||||
|
||||
// Prepare ledger
|
||||
const ledgerTransport = await TransportWebUSB.create(120000, 120000);
|
||||
@@ -99,7 +97,7 @@ const TransactionSigning = (props: Props) => {
|
||||
// Setup signer
|
||||
const offlineSigner = new LedgerSigner(ledgerTransport, {
|
||||
hdPaths: [makeCosmoshubPath(0)],
|
||||
prefix: state.chain.addressPrefix,
|
||||
prefix: chain.addressPrefix,
|
||||
});
|
||||
const accounts = await offlineSigner.getAccounts();
|
||||
const tempWalletAccount: WalletAccount = {
|
||||
@@ -138,12 +136,9 @@ const TransactionSigning = (props: Props) => {
|
||||
const signTransaction = async () => {
|
||||
try {
|
||||
setLoading((newLoading) => ({ ...newLoading, signing: true }));
|
||||
assert(state.chain.chainId, "chainId missing");
|
||||
|
||||
const offlineSigner =
|
||||
walletType === "Keplr"
|
||||
? window.getOfflineSignerOnlyAmino(state.chain.chainId)
|
||||
: ledgerSigner;
|
||||
walletType === "Keplr" ? window.getOfflineSignerOnlyAmino(chain.chainId) : ledgerSigner;
|
||||
|
||||
const signerAddress = walletAccount?.bech32Address;
|
||||
assert(signerAddress, "Missing signer address");
|
||||
@@ -152,7 +147,7 @@ const TransactionSigning = (props: Props) => {
|
||||
const signerData = {
|
||||
accountNumber: props.tx.accountNumber,
|
||||
sequence: props.tx.sequence,
|
||||
chainId: state.chain.chainId,
|
||||
chainId: chain.chainId,
|
||||
};
|
||||
|
||||
const { bodyBytes, signatures } = await signingClient.sign(
|
||||
|
||||
Reference in New Issue
Block a user