Skin onboarding app #33

Merged
zramsay merged 11 commits from style/vaidator into main 2024-08-11 21:05:05 +00:00
Showing only changes of commit bee7379e86 - Show all commits

View File

@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useLocation, useNavigate } from "react-router-dom"; import { useLocation, useNavigate } from "react-router-dom";
import { enqueueSnackbar } from "notistack"; import { enqueueSnackbar } from "notistack";
import { Box, Card, CardContent, Grid, Typography } from "@mui/material"; import { Box, Divider, Typography } from "@mui/material";
import LoadingButton from "@mui/lab/LoadingButton/LoadingButton"; import LoadingButton from "@mui/lab/LoadingButton/LoadingButton";
import { import {
MsgOnboardParticipantEncodeObject, MsgOnboardParticipantEncodeObject,
@ -11,22 +11,27 @@ import {
import { StargateClient } from "@cosmjs/stargate"; import { StargateClient } from "@cosmjs/stargate";
import { useWalletConnectContext } from "../context/WalletConnectContext"; import { useWalletConnectContext } from "../context/WalletConnectContext";
import SelectRoleCard, {Role} from "../components/SelectRoleCard"; import SelectRoleCard, { Role } from "../components/SelectRoleCard";
import { HASHED_SUBSCRIBER_ID_KEY } from "../constants"; import { HASHED_SUBSCRIBER_ID_KEY } from "../constants";
import { Layout } from "../layout/Layout";
const SignWithCosmos = () => { const SignWithCosmos = () => {
const { session, signClient } = useWalletConnectContext(); const { session, signClient } = useWalletConnectContext();
const location = useLocation(); const location = useLocation();
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [balance, setBalance] = useState(''); const [balance, setBalance] = useState("");
const [isRequesting, setIsRequesting] = useState(false); const [isRequesting, setIsRequesting] = useState(false);
const [isTncAccepted, setIsTncAccepted] = useState(false); const [isTncAccepted, setIsTncAccepted] = useState(false);
const [role, setRole] = useState(Role.Participant); const [role, setRole] = useState(Role.Participant);
const navigate = useNavigate(); const navigate = useNavigate();
const {message: innerMessage, cosmosAddress, receivedEthSig: ethSignature} = location.state as { const {
message: innerMessage,
cosmosAddress,
receivedEthSig: ethSignature,
} = location.state as {
message?: { message?: {
msg: string; msg: string;
address: string; address: string;
@ -51,7 +56,7 @@ const SignWithCosmos = () => {
ethPayload: innerMessage, ethPayload: innerMessage,
ethSignature: ethSignature!, ethSignature: ethSignature!,
kycId: subscriberIdHash!, kycId: subscriberIdHash!,
role role,
}, },
}; };
}, [cosmosAddress, innerMessage, ethSignature, subscriberIdHash, role]); }, [cosmosAddress, innerMessage, ethSignature, subscriberIdHash, role]);
@ -59,22 +64,27 @@ const SignWithCosmos = () => {
const handleTokenRequest = async () => { const handleTokenRequest = async () => {
try { try {
setIsRequesting(true); setIsRequesting(true);
const response = await fetch(`${process.env.REACT_APP_FAUCET_ENDPOINT!}/faucet`, { const response = await fetch(
method: 'POST', `${process.env.REACT_APP_FAUCET_ENDPOINT!}/faucet`,
headers: { {
'Content-Type': 'application/json', method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
address: cosmosAddress,
}),
}, },
body: JSON.stringify({ );
address: cosmosAddress,
}),
});
if (response.ok) { if (response.ok) {
enqueueSnackbar('Tokens sent successfully', { variant: "success" }); enqueueSnackbar("Tokens sent successfully", { variant: "success" });
} else { } else {
const errorResponse = await response.json(); const errorResponse = await response.json();
if (response.status === 429) { if (response.status === 429) {
enqueueSnackbar(`${response.statusText} : ${errorResponse.error}`, { variant: "error" }); enqueueSnackbar(`${response.statusText} : ${errorResponse.error}`, {
variant: "error",
});
} else { } else {
throw new Error(errorResponse.error); throw new Error(errorResponse.error);
} }
@ -90,7 +100,7 @@ const SignWithCosmos = () => {
}; };
const sendTransaction = async ( const sendTransaction = async (
transactionMessage: MsgOnboardParticipantEncodeObject transactionMessage: MsgOnboardParticipantEncodeObject,
) => { ) => {
if (!ethAddress) { if (!ethAddress) {
enqueueSnackbar("Set nitro address"); enqueueSnackbar("Set nitro address");
@ -100,7 +110,9 @@ const SignWithCosmos = () => {
try { try {
setIsLoading(true); setIsLoading(true);
enqueueSnackbar("View and sign the message from your Laconic Wallet", { variant: "info" }); enqueueSnackbar("View and sign the message from your Laconic Wallet", {
variant: "info",
});
const params = { transactionMessage, signer: cosmosAddress }; const params = { transactionMessage, signer: cosmosAddress };
const responseFromWallet = await signClient!.request<{ const responseFromWallet = await signClient!.request<{
@ -118,8 +130,8 @@ const SignWithCosmos = () => {
} else { } else {
navigate("/onboarding-success", { navigate("/onboarding-success", {
state: { state: {
cosmosAddress cosmosAddress,
} },
}); });
} }
} catch (error) { } catch (error) {
@ -132,11 +144,16 @@ const SignWithCosmos = () => {
const getBalances = useCallback(async () => { const getBalances = useCallback(async () => {
try { try {
const cosmosClient = await createCosmosClient(process.env.REACT_APP_LACONICD_RPC_ENDPOINT!); const cosmosClient = await createCosmosClient(
const balance = await cosmosClient.getBalance(cosmosAddress!, process.env.REACT_APP_LACONICD_DENOM!); process.env.REACT_APP_LACONICD_RPC_ENDPOINT!,
);
const balance = await cosmosClient.getBalance(
cosmosAddress!,
process.env.REACT_APP_LACONICD_DENOM!,
);
setBalance(balance.amount); setBalance(balance.amount);
} catch (error) { } catch (error) {
console.error('Error fetching balance:', error); console.error("Error fetching balance:", error);
throw error; throw error;
} }
}, [cosmosAddress, createCosmosClient]); }, [cosmosAddress, createCosmosClient]);
@ -146,69 +163,77 @@ const SignWithCosmos = () => {
}, [getBalances]); }, [getBalances]);
return ( return (
<Box <>
sx={{ {!isTncAccepted && (
display: "flex", <Layout
flexDirection: "column", title="Please accept the terms and conditions to continue"
marginTop: 6, noBackButton
gap: 1, >
}} <SelectRoleCard
> handleAccept={() => setIsTncAccepted(true)}
<Typography variant="h5" display={`${isTncAccepted ? "none" : "block"}`}>Please accept terms and conditions to continue</Typography> handleRoleChange={setRole}
<SelectRoleCard handleAccept={() => setIsTncAccepted(true)} handleRoleChange={setRole}/> />
<Typography variant="h5">Send transaction to chain</Typography> </Layout>
<Typography>Laconic Account:</Typography> )}
<Card className='mt-1 mb-1'> <Layout title="Send transaction to chain" noBackButton>
<CardContent> <Typography>Laconic Account:</Typography>
<Grid container spacing={2}> <Box sx={{ backgroundColor: "#29292E", p: 2, borderRadius: 1, mb: 2 }}>
<Grid item xs={9}> <Typography variant="body1">Address: {cosmosAddress}</Typography>
<Typography variant="body1">Address: {cosmosAddress}</Typography> <Typography variant="body1">
<Typography variant="body1">Balance: {balance} {process.env.REACT_APP_LACONICD_DENOM}</Typography> Balance: {balance} {process.env.REACT_APP_LACONICD_DENOM}
</Grid> </Typography>
<Grid item xs={3} container justifyContent="flex-end"> </Box>
<LoadingButton
variant="contained"
onClick={handleTokenRequest}
disabled={isTncAccepted ? isRequesting : !isTncAccepted}
loading={isRequesting}
>
Request tokens from Faucet
</LoadingButton>
</Grid>
</Grid>
</CardContent>
</Card>
<Typography variant="body1">
Onboarding message: <br />
</Typography>
<Box
sx={{
backgroundColor: "lightgray",
padding: 3,
wordWrap: "break-word",
}}
>
<pre style={{ whiteSpace: "pre-wrap", margin: 0 }}>
{JSON.stringify(onboardParticipantMsg, null, 2)}{" "}
</pre>
</Box>
<Box
sx={{
paddingBottom: 2,
}}>
<LoadingButton <LoadingButton
variant="contained" variant="contained"
onClick={async () => { onClick={handleTokenRequest}
await sendTransaction(onboardParticipantMsg); disabled={isTncAccepted ? isRequesting : !isTncAccepted}
}} loading={isRequesting}
loading={isLoading}
disabled={isTncAccepted ? (balance === '0') : !isTncAccepted}
> >
Send transaction Request tokens from Faucet
</LoadingButton> </LoadingButton>
</Box> <Divider flexItem sx={{ my: 2 }} />
</Box> <Typography variant="body1">Onboarding message:</Typography>
<Box
sx={{
backgroundColor: "#48474F",
padding: 3,
wordWrap: "break-word",
mt: 1,
borderRadius: 1,
}}
>
<pre
style={{
whiteSpace: "pre-wrap",
margin: 0,
backgroundColor: "#48474F",
color: "#FBFBFB",
}}
>
{JSON.stringify(onboardParticipantMsg, null, 2)}{" "}
</pre>
</Box>
<Box
sx={{
paddingBottom: 2,
mt: 2,
}}
>
<LoadingButton
variant="contained"
onClick={async () => {
await sendTransaction(onboardParticipantMsg);
}}
loading={isLoading}
disabled={isTncAccepted ? balance === "0" : !isTncAccepted}
>
Send transaction
</LoadingButton>
</Box>
</Layout>
</>
); );
}; };