testnet-onboarding-app/src/pages/SignWithNitroKey.tsx

149 lines
4.3 KiB
TypeScript

import React, { useState, useMemo, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { SnackbarProvider, enqueueSnackbar } from "notistack";
import canonicalStringify from "canonical-json";
import {
Select,
MenuItem,
Box,
Typography,
} from "@mui/material";
import LoadingButton from '@mui/lab/LoadingButton';
import { utf8ToHex } from "@walletconnect/encoding";
import { useWalletConnectContext } from "../context/WalletConnectContext";
const SignWithNitroKey = () => {
const { session, signClient, checkPersistedState } =
useWalletConnectContext();
useEffect(() => {
if (signClient && !session) {
checkPersistedState(signClient);
}
}, [session, signClient, checkPersistedState]);
const navigate = useNavigate();
const [ethAddress, setEthAddress] = useState("");
const [ethSignature, setEthSignature] = useState("");
const [cosmosAddress, setCosmosAddress] = useState("");
const [isLoading, setIsLoading] = useState(false);
const message = useMemo(() => {
return {
msg: "Register my account as a participant on the Laconic network",
address: ethAddress,
};
}, [ethAddress]);
const signEth = async () => {
if (session && signClient) {
try {
setIsLoading(true)
const jsonMessage = canonicalStringify(message);
const hexMsg = utf8ToHex(jsonMessage, true);
const receivedEthSig: string = await signClient!.request({
topic: session!.topic,
chainId: "eip155:1",
request: {
method: "personal_sign",
params: [hexMsg, ethAddress],
},
});
setIsLoading(false)
setEthSignature(ethSignature);
navigate("/user-verification", {
state: {
message,
cosmosAddress,
receivedEthSig,
},
});
} catch (error) {
console.log("err in signing ", error);
setIsLoading(false)
enqueueSnackbar("Error signing message", { variant: "error" });
}
}
};
return (
<div>
{session ? (
<Box
style={{
display: "flex",
flexDirection: "column",
marginTop: "100px",
gap: "10px",
}}
>
<Typography variant="h5">Sign with Nitro key</Typography>
<Typography variant="body1">Select Cosmos account:</Typography>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={cosmosAddress}
onChange={(e: any) => {
setCosmosAddress(e.target.value);
}}
style={{ maxWidth: "600px", display: "block" }}
>
{session?.namespaces.cosmos.accounts.map((address, index) => (
<MenuItem value={address.split(":")[2]} key={index}>
{address.split(":")[2]}
</MenuItem>
))}
</Select>
<Typography variant="body1">Select Nitro account: </Typography>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={ethAddress}
onChange={(e: any) => {
setEthAddress(e.target.value);
}}
style={{ maxWidth: "600px", display: "block" }}
>
{session?.namespaces.eip155.accounts.map((address, index) => (
<MenuItem value={address.split(":")[2]} key={index}>
{address.split(":")[2]}
</MenuItem>
))}
</Select>
{(Boolean(ethAddress) && Boolean(cosmosAddress)) && (<Box
sx={{
backgroundColor: "lightgray",
padding: 3,
wordWrap: "break-word",
}}
>
<pre style={{ whiteSpace: "pre-wrap", margin: 0 }}>{canonicalStringify(message, null, 2)} </pre>
</Box>)}
<Box>
<LoadingButton
variant="contained"
onClick={signEth}
disabled={!Boolean(ethAddress)}
style={{ marginTop: "20px" }}
loading={isLoading}
>
Sign using Nitro key
</LoadingButton>
</Box>
<SnackbarProvider />
</Box>
) : (
<>Loading...</>
)}
</div>
);
};
export default SignWithNitroKey;