Integrate sumsub KYC with terms & conditions #6
14
src/App.tsx
14
src/App.tsx
@ -6,28 +6,32 @@ import SignWithNitroKey from "./pages/SignWithNitroKey";
|
|||||||
import SignWithCosmos from "./pages/SignWithCosmos";
|
import SignWithCosmos from "./pages/SignWithCosmos";
|
||||||
import PageNotFound from "./pages/PageNotFound";
|
import PageNotFound from "./pages/PageNotFound";
|
||||||
import OnboardingSuccess from "./pages/OnboardingSuccess";
|
import OnboardingSuccess from "./pages/OnboardingSuccess";
|
||||||
import UserVerification from "./pages/UserVerification";
|
|
||||||
import SignPageLayout from "./layout/SignPageLayout";
|
import SignPageLayout from "./layout/SignPageLayout";
|
||||||
|
import UserVerification from "./pages/UserVerification";
|
||||||
|
import TermsAndConditions from "./pages/TermsAndConditions";
|
||||||
|
import Header from "./components/Header";
|
||||||
import { WalletConnectProvider } from "./context/WalletConnectContext";
|
import { WalletConnectProvider } from "./context/WalletConnectContext";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<Router>
|
<Router>
|
||||||
|
<Header />
|
||||||
<WalletConnectProvider>
|
<WalletConnectProvider>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<ConnectWallet />} />
|
<Route path="/" element={<TermsAndConditions />} />
|
||||||
<Route
|
<Route
|
||||||
path="/user-verification"
|
path="/user-verification"
|
||||||
element={<UserVerification />}
|
element={<UserVerification />}
|
||||||
/>
|
/>
|
||||||
|
<Route path="/connect-wallet" element={<ConnectWallet />} />
|
||||||
<Route element={<SignPageLayout />}>
|
<Route element={<SignPageLayout />}>
|
||||||
<Route path="/sign-with-nitro-key/:userId" element={<SignWithNitroKey />} />
|
<Route path="/sign-with-nitro-key" element={<SignWithNitroKey />} />
|
||||||
<Route
|
<Route
|
||||||
path="/sign-with-cosmos/:cosmosAddress/:ethSignature"
|
path="/sign-with-cosmos"
|
||||||
element={<SignWithCosmos />}
|
element={<SignWithCosmos />}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path="/onboarding-success/:cosmosAddress"
|
path="/onboarding-success"
|
||||||
element={<OnboardingSuccess />}
|
element={<OnboardingSuccess />}
|
||||||
></Route>
|
></Route>
|
||||||
</Route>
|
</Route>
|
||||||
|
33
src/components/Header.tsx
Normal file
33
src/components/Header.tsx
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Link, useLocation } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { AppBar, Toolbar, Avatar, Box, IconButton } from '@mui/material';
|
||||||
|
|
||||||
|
const Header: React.FC = () => {
|
||||||
|
const location = useLocation()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AppBar position="static" color="inherit">
|
||||||
|
<Toolbar>
|
||||||
|
<Link to={location.pathname === "/" ? "/" : "/connect-wallet"} style={{ color: "inherit", textDecoration: "none" }}>
|
||||||
|
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||||
|
<Avatar
|
||||||
|
alt="Laconic logo"
|
||||||
|
src="https://avatars.githubusercontent.com/u/92608123"
|
||||||
|
/>
|
||||||
|
<IconButton
|
||||||
|
edge="start"
|
||||||
|
color="inherit"
|
||||||
|
aria-label="menu"
|
||||||
|
sx={{ ml: 2, mr: 2 }}
|
||||||
|
>
|
||||||
|
Testnet Onboarding
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
</Link>
|
||||||
|
</Toolbar>
|
||||||
|
</AppBar>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Header;
|
81
src/components/TermsAndConditionsCard.tsx
Normal file
81
src/components/TermsAndConditionsCard.tsx
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
|
import { Typography, Button, Box, Paper, Radio, RadioGroup, FormControlLabel, FormControl, FormLabel, Link, Checkbox } from '@mui/material';
|
||||||
|
import { Role } from '@cerc-io/registry-sdk/dist/proto/cerc/onboarding/v1/onboarding';
|
||||||
|
|
||||||
|
import TermsAndConditionsDialog from './TermsAndConditionsDialog';
|
||||||
|
|
||||||
|
const VALIDATOR_OPTION = "validator";
|
||||||
|
const PARTICIPANT_OPTION = "participant";
|
||||||
|
|
||||||
|
const TermsAndConditionsCard = ({ handleAccept, handleRoleChange }: { handleAccept: () => void, handleRoleChange: (role: Role) => void }) => {
|
||||||
|
const [selectedRole, setSelectedRole] = useState(PARTICIPANT_OPTION);
|
||||||
|
const [checked, setChecked] = useState(false);
|
||||||
|
const [isHidden, setIsHidden] = useState(false);
|
||||||
|
|
||||||
|
const [isDialogOpen, setisDialogOpen] = useState(false)
|
||||||
|
|
||||||
|
const handleCheckboxChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setChecked(event.target.checked);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleContinue = () => {
|
||||||
|
handleAccept()
|
||||||
|
setIsHidden(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleRadioChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setSelectedRole((event.target as HTMLInputElement).value);
|
||||||
|
handleRoleChange((event.target as HTMLInputElement).value === VALIDATOR_OPTION ? Role.ROLE_VALIDATOR : Role.ROLE_PARTICIPANT);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Paper elevation={3} style={{ padding: '2rem', marginTop: '2rem', display: isHidden ? "none" : "block" }}>
|
||||||
|
<FormControl component="fieldset">
|
||||||
|
<FormLabel component="legend">Select your role</FormLabel>
|
||||||
|
<RadioGroup
|
||||||
|
aria-label="roles"
|
||||||
|
name="roles"
|
||||||
|
value={selectedRole}
|
||||||
|
onChange={handleRadioChange}
|
||||||
|
>
|
||||||
|
<FormControlLabel
|
||||||
|
value={VALIDATOR_OPTION}
|
||||||
|
control={<Radio />}
|
||||||
|
label="Validator"
|
||||||
|
/>
|
||||||
|
<FormControlLabel
|
||||||
|
value={PARTICIPANT_OPTION}
|
||||||
|
control={<Radio />}
|
||||||
|
label="Participant"
|
||||||
|
/>
|
||||||
|
</RadioGroup>
|
||||||
|
</FormControl>
|
||||||
|
<Box mt={2} display="flex" alignItems="center">
|
||||||
|
<Checkbox
|
||||||
|
checked={checked}
|
||||||
|
onChange={handleCheckboxChange}
|
||||||
|
color="primary"
|
||||||
|
/>
|
||||||
|
<Typography variant="body1">
|
||||||
|
I accept the <Link onClick={() => setisDialogOpen(true)} target="_blank" rel="noopener">
|
||||||
|
terms and conditions
|
||||||
|
</Link>
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box mt={4} display="flex" justifyContent="end">
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
onClick={handleContinue}
|
||||||
|
disabled={!checked}
|
||||||
|
>
|
||||||
|
Continue
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
<TermsAndConditionsDialog isValidator = { selectedRole === VALIDATOR_OPTION } open={isDialogOpen} onClose={() => setisDialogOpen(false)}/>
|
||||||
|
</Paper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TermsAndConditionsCard;
|
34
src/components/TermsAndConditionsDialog.tsx
Normal file
34
src/components/TermsAndConditionsDialog.tsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Button, Typography } from '@mui/material';
|
||||||
|
|
||||||
|
import { TNC_CONTENT } from '../constants';
|
||||||
|
|
||||||
|
interface TermsDialogProps {
|
||||||
|
isValidator: boolean;
|
||||||
|
open: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TermsAndConditionsDialog: React.FC<TermsDialogProps> = ({ isValidator, open, onClose }) => {
|
||||||
|
return (
|
||||||
|
<Dialog open={open} onClose={onClose}>
|
||||||
|
<DialogTitle>Terms and Conditions</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<Typography variant="h6" gutterBottom>
|
||||||
|
Onboard as a {isValidator ? "validator" : "participant"}
|
||||||
|
</Typography>
|
||||||
|
<DialogContentText>
|
||||||
|
<div dangerouslySetInnerHTML={{__html: TNC_CONTENT}} />
|
||||||
|
</DialogContentText>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={onClose} color="primary">
|
||||||
|
Close
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TermsAndConditionsDialog;
|
9
src/constants.ts
Normal file
9
src/constants.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
export const TNC_CONTENT = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. <br/>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. <br/>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. <br/>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. <br/>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. <br/>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. <br/>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. <br/>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. <br/>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`;
|
@ -1,14 +1,12 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Outlet, useNavigate, Link } from "react-router-dom";
|
import { Outlet, useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Toolbar,
|
Toolbar,
|
||||||
IconButton,
|
|
||||||
Avatar,
|
Avatar,
|
||||||
Button,
|
Button,
|
||||||
Typography,
|
Typography,
|
||||||
Container,
|
Container
|
||||||
Box,
|
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
|
|
||||||
import { useWalletConnectContext } from "../context/WalletConnectContext";
|
import { useWalletConnectContext } from "../context/WalletConnectContext";
|
||||||
@ -25,22 +23,6 @@ const SignPageLayout = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Toolbar variant="dense">
|
<Toolbar variant="dense">
|
||||||
<Link to="/" style={{ color: "inherit", textDecoration: "none" }}>
|
|
||||||
<Box sx={{ display: "flex", alignItems: "center" }}>
|
|
||||||
<Avatar
|
|
||||||
alt="Laconic logo"
|
|
||||||
src="https://avatars.githubusercontent.com/u/92608123"
|
|
||||||
/>
|
|
||||||
<IconButton
|
|
||||||
edge="start"
|
|
||||||
color="inherit"
|
|
||||||
aria-label="menu"
|
|
||||||
sx={{ ml: 2, mr: 2 }}
|
|
||||||
>
|
|
||||||
Testnet Onboarding
|
|
||||||
</IconButton>
|
|
||||||
</Box>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import { Typography, Button, Box, Container, Avatar } from "@mui/material";
|
import { Button, Box, Container } from "@mui/material";
|
||||||
|
|
||||||
import { useWalletConnectContext } from "../context/WalletConnectContext";
|
import { useWalletConnectContext } from "../context/WalletConnectContext";
|
||||||
|
|
||||||
@ -10,11 +10,16 @@ const ConnectWallet = () => {
|
|||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const location = useLocation();
|
||||||
|
const queryParams = new URLSearchParams(location.search);
|
||||||
|
const kycId = queryParams.get('kycId');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
if (session) {
|
if (session) {
|
||||||
navigate("/user-verification");
|
navigate(`/sign-with-nitro-key?kycId=${kycId}`);
|
||||||
}
|
}
|
||||||
}, [session, navigate]);
|
}, [session, navigate, kycId]);
|
||||||
|
|
||||||
const handler = async () => {
|
const handler = async () => {
|
||||||
await connect();
|
await connect();
|
||||||
@ -30,28 +35,12 @@ const ConnectWallet = () => {
|
|||||||
justifyContent="center"
|
justifyContent="center"
|
||||||
padding={5}
|
padding={5}
|
||||||
>
|
>
|
||||||
<Box display="flex" alignItems="center">
|
|
||||||
<Avatar
|
|
||||||
alt="Laconic logo"
|
|
||||||
src="https://avatars.githubusercontent.com/u/92608123"
|
|
||||||
/>
|
|
||||||
<Typography
|
|
||||||
variant="h4"
|
|
||||||
component="h6"
|
|
||||||
style={{ marginLeft: "10px" }}
|
|
||||||
>
|
|
||||||
Testnet Onboarding
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
<Typography variant="h6" component="h6" style={{ marginTop: "30px" }}>
|
|
||||||
Connect wallet
|
|
||||||
</Typography>
|
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
onClick={handler}
|
onClick={handler}
|
||||||
style={{ marginTop: "20px" }}
|
style={{ marginTop: "20px" }}
|
||||||
>
|
>
|
||||||
Connect
|
Connect Wallet
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
</Container>
|
</Container>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { SnackbarProvider, enqueueSnackbar } from "notistack";
|
import { SnackbarProvider, enqueueSnackbar } from "notistack";
|
||||||
import { useParams } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
|
|
||||||
import { Box, Typography } from "@mui/material";
|
import { Box, Typography } from "@mui/material";
|
||||||
import { Registry } from "@cerc-io/registry-sdk";
|
import { Registry } from "@cerc-io/registry-sdk";
|
||||||
@ -15,7 +15,9 @@ const registry = new Registry(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const OnboardingSuccess = () => {
|
const OnboardingSuccess = () => {
|
||||||
const { cosmosAddress } = useParams();
|
const location = useLocation();
|
||||||
|
const queryParams = new URLSearchParams(location.search);
|
||||||
|
const cosmosAddress = queryParams.get('cosmosAddress');
|
||||||
|
|
||||||
const [participant, setParticipant] = useState<Participant>();
|
const [participant, setParticipant] = useState<Participant>();
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import { useParams, useLocation, useNavigate } from "react-router-dom";
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
import { SnackbarProvider, enqueueSnackbar } from "notistack";
|
import { SnackbarProvider, enqueueSnackbar } from "notistack";
|
||||||
|
|
||||||
import { Box, Card, CardContent, Grid, Typography } from "@mui/material";
|
import { Box, Card, CardContent, Grid, Typography } from "@mui/material";
|
||||||
@ -8,21 +8,28 @@ import {
|
|||||||
MsgOnboardParticipantEncodeObject,
|
MsgOnboardParticipantEncodeObject,
|
||||||
typeUrlMsgOnboardParticipant,
|
typeUrlMsgOnboardParticipant,
|
||||||
} from "@cerc-io/registry-sdk";
|
} from "@cerc-io/registry-sdk";
|
||||||
|
import { Role } from "@cerc-io/registry-sdk/dist/proto/cerc/onboarding/v1/onboarding";
|
||||||
import { StargateClient } from "@cosmjs/stargate";
|
import { StargateClient } from "@cosmjs/stargate";
|
||||||
|
|
||||||
import { useWalletConnectContext } from "../context/WalletConnectContext";
|
import { useWalletConnectContext } from "../context/WalletConnectContext";
|
||||||
|
import TermsAndConditionsCard from "../components/TermsAndConditionsCard";
|
||||||
|
|
||||||
const SignWithCosmos = () => {
|
const SignWithCosmos = () => {
|
||||||
const { session, signClient } = useWalletConnectContext();
|
const { session, signClient } = useWalletConnectContext();
|
||||||
|
|
||||||
const { cosmosAddress, ethSignature } = useParams();
|
const location = useLocation();
|
||||||
|
const queryParams = new URLSearchParams(location.search);
|
||||||
|
const cosmosAddress = queryParams.get('cosmosAddress');
|
||||||
|
const ethSignature = queryParams.get('ethSignature');
|
||||||
|
const kycId = queryParams.get('kycId');
|
||||||
|
|
||||||
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 [role, setRole] = useState(Role.ROLE_PARTICIPANT);
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const location = useLocation();
|
|
||||||
const innerMessage = location.state;
|
const innerMessage = location.state;
|
||||||
const ethAddress = innerMessage.address;
|
const ethAddress = innerMessage.address;
|
||||||
|
|
||||||
@ -35,12 +42,14 @@ const SignWithCosmos = () => {
|
|||||||
return {
|
return {
|
||||||
typeUrl: typeUrlMsgOnboardParticipant,
|
typeUrl: typeUrlMsgOnboardParticipant,
|
||||||
value: {
|
value: {
|
||||||
participant: cosmosAddress,
|
participant: cosmosAddress!,
|
||||||
ethPayload: innerMessage,
|
ethPayload: innerMessage,
|
||||||
ethSignature,
|
ethSignature: ethSignature!,
|
||||||
|
kycId: kycId!,
|
||||||
|
role
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}, [cosmosAddress, innerMessage, ethSignature]);
|
}, [cosmosAddress, innerMessage, ethSignature, kycId, role]);
|
||||||
|
|
||||||
const handleTokenRequest = async () => {
|
const handleTokenRequest = async () => {
|
||||||
try {
|
try {
|
||||||
@ -100,7 +109,7 @@ const SignWithCosmos = () => {
|
|||||||
if (responseFromWallet.code !== 0) {
|
if (responseFromWallet.code !== 0) {
|
||||||
enqueueSnackbar("Transaction not sent", { variant: "error" });
|
enqueueSnackbar("Transaction not sent", { variant: "error" });
|
||||||
} else {
|
} else {
|
||||||
navigate(`/onboarding-success/${cosmosAddress}`);
|
navigate(`/onboarding-success?cosmosAddress=${cosmosAddress}`);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@ -130,10 +139,12 @@ const SignWithCosmos = () => {
|
|||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
marginTop: "100px",
|
marginY: "100px",
|
||||||
gap: "10px",
|
gap: "10px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<Typography variant="h5">Please accept terms and conditions to continue</Typography>
|
||||||
|
<TermsAndConditionsCard handleAccept={() => setIsTncAccepted(true)} handleRoleChange={setRole}/>
|
||||||
<Typography variant="h5">Send transaction to chain</Typography>
|
<Typography variant="h5">Send transaction to chain</Typography>
|
||||||
<Typography>Cosmos Account:</Typography>
|
<Typography>Cosmos Account:</Typography>
|
||||||
<Card className='mt-1 mb-1'>
|
<Card className='mt-1 mb-1'>
|
||||||
@ -147,7 +158,7 @@ const SignWithCosmos = () => {
|
|||||||
<LoadingButton
|
<LoadingButton
|
||||||
variant="contained"
|
variant="contained"
|
||||||
onClick={handleTokenRequest}
|
onClick={handleTokenRequest}
|
||||||
disabled={isRequesting}
|
disabled={isTncAccepted ? isRequesting : !isTncAccepted}
|
||||||
loading={isRequesting}
|
loading={isRequesting}
|
||||||
>
|
>
|
||||||
Request tokens from Faucet
|
Request tokens from Faucet
|
||||||
@ -178,7 +189,7 @@ const SignWithCosmos = () => {
|
|||||||
await sendTransaction(onboardParticipantMsg);
|
await sendTransaction(onboardParticipantMsg);
|
||||||
}}
|
}}
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
disabled={balance === '0'}
|
disabled={isTncAccepted ? (balance === '0') : !isTncAccepted}
|
||||||
>
|
>
|
||||||
Send transaction
|
Send transaction
|
||||||
</LoadingButton>
|
</LoadingButton>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useMemo, useEffect } from "react";
|
import React, { useState, useMemo, useEffect } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
import { SnackbarProvider, enqueueSnackbar } from "notistack";
|
import { SnackbarProvider, enqueueSnackbar } from "notistack";
|
||||||
import canonicalStringify from "canonical-json";
|
import canonicalStringify from "canonical-json";
|
||||||
|
|
||||||
@ -15,6 +15,10 @@ import { utf8ToHex } from "@walletconnect/encoding";
|
|||||||
import { useWalletConnectContext } from "../context/WalletConnectContext";
|
import { useWalletConnectContext } from "../context/WalletConnectContext";
|
||||||
|
|
||||||
const SignWithNitroKey = () => {
|
const SignWithNitroKey = () => {
|
||||||
|
const location = useLocation();
|
||||||
|
const queryParams = new URLSearchParams(location.search);
|
||||||
|
const kycId = queryParams.get('kycId');
|
||||||
|
|
||||||
const { session, signClient, checkPersistedState } =
|
const { session, signClient, checkPersistedState } =
|
||||||
useWalletConnectContext();
|
useWalletConnectContext();
|
||||||
|
|
||||||
@ -55,7 +59,7 @@ const SignWithNitroKey = () => {
|
|||||||
});
|
});
|
||||||
setIsLoading(false)
|
setIsLoading(false)
|
||||||
setEthSignature(ethSignature);
|
setEthSignature(ethSignature);
|
||||||
navigate(`/sign-with-cosmos/${cosmosAddress}/${receivedEthSig}`, {
|
navigate(`/sign-with-cosmos?cosmosAddress=${cosmosAddress}ðSignature=${receivedEthSig}&kycId=${kycId}`, {
|
||||||
state: message,
|
state: message,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
44
src/pages/TermsAndConditions.tsx
Normal file
44
src/pages/TermsAndConditions.tsx
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { Container, Typography, Button, Box, Paper } from '@mui/material';
|
||||||
|
|
||||||
|
import { TNC_CONTENT } from '../constants';
|
||||||
|
|
||||||
|
const TermsAndConditions = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const handleAccept = () => {
|
||||||
|
navigate('/user-verification');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container maxWidth="md">
|
||||||
|
<Paper elevation={3} style={{ padding: '2rem', marginTop: '2rem', height: '80vh', display: 'flex', flexDirection: 'column' }}>
|
||||||
|
<Typography variant="h4" gutterBottom>
|
||||||
|
Terms and Conditions
|
||||||
|
</Typography>
|
||||||
|
<Box
|
||||||
|
style={{
|
||||||
|
overflowY: 'auto',
|
||||||
|
flexGrow: 1,
|
||||||
|
paddingRight: '1rem',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography variant="body1" gutterBottom>
|
||||||
|
<div dangerouslySetInnerHTML={{__html: TNC_CONTENT}} />
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
</Box>
|
||||||
|
<Box mt={2} display="flex" justifyContent="center">
|
||||||
|
<Button variant="contained" color="primary" onClick={handleAccept}>
|
||||||
|
Accept
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Paper>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TermsAndConditions;
|
@ -15,16 +15,16 @@ const options = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const UserVerification = () => {
|
const UserVerification = () => {
|
||||||
const [userId, setUserId] = useState<String>('');
|
const [kycId, setKycId] = useState<String>('');
|
||||||
const [applicationSubmitted, setApplicationSubmitted] = useState<boolean>(false);
|
const [applicationSubmitted, setApplicationSubmitted] = useState<boolean>(false);
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
if (applicationSubmitted && userId !== '') {
|
if (applicationSubmitted && kycId !== '') {
|
||||||
navigate(`/sign-with-nitro-key/${userId}`)
|
navigate(`/connect-wallet?kycId=${kycId}`)
|
||||||
}
|
}
|
||||||
}, [applicationSubmitted, userId, navigate]);
|
}, [applicationSubmitted, kycId, navigate]);
|
||||||
|
|
||||||
// TODO: Implement
|
// TODO: Implement
|
||||||
const accessTokenExpirationHandler = async () => {
|
const accessTokenExpirationHandler = async () => {
|
||||||
@ -41,7 +41,7 @@ const UserVerification = () => {
|
|||||||
|
|
||||||
const messageHandler = (event: any, payload: any ) => {
|
const messageHandler = (event: any, payload: any ) => {
|
||||||
if (event === 'idCheck.onApplicantLoaded') {
|
if (event === 'idCheck.onApplicantLoaded') {
|
||||||
setUserId(payload.applicantId);
|
setKycId(payload.applicantId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event === 'idCheck.onApplicantSubmitted'){
|
if (event === 'idCheck.onApplicantSubmitted'){
|
||||||
|
Loading…
Reference in New Issue
Block a user