Add text fields for moniker and public key
This commit is contained in:
parent
c461e90768
commit
30300b6cca
@ -1,35 +1,52 @@
|
|||||||
import { Box, MenuItem, Select, Typography } from '@mui/material'
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import React, { useEffect, useMemo, useState } from 'react'
|
import { Box, MenuItem, Select, TextField, Typography } from '@mui/material';
|
||||||
import { enqueueSnackbar } from 'notistack';
|
import { enqueueSnackbar } from 'notistack';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { MsgCreateValidator } from 'cosmjs-types/cosmos/staking/v1beta1/tx';
|
import { MsgCreateValidator } from 'cosmjs-types/cosmos/staking/v1beta1/tx';
|
||||||
import { fromBech32, toBech32 } from '@cosmjs/encoding';
|
import { fromBech32, toBech32 } from '@cosmjs/encoding';
|
||||||
import { LoadingButton } from '@mui/lab';
|
import { LoadingButton } from '@mui/lab';
|
||||||
import { EncodeObject, encodePubkey } from '@cosmjs/proto-signing';
|
import { EncodeObject, encodePubkey } from '@cosmjs/proto-signing';
|
||||||
import { Registry } from '@cerc-io/registry-sdk';
|
import { Registry } from '@cerc-io/registry-sdk';
|
||||||
|
import { useWalletConnectContext } from '../context/WalletConnectContext';
|
||||||
import { useWalletConnectContext } from '../context/WalletConnectContext'
|
|
||||||
import { Participant } from '../types';
|
import { Participant } from '../types';
|
||||||
|
|
||||||
const Validator = () => {
|
const Validator = () => {
|
||||||
const { session, signClient } = useWalletConnectContext();
|
const { session, signClient } = useWalletConnectContext();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const [cosmosAddress, setCosmosAddress] = useState('laconic1z4l4556v8jnk7k456ujme720nk8mzjwhka7qvw');
|
const [cosmosAddress, setCosmosAddress] = useState('');
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [pubkey, setPubkey] = useState('qiQEvyqIf9/e912ZEIZD5CfdqR3iOlpI+NVtRnpHuYc=');
|
const [moniker, setMoniker] = useState('');
|
||||||
|
const [pubKey, setPubKey] = useState('');
|
||||||
const [participant, setParticipant] = useState<Participant | null>(null);
|
const [participant, setParticipant] = useState<Participant | null>(null);
|
||||||
|
const [isError, setIsError] = useState(false);
|
||||||
|
|
||||||
if (!session) {
|
if (!session) {
|
||||||
navigate("/connect-wallet?redirectTo=create-validator");
|
navigate("/connect-wallet?redirectTo=create-validator");
|
||||||
}
|
}
|
||||||
|
|
||||||
const msgCreateValidator: MsgCreateValidator =
|
const isMonikerValid = useMemo(()=>{
|
||||||
useMemo(() => {
|
return moniker.trim().length > 0;
|
||||||
|
}, [moniker]);
|
||||||
|
|
||||||
|
const isPubKeyValid = useMemo(()=>{
|
||||||
|
return pubKey.length === 44
|
||||||
|
}, [pubKey]);
|
||||||
|
|
||||||
|
const msgCreateValidator: MsgCreateValidator = useMemo(() => {
|
||||||
|
let value = '';
|
||||||
|
if (pubKey.length === 44) {
|
||||||
|
value = pubKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
const encodedPubKey = encodePubkey({
|
||||||
|
type: "tendermint/PubKeyEd25519",
|
||||||
|
value,
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
description: {
|
description: {
|
||||||
moniker: "dockerNode2",
|
moniker,
|
||||||
identity: "",
|
identity: "",
|
||||||
website: "",
|
website: "",
|
||||||
securityContact: "",
|
securityContact: "",
|
||||||
@ -42,37 +59,26 @@ const Validator = () => {
|
|||||||
},
|
},
|
||||||
minSelfDelegation: "1",
|
minSelfDelegation: "1",
|
||||||
delegatorAddress: '',
|
delegatorAddress: '',
|
||||||
validatorAddress: toBech32('laconicvaloper', fromBech32(cosmosAddress).data),
|
validatorAddress: cosmosAddress && toBech32('laconicvaloper', fromBech32(cosmosAddress).data),
|
||||||
pubkey: encodePubkey({
|
pubkey: encodedPubKey,
|
||||||
type: "tendermint/PubKeyEd25519",
|
|
||||||
value: pubkey,
|
|
||||||
}),
|
|
||||||
value: {
|
value: {
|
||||||
amount: process.env.REACT_APP_STAKING_AMOUNT!,
|
amount: process.env.REACT_APP_STAKING_AMOUNT!,
|
||||||
denom: process.env.REACT_APP_LACONICD_DENOM!,
|
denom: process.env.REACT_APP_LACONICD_DENOM!,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}, [cosmosAddress, pubkey]);
|
}, [cosmosAddress, pubKey, moniker]);
|
||||||
|
|
||||||
// When sending a typed message value, the pubkey value type (Uint8Array) gets lost when wallet connect JSON-stringifies the tx message;
|
|
||||||
// resulting into a type error from the chain
|
|
||||||
// Workaround: Encode the tx value instead of sending a typed message directly, has to be decoded using MsgCreateValidator.fromJSON on the wallet side
|
|
||||||
const msgCreateValidatorEncodeObject: EncodeObject = {
|
const msgCreateValidatorEncodeObject: EncodeObject = {
|
||||||
typeUrl: '/cosmos.staking.v1beta1.MsgCreateValidator',
|
typeUrl: '/cosmos.staking.v1beta1.MsgCreateValidator',
|
||||||
value: MsgCreateValidator.toJSON(msgCreateValidator)
|
value: MsgCreateValidator.toJSON(msgCreateValidator)
|
||||||
// value: msgCreateValidator
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendTransaction = async (
|
const sendTransaction = async (transactionMessage: EncodeObject) => {
|
||||||
transactionMessage: EncodeObject
|
|
||||||
) => {
|
|
||||||
try {
|
try {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|
||||||
const params = { transactionMessage, signer: cosmosAddress };
|
const params = { transactionMessage, signer: cosmosAddress };
|
||||||
const responseFromWallet = await signClient!.request<{
|
const responseFromWallet = await signClient!.request<{ code: number }>({
|
||||||
code: number;
|
|
||||||
}>({
|
|
||||||
topic: session!.topic,
|
topic: session!.topic,
|
||||||
chainId: `cosmos:${process.env.REACT_APP_LACONICD_CHAIN_ID}`,
|
chainId: `cosmos:${process.env.REACT_APP_LACONICD_CHAIN_ID}`,
|
||||||
request: {
|
request: {
|
||||||
@ -84,9 +90,7 @@ const Validator = () => {
|
|||||||
enqueueSnackbar("Transaction not sent", { variant: "error" });
|
enqueueSnackbar("Transaction not sent", { variant: "error" });
|
||||||
} else {
|
} else {
|
||||||
navigate("/onboarding-success", {
|
navigate("/onboarding-success", {
|
||||||
state: {
|
state: { cosmosAddress },
|
||||||
cosmosAddress
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -98,9 +102,7 @@ const Validator = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const registry = new Registry(
|
const registry = new Registry(process.env.REACT_APP_REGISTRY_GQL_ENDPOINT!);
|
||||||
process.env.REACT_APP_REGISTRY_GQL_ENDPOINT!
|
|
||||||
);
|
|
||||||
|
|
||||||
const fetchParticipant = async () => {
|
const fetchParticipant = async () => {
|
||||||
try {
|
try {
|
||||||
@ -114,7 +116,6 @@ const Validator = () => {
|
|||||||
setParticipant(null);
|
setParticipant(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setParticipant(fetchedParticipant);
|
setParticipant(fetchedParticipant);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching participant", error);
|
console.error("Error fetching participant", error);
|
||||||
@ -137,15 +138,11 @@ const Validator = () => {
|
|||||||
<Typography variant="h5">Create a validator</Typography>
|
<Typography variant="h5">Create a validator</Typography>
|
||||||
<Typography variant="body1">Select Laconic account:</Typography>
|
<Typography variant="body1">Select Laconic account:</Typography>
|
||||||
<Select
|
<Select
|
||||||
sx={{
|
sx={{ marginBottom: 2 }}
|
||||||
marginBottom: 2
|
|
||||||
}}
|
|
||||||
labelId="demo-simple-select-label"
|
labelId="demo-simple-select-label"
|
||||||
id="demo-simple-select"
|
id="demo-simple-select"
|
||||||
value={cosmosAddress}
|
value={cosmosAddress}
|
||||||
onChange={(e: any) => {
|
onChange={(e) => setCosmosAddress(e.target.value)}
|
||||||
setCosmosAddress(e.target.value);
|
|
||||||
}}
|
|
||||||
style={{ maxWidth: "600px", display: "block" }}
|
style={{ maxWidth: "600px", display: "block" }}
|
||||||
>
|
>
|
||||||
{session?.namespaces.cosmos.accounts.map((address, index) => (
|
{session?.namespaces.cosmos.accounts.map((address, index) => (
|
||||||
@ -183,7 +180,37 @@ const Validator = () => {
|
|||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* {participant && participant.role === "validator" && ( */}
|
<Box style={{ maxWidth: "600px" }}>
|
||||||
|
<TextField
|
||||||
|
id="moniker"
|
||||||
|
label="Enter your node moniker"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
margin="normal"
|
||||||
|
value={moniker}
|
||||||
|
onChange={(e) => {
|
||||||
|
setIsError(false);
|
||||||
|
setMoniker(e.target.value)
|
||||||
|
}}
|
||||||
|
error={!isMonikerValid && isError }
|
||||||
|
helperText={!isMonikerValid && isError ? "Moniker is required" : ""}
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
id="pub-key"
|
||||||
|
label="Enter your public key"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
margin="normal"
|
||||||
|
value={pubKey}
|
||||||
|
onChange={(e) => {
|
||||||
|
setIsError(false);
|
||||||
|
setPubKey(e.target.value)
|
||||||
|
}}
|
||||||
|
error={!isPubKeyValid && isError}
|
||||||
|
helperText={!isPubKeyValid ? "Public key must be 44 characters" : ""}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<>
|
<>
|
||||||
<Typography>Send transaction to chain</Typography>
|
<Typography>Send transaction to chain</Typography>
|
||||||
<Box
|
<Box
|
||||||
@ -197,24 +224,32 @@ const Validator = () => {
|
|||||||
{JSON.stringify(msgCreateValidator, null, 2)}
|
{JSON.stringify(msgCreateValidator, null, 2)}
|
||||||
</pre>
|
</pre>
|
||||||
</Box>
|
</Box>
|
||||||
<Box marginTop={1}>
|
<Box marginTop={1} marginBottom={1}>
|
||||||
<LoadingButton
|
<LoadingButton
|
||||||
variant="contained"
|
variant="contained"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
console.log(msgCreateValidatorEncodeObject);
|
console.log(msgCreateValidatorEncodeObject);
|
||||||
|
if (
|
||||||
|
msgCreateValidator.pubkey?.value?.length !== 34 ||
|
||||||
|
msgCreateValidator.description.moniker.length === 0 ||
|
||||||
|
msgCreateValidator.validatorAddress.length === 0
|
||||||
|
) {
|
||||||
|
setIsError(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
await sendTransaction(msgCreateValidatorEncodeObject);
|
await sendTransaction(msgCreateValidatorEncodeObject);
|
||||||
}}
|
}}
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
|
disabled={isError}
|
||||||
>
|
>
|
||||||
Send transaction
|
Send transaction
|
||||||
</LoadingButton>
|
</LoadingButton>
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
{/* )} */}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default Validator
|
export default Validator;
|
||||||
|
Loading…
Reference in New Issue
Block a user