From 359eddd385112539478439dd9a723db77f80d8e3 Mon Sep 17 00:00:00 2001 From: Adwait Gharpure <69599306+Adw8@users.noreply.github.com> Date: Fri, 5 Jul 2024 15:12:57 +0530 Subject: [PATCH] Add support for onboarding to laconicd (#13) * Change logo and app name * Get cosmos address from route * Navigate to second page on receiving eth signature * Add title to page * Use consistent formatting * Handle review changes * Remove unecessary field from onboarding message --- src/App.tsx | 11 +- src/context/WalletConnectContext.tsx | 22 ++-- src/layout/SignPageLayout.tsx | 29 +++-- src/pages/ConnectWallet.tsx | 44 +++++--- src/pages/SignWithCosmos.tsx | 162 +++++++-------------------- src/pages/SignWithEthereum.tsx | 63 ++--------- 6 files changed, 118 insertions(+), 213 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index fe29475..1a58acc 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; +import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; import ConnectWallet from "./pages/ConnectWallet"; import SignWithEthereum from "./pages/SignWithEthereum"; @@ -14,13 +14,16 @@ function App() { } /> - } > + }> } /> - } /> + } + /> } /> - + ); } diff --git a/src/context/WalletConnectContext.tsx b/src/context/WalletConnectContext.tsx index 9ebf509..8d060ca 100644 --- a/src/context/WalletConnectContext.tsx +++ b/src/context/WalletConnectContext.tsx @@ -48,7 +48,7 @@ export const WalletConnectProvider = ({ const [signClient, setSignClient] = useState(); const [session, setSession] = useState(null); const isSignClientInitializing = useRef(false); - const navigate = useNavigate() + const navigate = useNavigate(); const disconnect = useCallback(async () => { if (signClient && session) { @@ -80,7 +80,7 @@ export const WalletConnectProvider = ({ client.on("session_delete", () => { setSession(null); - navigate("/") + navigate("/"); }); }, [navigate] @@ -91,10 +91,10 @@ export const WalletConnectProvider = ({ const signClient = await SignClient.init({ projectId: PROJECT_ID, metadata: { - name: "Urbit onboarding app", - description: "Urbit onboarding app", + name: "Testnet onboarding app", + description: "Testnet onboarding app", url: "localhost:3000", - icons: ["https://avatars.githubusercontent.com/u/5237680?s=200&v=4"], + icons: ["https://avatars.githubusercontent.com/u/92608123"], }, }); @@ -102,7 +102,7 @@ export const WalletConnectProvider = ({ await subscribeToEvents(signClient); await checkPersistedState(signClient); isSignClientInitializing.current = false; - }, [checkPersistedState, subscribeToEvents]) + }, [checkPersistedState, subscribeToEvents]); const connect = async () => { if (!signClient) { @@ -114,10 +114,12 @@ export const WalletConnectProvider = ({ methods: ["personal_sign"], chains: ["eip155:1"], events: [], - },cosmos: { - methods: - ["cosmos_signDirect", "cosmos_signAmino", "cosmos_sendTransaction"], - chains: ["cosmos:cosmoshub-4", "cosmos:laconic_9000-1"], + }, + cosmos: { + methods: [ + "cosmos_sendTransaction", + ], + chains: ["cosmos:cosmoshub-4", "cosmos:laconic_9000-1"], // TODO: Get chain ID from .env events: [], }, }; diff --git a/src/layout/SignPageLayout.tsx b/src/layout/SignPageLayout.tsx index 3fe8744..3bb5e9e 100644 --- a/src/layout/SignPageLayout.tsx +++ b/src/layout/SignPageLayout.tsx @@ -8,7 +8,7 @@ import { Button, Typography, Container, - Box + Box, } from "@mui/material"; import { useWalletConnectContext } from "../context/WalletConnectContext"; @@ -25,19 +25,19 @@ const SignPageLayout = () => { return ( <> - - + + - Urbit + Testnet Onboarding @@ -57,7 +57,13 @@ const SignPageLayout = () => { {session && (
-
+
Connected to: {session.peer.metadata.name}{" "} @@ -65,7 +71,12 @@ const SignPageLayout = () => { variant="square" alt="Peer logo" src={session.peer.metadata.icons[0]} - sx={{ width: 20, height: 20, marginLeft: 1, paddingBottom: 0.5 }} + sx={{ + width: 20, + height: 20, + marginLeft: 1, + paddingBottom: 0.5, + }} />
diff --git a/src/pages/ConnectWallet.tsx b/src/pages/ConnectWallet.tsx index 4a5b23e..c54a46a 100644 --- a/src/pages/ConnectWallet.tsx +++ b/src/pages/ConnectWallet.tsx @@ -1,38 +1,56 @@ -import React, { useEffect } from 'react'; -import { useNavigate } from 'react-router-dom' +import React, { useEffect } from "react"; +import { useNavigate } from "react-router-dom"; -import { Typography, Button, Box, Container, Avatar } from '@mui/material'; +import { Typography, Button, Box, Container, Avatar } from "@mui/material"; import { useWalletConnectContext } from "../context/WalletConnectContext"; const ConnectWallet = () => { const { connect, session } = useWalletConnectContext(); - const navigate = useNavigate() + const navigate = useNavigate(); useEffect(() => { if (session) { - navigate("/sign-with-ethereum") + navigate("/sign-with-ethereum"); } - }, [session, navigate]) + }, [session, navigate]); const handler = async () => { await connect(); - } + }; return ( - + - - - Urbit Onboarding + + + Testnet Onboarding - + Connect wallet - diff --git a/src/pages/SignWithCosmos.tsx b/src/pages/SignWithCosmos.tsx index 4c05006..16aad73 100644 --- a/src/pages/SignWithCosmos.tsx +++ b/src/pages/SignWithCosmos.tsx @@ -1,141 +1,87 @@ import React, { useMemo, useState } from "react"; import { useParams, useLocation } from "react-router-dom"; import { SnackbarProvider, enqueueSnackbar } from "notistack"; -import canonicalStringify from "canonical-json"; -import { - Button, - Dialog, - DialogContent, - DialogActions, - Box, - Typography, -} from "@mui/material"; +import { Box, Typography } from "@mui/material"; import LoadingButton from "@mui/lab/LoadingButton/LoadingButton"; - -// TODO: Import types exported from registry-sdk import { - MsgCreateBondEncodeObject, -} from "@cerc-io/registry-sdk/dist/types/cerc/bond/message"; + MsgOnboardParticipantEncodeObject, + typeUrlMsgOnboardParticipant, +} from "@cerc-io/registry-sdk"; import { useWalletConnectContext } from "../context/WalletConnectContext"; const SignWithCosmos = () => { const { session, signClient } = useWalletConnectContext(); - const { ethAddress, ethSignature } = useParams(); + const { cosmosAddress, ethSignature } = useParams(); - const [openModal, setOpenModal] = useState(false); const [isLoading, setIsLoading] = useState(false); - const [cosmosSignature, setCosmosSignature] = useState(""); const location = useLocation(); const innerMessage = location.state; - const cosmosAddress = innerMessage.address; + const ethAddress = innerMessage.address; - const displayAttestation = useMemo(() => { - return canonicalStringify( - { - payload: { - msg: "Onboarding my Azimuth ID onto UrbitChain", - address: ethAddress, - payload: innerMessage, + const onboardParticipantMsg: MsgOnboardParticipantEncodeObject = + useMemo(() => { + return { + typeUrl: typeUrlMsgOnboardParticipant, + value: { + participant: cosmosAddress, + ethPayload: innerMessage, + ethSignature, }, - signatures: [cosmosSignature, ethSignature], - }, - null, - 2 - ); - }, [ethAddress, cosmosSignature, ethSignature, innerMessage]); + }; + }, [cosmosAddress, innerMessage, ethSignature]); - const message = useMemo(() => { - return { - msg: "Onboarding my Azimuth ID onto UrbitChain", - address: ethAddress, - payload: innerMessage, - }; - }, [ethAddress, innerMessage]); - - const signCosmos = async () => { + const sendTransaction = async ( + transactionMessage: MsgOnboardParticipantEncodeObject + ) => { if (!ethAddress) { + enqueueSnackbar("Set ethereum address"); return; } + try { setIsLoading(true); - const signDoc = { - msgs: [], - fee: { amount: [], gas: "23" }, - chain_id: "cosmos:cosmoshub-4", - memo: canonicalStringify(message), - account_number: "7", - sequence: "54", - }; - const params = { signerAddress: cosmosAddress, signDoc }; - - const signedMessage = await signClient!.request<{ signature: string }>({ + const params = { transactionMessage, signer: cosmosAddress }; + const responseFromWallet = await signClient!.request<{ + code: number; + }>({ topic: session!.topic, - chainId: "cosmos:cosmoshub-4", + chainId: "cosmos:laconic_9000-1", // TODO: Get chain ID from .env request: { - method: "cosmos_signAmino", + method: "cosmos_sendTransaction", params, }, }); - setIsLoading(false); - setOpenModal(true); - setCosmosSignature(signedMessage.signature); - } catch (error) { - setIsLoading(false); - setOpenModal(false); - enqueueSnackbar("Error signing message", { variant: "error" }); - } - }; - - const sendTransaction = async ( - transactionMessage: MsgCreateBondEncodeObject - ) => { - try { - if (ethAddress) { - setIsLoading(true); - - const params = { transactionMessage }; - const responseFromWallet = await signClient!.request<{ - code: number - }>({ - topic: session!.topic, - chainId: "cosmos:laconic_9000-1", // TODO: Get chain from WalletConnect - request: { - method: "cosmos_sendTransaction", - params, - }, - }); - if (responseFromWallet.code !== 0) { - enqueueSnackbar("Error creating bond", { variant: "error" }); - } else { - enqueueSnackbar("Created bond", { variant: "success" }); - } + if (responseFromWallet.code !== 0) { + enqueueSnackbar("Transaction not sent", { variant: "error" }); + } else { + enqueueSnackbar("Transaction successful", { variant: "success" }); } } catch (error) { + console.error(error); enqueueSnackbar("Error in sending transaction", { variant: "error" }); + } finally { + setIsLoading(false); } - setIsLoading(false); }; - // TODO: Add method to create attestation - return ( - Sign with cosmos key + Send transaction to chain Cosmos account: {cosmosAddress} - Message:
+ Onboarding message:
{ }} >
-          {canonicalStringify(message, null, 2)}{" "}
+          {JSON.stringify(onboardParticipantMsg, null, 2)}{" "}
         
