Compare commits

..

No commits in common. "iv-rename-cosmos-laconic" and "main" have entirely different histories.

9 changed files with 56 additions and 56 deletions

View File

@ -1,5 +1,5 @@
# testnet-onboarding-app # testnet-onboarding-app
React app for onboarding participants to laconicd chain with Nitro/Laconic key attestation React app for onboarding participants to laconicd chain with Nitro/Cosmos key attestation
## Setup for testnet-onboarding-app ## Setup for testnet-onboarding-app

View File

@ -3,7 +3,7 @@
"version": "0.1.2", "version": "0.1.2",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@cerc-io/registry-sdk": "^0.2.6", "@cerc-io/registry-sdk": "^0.2.5",
"@cosmjs/encoding": "^0.32.4", "@cosmjs/encoding": "^0.32.4",
"@cosmjs/proto-signing": "^0.32.4", "@cosmjs/proto-signing": "^0.32.4",
"@cosmjs/stargate": "^0.32.4", "@cosmjs/stargate": "^0.32.4",

View File

@ -3,7 +3,7 @@ import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import ConnectWallet from "./pages/ConnectWallet"; import ConnectWallet from "./pages/ConnectWallet";
import SignWithNitroKey from "./pages/SignWithNitroKey"; import SignWithNitroKey from "./pages/SignWithNitroKey";
import SignWithLaconic from "./pages/SignWithLaconic"; 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 SignPageLayout from "./layout/SignPageLayout"; import SignPageLayout from "./layout/SignPageLayout";
@ -111,7 +111,7 @@ function App() {
path="/user-verification" path="/user-verification"
element={<UserVerification />} element={<UserVerification />}
/> />
<Route path="/sign-with-laconic" element={<SignWithLaconic />} /> <Route path="/sign-with-cosmos" element={<SignWithCosmos />} />
<Route <Route
path="/onboarding-success" path="/onboarding-success"
element={<OnboardingSuccess />} element={<OnboardingSuccess />}

View File

@ -21,8 +21,8 @@ const registry = new Registry(process.env.REACT_APP_REGISTRY_GQL_ENDPOINT!);
const OnboardingSuccess = () => { const OnboardingSuccess = () => {
const location = useLocation(); const location = useLocation();
const { laconicAddress } = location.state as { const { cosmosAddress } = location.state as {
laconicAddress?: string; cosmosAddress?: string;
}; };
const [participant, setParticipant] = useState<Participant>(); const [participant, setParticipant] = useState<Participant>();
@ -36,14 +36,14 @@ const OnboardingSuccess = () => {
useEffect(() => { useEffect(() => {
const fetchParticipants = async () => { const fetchParticipants = async () => {
try { try {
if (!laconicAddress) { if (!cosmosAddress) {
enqueueSnackbar("Laconic address is not provided", { enqueueSnackbar("Laconic address is not provided", {
variant: "error", variant: "error",
}); });
return; return;
} }
const participant: Participant = const participant: Participant =
await registry.getParticipantByAddress(laconicAddress); await registry.getParticipantByAddress(cosmosAddress);
if (!participant) { if (!participant) {
enqueueSnackbar("Participant not found", { variant: "error" }); enqueueSnackbar("Participant not found", { variant: "error" });
return; return;
@ -58,7 +58,7 @@ const OnboardingSuccess = () => {
}; };
fetchParticipants(); fetchParticipants();
}, [laconicAddress]); }, [cosmosAddress]);
useEffect(() => { useEffect(() => {
const getToken = async (userId: string) => { const getToken = async (userId: string) => {
@ -67,13 +67,13 @@ const OnboardingSuccess = () => {
setLoading(false); setLoading(false);
}; };
if (laconicAddress && ENABLE_KYC) { if (cosmosAddress && ENABLE_KYC) {
getToken(laconicAddress).catch((error) => { getToken(cosmosAddress).catch((error) => {
console.error(error); console.error(error);
alert("Failed to fetch token"); alert("Failed to fetch token");
}); });
} }
}, [laconicAddress]); }, [cosmosAddress]);
return ( return (
<> <>
@ -92,7 +92,7 @@ const OnboardingSuccess = () => {
<CodeBlock> <CodeBlock>
{participant && ( {participant && (
<div> <div>
Laconic Address: {participant.laconicAddress} <br /> Laconic Address: {participant.cosmosAddress} <br />
Nitro Address: {participant.nitroAddress} <br /> Nitro Address: {participant.nitroAddress} <br />
Role: {participant.role} <br /> Role: {participant.role} <br />
KYC ID: {participant.kycId} <br /> KYC ID: {participant.kycId} <br />
@ -103,11 +103,11 @@ const OnboardingSuccess = () => {
{ENABLE_KYC ? ( {ENABLE_KYC ? (
<Box> <Box>
<Typography variant="h5">KYC Status</Typography> <Typography variant="h5">KYC Status</Typography>
{!loading && token && laconicAddress && ( {!loading && token && cosmosAddress && (
<SumsubWebSdk <SumsubWebSdk
accessToken={token} accessToken={token}
expirationHandler={getAccessTokenExpirationHandler( expirationHandler={getAccessTokenExpirationHandler(
laconicAddress, cosmosAddress,
)} )}
config={config} config={config}
options={options} options={options}

View File

@ -16,7 +16,7 @@ import { HASHED_SUBSCRIBER_ID_KEY } from "../constants";
import { Layout } from "../layout/Layout"; import { Layout } from "../layout/Layout";
import { CodeBlock } from "../components/CodeBlock"; import { CodeBlock } from "../components/CodeBlock";
const SignWithLaconic = () => { const SignWithCosmos = () => {
const { session, signClient } = useWalletConnectContext(); const { session, signClient } = useWalletConnectContext();
const location = useLocation(); const location = useLocation();
@ -30,21 +30,21 @@ const SignWithLaconic = () => {
const { const {
message: innerMessage, message: innerMessage,
laconicAddress, cosmosAddress,
receivedEthSig: ethSignature, receivedEthSig: ethSignature,
} = location.state as { } = location.state as {
message?: { message?: {
msg: string; msg: string;
address: string; address: string;
}; };
laconicAddress?: string; cosmosAddress?: string;
receivedEthSig?: string; receivedEthSig?: string;
}; };
const ethAddress = innerMessage!.address; const ethAddress = innerMessage!.address;
const subscriberIdHash = localStorage.getItem(HASHED_SUBSCRIBER_ID_KEY); const subscriberIdHash = localStorage.getItem(HASHED_SUBSCRIBER_ID_KEY);
const createLaconicClient = useCallback(async (endpoint: string) => { const createCosmosClient = useCallback(async (endpoint: string) => {
return await StargateClient.connect(endpoint); return await StargateClient.connect(endpoint);
}, []); }, []);
@ -53,14 +53,14 @@ const SignWithLaconic = () => {
return { return {
typeUrl: typeUrlMsgOnboardParticipant, typeUrl: typeUrlMsgOnboardParticipant,
value: { value: {
participant: laconicAddress!, participant: cosmosAddress!,
ethPayload: innerMessage, ethPayload: innerMessage,
ethSignature: ethSignature!, ethSignature: ethSignature!,
kycId: subscriberIdHash!, kycId: subscriberIdHash!,
role, role,
}, },
}; };
}, [laconicAddress, innerMessage, ethSignature, subscriberIdHash, role]); }, [cosmosAddress, innerMessage, ethSignature, subscriberIdHash, role]);
const handleTokenRequest = async () => { const handleTokenRequest = async () => {
try { try {
@ -73,7 +73,7 @@ const SignWithLaconic = () => {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
body: JSON.stringify({ body: JSON.stringify({
address: laconicAddress, address: cosmosAddress,
}), }),
}, },
); );
@ -115,7 +115,7 @@ const SignWithLaconic = () => {
variant: "info", variant: "info",
}); });
const params = { transactionMessage, signer: laconicAddress }; const params = { transactionMessage, signer: cosmosAddress };
const responseFromWallet = await signClient!.request<{ const responseFromWallet = await signClient!.request<{
code: number; code: number;
}>({ }>({
@ -131,7 +131,7 @@ const SignWithLaconic = () => {
} else { } else {
navigate("/onboarding-success", { navigate("/onboarding-success", {
state: { state: {
laconicAddress, cosmosAddress,
}, },
}); });
} }
@ -145,11 +145,11 @@ const SignWithLaconic = () => {
const getBalances = useCallback(async () => { const getBalances = useCallback(async () => {
try { try {
const cosmosClient = await createLaconicClient( const cosmosClient = await createCosmosClient(
process.env.REACT_APP_LACONICD_RPC_ENDPOINT!, process.env.REACT_APP_LACONICD_RPC_ENDPOINT!,
); );
const balance = await cosmosClient.getBalance( const balance = await cosmosClient.getBalance(
laconicAddress!, cosmosAddress!,
process.env.REACT_APP_LACONICD_DENOM!, process.env.REACT_APP_LACONICD_DENOM!,
); );
setBalance(balance.amount); setBalance(balance.amount);
@ -157,7 +157,7 @@ const SignWithLaconic = () => {
console.error("Error fetching balance:", error); console.error("Error fetching balance:", error);
throw error; throw error;
} }
}, [laconicAddress, createLaconicClient]); }, [cosmosAddress, createCosmosClient]);
useEffect(() => { useEffect(() => {
getBalances(); getBalances();
@ -179,7 +179,7 @@ const SignWithLaconic = () => {
<Layout title="Send transaction to chain" noBackButton> <Layout title="Send transaction to chain" noBackButton>
<Typography>Laconic Account:</Typography> <Typography>Laconic Account:</Typography>
<Box sx={{ backgroundColor: "#29292E", p: 2, borderRadius: 1, mb: 2 }}> <Box sx={{ backgroundColor: "#29292E", p: 2, borderRadius: 1, mb: 2 }}>
<Typography variant="body1">Address: {laconicAddress}</Typography> <Typography variant="body1">Address: {cosmosAddress}</Typography>
<Typography variant="body1"> <Typography variant="body1">
Balance: {balance} {process.env.REACT_APP_LACONICD_DENOM} Balance: {balance} {process.env.REACT_APP_LACONICD_DENOM}
</Typography> </Typography>
@ -219,4 +219,4 @@ const SignWithLaconic = () => {
); );
}; };
export default SignWithLaconic; export default SignWithCosmos;

View File

@ -33,7 +33,7 @@ const SignWithNitroKey = () => {
const [ethAddress, setEthAddress] = useState(""); const [ethAddress, setEthAddress] = useState("");
const [ethSignature, setEthSignature] = useState(""); const [ethSignature, setEthSignature] = useState("");
const [laconicAddress, setLaconicAddress] = useState(""); const [cosmosAddress, setCosmosAddress] = useState("");
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
@ -84,15 +84,15 @@ const SignWithNitroKey = () => {
navigate("/user-verification", { navigate("/user-verification", {
state: { state: {
message, message,
laconicAddress, cosmosAddress,
receivedEthSig, receivedEthSig,
}, },
}); });
} else { } else {
navigate("/sign-with-laconic", { navigate("/sign-with-cosmos", {
state: { state: {
message, message,
laconicAddress, cosmosAddress,
receivedEthSig, receivedEthSig,
}, },
}); });
@ -113,9 +113,9 @@ const SignWithNitroKey = () => {
<Select <Select
labelId="demo-simple-select-label" labelId="demo-simple-select-label"
id="demo-simple-select" id="demo-simple-select"
value={laconicAddress} value={cosmosAddress}
onChange={(e: any) => { onChange={(e: any) => {
setLaconicAddress(e.target.value); setCosmosAddress(e.target.value);
}} }}
style={{ maxWidth: "600px", display: "block" }} style={{ maxWidth: "600px", display: "block" }}
> >
@ -142,7 +142,7 @@ const SignWithNitroKey = () => {
))} ))}
</Select> </Select>
{Boolean(ethAddress) && Boolean(laconicAddress) && ( {Boolean(ethAddress) && Boolean(cosmosAddress) && (
<CodeBlock>{canonicalStringify(message, null, 2)} </CodeBlock> <CodeBlock>{canonicalStringify(message, null, 2)} </CodeBlock>
)} )}
<Box> <Box>

View File

@ -18,13 +18,13 @@ const UserVerification = () => {
const location = useLocation(); const location = useLocation();
const navigate = useNavigate(); const navigate = useNavigate();
const {message, laconicAddress, receivedEthSig} = location.state as { const {message, cosmosAddress, receivedEthSig} = location.state as {
message?: string; message?: string;
laconicAddress?: string; cosmosAddress?: string;
receivedEthSig?: string; receivedEthSig?: string;
}; };
const userId = laconicAddress; const userId = cosmosAddress;
useEffect(() => { useEffect(() => {
const getToken = async (userId: string) => { const getToken = async (userId: string) => {
@ -46,15 +46,15 @@ const UserVerification = () => {
if (applicationSubmitted && kycId !== '') { if (applicationSubmitted && kycId !== '') {
const kycIdHash = ethers.utils.sha256(ethers.utils.toUtf8Bytes(kycId)); const kycIdHash = ethers.utils.sha256(ethers.utils.toUtf8Bytes(kycId));
navigate("/sign-with-laconic", { navigate("/sign-with-cosmos", {
state: { state: {
message, message,
laconicAddress, cosmosAddress,
receivedEthSig, receivedEthSig,
kycIdHash kycIdHash
}}); }});
} }
}, [applicationSubmitted, kycId, navigate, laconicAddress, message, receivedEthSig]); }, [applicationSubmitted, kycId, navigate, cosmosAddress, message, receivedEthSig]);
const messageHandler: MessageHandler = (event, payload) => { const messageHandler: MessageHandler = (event, payload) => {
console.log('sumsubEvent:', event, payload); console.log('sumsubEvent:', event, payload);

View File

@ -25,7 +25,7 @@ const Validator = () => {
const { session, signClient, isSessionLoading } = useWalletConnectContext(); const { session, signClient, isSessionLoading } = useWalletConnectContext();
const navigate = useNavigate(); const navigate = useNavigate();
const [laconicAddress, setLaconicAddress] = useState(""); const [cosmosAddress, setCosmosAddress] = useState("");
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [moniker, setMoniker] = useState(""); const [moniker, setMoniker] = useState("");
const [pubKey, setPubKey] = useState(""); const [pubKey, setPubKey] = useState("");
@ -43,7 +43,7 @@ const Validator = () => {
}, [session, navigate, isSessionLoading]); }, [session, navigate, isSessionLoading]);
useEffect(() => { useEffect(() => {
if (!laconicAddress) { if (!cosmosAddress) {
setParticipant(null); setParticipant(null);
return; return;
} }
@ -55,7 +55,7 @@ const Validator = () => {
try { try {
const fetchedParticipant = const fetchedParticipant =
await registry.getParticipantByAddress(laconicAddress); await registry.getParticipantByAddress(cosmosAddress);
if (fetchedParticipant) { if (fetchedParticipant) {
setParticipant(fetchedParticipant); setParticipant(fetchedParticipant);
} else { } else {
@ -69,7 +69,7 @@ const Validator = () => {
}; };
fetchParticipant(); fetchParticipant();
}, [laconicAddress]); }, [cosmosAddress]);
const isMonikerValid = useMemo(() => moniker.trim().length > 0, [moniker]); const isMonikerValid = useMemo(() => moniker.trim().length > 0, [moniker]);
const isPubKeyValid = useMemo(() => pubKey.length === 44, [pubKey]); const isPubKeyValid = useMemo(() => pubKey.length === 44, [pubKey]);
@ -96,15 +96,15 @@ const Validator = () => {
minSelfDelegation: "1", minSelfDelegation: "1",
delegatorAddress: "", delegatorAddress: "",
validatorAddress: validatorAddress:
laconicAddress && cosmosAddress &&
toBech32("laconicvaloper", fromBech32(laconicAddress).data), toBech32("laconicvaloper", fromBech32(cosmosAddress).data),
pubkey: encodedPubKey, pubkey: encodedPubKey,
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!,
}, },
}; };
}, [laconicAddress, pubKey, moniker]); }, [cosmosAddress, pubKey, moniker]);
const msgCreateValidatorEncodeObject: EncodeObject = { const msgCreateValidatorEncodeObject: EncodeObject = {
typeUrl: "/cosmos.staking.v1beta1.MsgCreateValidator", typeUrl: "/cosmos.staking.v1beta1.MsgCreateValidator",
@ -129,7 +129,7 @@ const Validator = () => {
try { try {
const params = { const params = {
transactionMessage: msgCreateValidatorEncodeObject, transactionMessage: msgCreateValidatorEncodeObject,
signer: laconicAddress, signer: cosmosAddress,
}; };
const response = await signClient!.request<{ code: number }>({ const response = await signClient!.request<{ code: number }>({
topic: session!.topic, topic: session!.topic,
@ -167,9 +167,9 @@ const Validator = () => {
<Typography variant="body1">Select Laconic account:</Typography> <Typography variant="body1">Select Laconic account:</Typography>
<Select <Select
sx={{ marginBottom: 2 }} sx={{ marginBottom: 2 }}
id="laconic-address-select" id="cosmos-address-select"
value={laconicAddress} value={cosmosAddress}
onChange={(e) => setLaconicAddress(e.target.value)} onChange={(e) => 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) => (
@ -179,7 +179,7 @@ const Validator = () => {
))} ))}
</Select> </Select>
{Boolean(laconicAddress) && ( {Boolean(cosmosAddress) && (
<> <>
{participant ? ( {participant ? (
<Typography>Onboarded participant</Typography> <Typography>Onboarded participant</Typography>
@ -189,7 +189,7 @@ const Validator = () => {
{participant && ( {participant && (
<CodeBlock> <CodeBlock>
Laconic Address: {participant.laconicAddress} <br /> Laconic Address: {participant.cosmosAddress} <br />
Nitro Address: {participant.nitroAddress} <br /> Nitro Address: {participant.nitroAddress} <br />
Role: {participant.role} <br /> Role: {participant.role} <br />
KYC ID: {participant.kycId} <br /> KYC ID: {participant.kycId} <br />

View File

@ -1,5 +1,5 @@
export interface Participant { export interface Participant {
laconicAddress: string; cosmosAddress: string;
nitroAddress: string; nitroAddress: string;
role: string; role: string;
kycId: string; kycId: string;