Add text fields for moniker and public key

This commit is contained in:
Adw8 2024-08-08 19:31:29 +05:30
parent c461e90768
commit 30300b6cca

View File

@ -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;