{ - signCosmos(); + onClick={async () => { + await sendTransaction(onboardParticipantMsg); }} loading={isLoading} > Send transaction - { - setOpenModal(false); - }} - aria-labelledby="alert-dialog-title" - aria-describedby="alert-dialog-description" - maxWidth="md" - > - - Response from chain - -
-              {displayAttestation}{" "}
-            
-
-
- - - -
-
); diff --git a/src/pages/SignWithEthereum.tsx b/src/pages/SignWithEthereum.tsx index 1187d44..5a3b5f2 100644 --- a/src/pages/SignWithEthereum.tsx +++ b/src/pages/SignWithEthereum.tsx @@ -1,16 +1,11 @@ -import React, { useState, useMemo, useEffect, useCallback } from "react"; +import React, { useState, useMemo, useEffect } from "react"; import { useNavigate } from "react-router-dom"; import { SnackbarProvider, enqueueSnackbar } from "notistack"; import canonicalStringify from "canonical-json"; import { - Button, Select, MenuItem, - Dialog, - DialogTitle, - DialogContent, - DialogActions, Box, Typography, } from "@mui/material"; @@ -35,15 +30,14 @@ const SignWithEthereum = () => { const [cosmosAddress, setCosmosAddress] = useState(""); - const [openModal, setOpenModal] = useState(false); const [isLoading, setIsLoading] = useState(false); const message = useMemo(() => { return { - msg: "Onboarding my cosmos validator onto UrbitChain", - address: cosmosAddress, + msg: "Register my account as a validator on the Laconic network", + address: ethAddress, }; - }, [cosmosAddress]); + }, [ethAddress]); const signEth = async () => { if (session && signClient) { @@ -51,7 +45,7 @@ const SignWithEthereum = () => { setIsLoading(true) const jsonMessage = canonicalStringify(message); const hexMsg = utf8ToHex(jsonMessage, true); - const ethSignature: string = await signClient!.request({ + const receivedEthSig: string = await signClient!.request({ topic: session!.topic, chainId: "eip155:1", request: { @@ -61,22 +55,17 @@ const SignWithEthereum = () => { }); setIsLoading(false) setEthSignature(ethSignature); - setOpenModal(true); + navigate(`/sign-with-cosmos/${cosmosAddress}/${receivedEthSig}`, { + state: message, + }); } catch (error) { console.log("err in signing ", error); setIsLoading(false) - setOpenModal(false); enqueueSnackbar("Error signing message", { variant: "error" }); } } }; - const submitHandler = useCallback(() => { - navigate(`/sign-with-cosmos/${ethAddress}/${ethSignature}`, { - state: message, - }); - setOpenModal(false); - }, [ethAddress, ethSignature, navigate, message]); return (
@@ -143,42 +132,6 @@ const SignWithEthereum = () => { Sign using Ethereum key - { - setOpenModal(false); - }} - aria-labelledby="alert-dialog-title" - aria-describedby="alert-dialog-description" - maxWidth="md" - > - - {"Signed message with ethereum key"} - - - - Signature: {ethSignature} - - - -
-                  {canonicalStringify(message, null, 2)}{" "}
-                
-
-
- - - - -
) : (