diff --git a/src/pages/Validator.tsx b/src/pages/Validator.tsx index 67daa80..e36199c 100644 --- a/src/pages/Validator.tsx +++ b/src/pages/Validator.tsx @@ -1,78 +1,84 @@ -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 { useNavigate } from 'react-router-dom'; - 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 { EncodeObject, encodePubkey } from '@cosmjs/proto-signing'; import { Registry } from '@cerc-io/registry-sdk'; - -import { useWalletConnectContext } from '../context/WalletConnectContext' +import { useWalletConnectContext } from '../context/WalletConnectContext'; import { Participant } from '../types'; const Validator = () => { - const {session, signClient} = useWalletConnectContext(); + const { session, signClient } = useWalletConnectContext(); const navigate = useNavigate(); - const [cosmosAddress, setCosmosAddress] = useState('laconic1z4l4556v8jnk7k456ujme720nk8mzjwhka7qvw'); + const [cosmosAddress, setCosmosAddress] = useState(''); const [isLoading, setIsLoading] = useState(false); - const [pubkey, setPubkey] = useState('qiQEvyqIf9/e912ZEIZD5CfdqR3iOlpI+NVtRnpHuYc='); + const [moniker, setMoniker] = useState(''); + const [pubKey, setPubKey] = useState(''); const [participant, setParticipant] = useState(null); + const [isError, setIsError] = useState(false); - if (!session){ + if (!session) { navigate("/connect-wallet?redirectTo=create-validator"); } - const msgCreateValidator: MsgCreateValidator = - useMemo(() => { - return { - description: { - moniker: "dockerNode2", - identity: "", - website: "", - securityContact: "", - details: "", - }, - commission: { - maxChangeRate: "10000000000000000", // 0.01 - maxRate: "200000000000000000", // 0.2 - rate: "100000000000000000", // 0.1 - }, - minSelfDelegation: "1", - delegatorAddress: '', - validatorAddress: toBech32('laconicvaloper', fromBech32(cosmosAddress).data), - pubkey: encodePubkey({ - type: "tendermint/PubKeyEd25519", - value: pubkey, - }), - value: { - amount: process.env.REACT_APP_STAKING_AMOUNT!, - denom: process.env.REACT_APP_LACONICD_DENOM!, - }, - }; - }, [cosmosAddress, pubkey]); + const isMonikerValid = 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 { + description: { + moniker, + identity: "", + website: "", + securityContact: "", + details: "", + }, + commission: { + maxChangeRate: "10000000000000000", // 0.01 + maxRate: "200000000000000000", // 0.2 + rate: "100000000000000000", // 0.1 + }, + minSelfDelegation: "1", + delegatorAddress: '', + validatorAddress: cosmosAddress && toBech32('laconicvaloper', fromBech32(cosmosAddress).data), + pubkey: encodedPubKey, + value: { + amount: process.env.REACT_APP_STAKING_AMOUNT!, + denom: process.env.REACT_APP_LACONICD_DENOM!, + }, + }; + }, [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 = { typeUrl: '/cosmos.staking.v1beta1.MsgCreateValidator', value: MsgCreateValidator.toJSON(msgCreateValidator) - // value: msgCreateValidator }; - const sendTransaction = async ( - transactionMessage: EncodeObject - ) => { + const sendTransaction = async (transactionMessage: EncodeObject) => { try { setIsLoading(true); const params = { transactionMessage, signer: cosmosAddress }; - const responseFromWallet = await signClient!.request<{ - code: number; - }>({ + const responseFromWallet = await signClient!.request<{ code: number }>({ topic: session!.topic, chainId: `cosmos:${process.env.REACT_APP_LACONICD_CHAIN_ID}`, request: { @@ -84,9 +90,7 @@ const Validator = () => { enqueueSnackbar("Transaction not sent", { variant: "error" }); } else { navigate("/onboarding-success", { - state: { - cosmosAddress - } + state: { cosmosAddress }, }); } } catch (error) { @@ -98,9 +102,7 @@ const Validator = () => { }; useEffect(() => { - const registry = new Registry( - process.env.REACT_APP_REGISTRY_GQL_ENDPOINT! - ); + const registry = new Registry(process.env.REACT_APP_REGISTRY_GQL_ENDPOINT!); const fetchParticipant = async () => { try { @@ -114,7 +116,6 @@ const Validator = () => { setParticipant(null); return; } - setParticipant(fetchedParticipant); } catch (error) { console.error("Error fetching participant", error); @@ -137,15 +138,11 @@ const Validator = () => { Create a validator Select Laconic account: