add basic menu, metamask guard

This commit is contained in:
Sasha 2023-12-03 00:25:59 +01:00
parent d66235c07c
commit 8dfa55096c
No known key found for this signature in database
7 changed files with 59 additions and 21 deletions

View File

@ -0,0 +1,12 @@
import Link from "next/link";
import { Block } from "@/components/Block";
export const Menu: React.FunctionComponent<{}> = () => {
return (
<Block className="m-5 flex text-lg">
<p className="mr-5">{">"}</p>
<p className="mr-5"><Link href="/">Chat</Link></p>
<p><Link href="/keystore">Keystore</Link></p>
</Block>
);
};

View File

@ -7,10 +7,20 @@ import { Status } from "@/components/Status";
import { useStore } from "@/hooks";
export default function KeystorePage() {
const { onWalletConnect } = useWallet();
const { appStatus, wallet } = useStore();
const { onWalletConnect } = useWallet();
const { appStatus, wallet } = useStore();
if (typeof window !== "undefined" && !window?.ethereum) {
return (
<main className="flex min-h-screen flex-col p-6 font-mono max-w-screen-lg">
<Header />
<p className="text-xl">Seems you don't have MetaMask installed. Please, install and reload the page.</p>
</main>
);
}
return (
<main className="flex min-h-screen flex-col p-24 font-mono max-w-screen-lg m-auto">
<main className="flex min-h-screen flex-col p-6 font-mono max-w-screen-lg">
<Header onWalletConnect={onWalletConnect}>
<Status text="Application status" mark={appStatus} />
{wallet && <p className="mt-3 text-sm">Wallet connected: {wallet}</p> }

View File

@ -1,6 +1,7 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import { Menu } from "@/app/components/Menu";
const inter = Inter({ subsets: ["latin"] });
@ -16,7 +17,10 @@ export default function RootLayout({
}) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
<body className={inter.className}>
<Menu />
{children}
</body>
</html>
);
}

View File

@ -4,7 +4,6 @@ import { Waku } from "@/app/components/Waku";
import { useWaku } from "@/hooks";
import { DebugInfo } from "@/services/waku";
export const dynamic = "force-static";
export default function Home() {
const {
onSend,
@ -15,7 +14,7 @@ export default function Home() {
} = useWaku();
return (
<main className="flex min-h-screen flex-col p-24 font-mono max-w-screen-lg">
<main className="flex min-h-screen flex-col p-6 font-mono max-w-screen-lg">
<Header>
<DebugInfo value={debugInfo} />
</Header>

View File

@ -12,16 +12,16 @@ export const useContract = (): UseContractResult => {
const onFetchContract = React.useCallback(async () => {
const fetchAccounts = new Promise<void>(async (resolve) => {
if (!rln) {
if (!rln || !rln?.ethProvider) {
console.log("Cannot fetch wallet, not provider found.");
resolve();
return;
}
try {
const accounts = await rln.ethProvider.send("eth_requestAccounts", []);
const accounts = await rln?.ethProvider.send("eth_requestAccounts", []);
setEthAccount(accounts[0] || "");
const network = await rln.ethProvider.getNetwork();
const network = await rln?.ethProvider.getNetwork();
setChainID(network.chainId);
} catch (error) {
console.error("Failed to connect to account: ", error);

View File

@ -25,7 +25,7 @@ export const useKeystore = (): UseKeystoreResult => {
return;
}
const signer = rln.ethProvider.getSigner();
const signer = rln?.ethProvider.getSigner();
const signature = await signer.signMessage(
`${SIGNATURE_MESSAGE}. Nonce: ${randomNumber()}`
);

View File

@ -37,7 +37,7 @@ type IRLN = {
export class RLN implements IRLN {
private readonly emitter = new EventTarget();
public readonly ethProvider: ethers.providers.Web3Provider;
public ethProvider: ethers.providers.Web3Provider | undefined;
public rlnInstance: undefined | RLNInstance;
public rlnContract: undefined | RLNContract;
@ -47,14 +47,6 @@ export class RLN implements IRLN {
private initializing = false;
public constructor() {
const ethereum =
window.ethereum as unknown as ethers.providers.ExternalProvider;
if (!isBrowserProviderValid(ethereum)) {
throw Error(
"Invalid Ethereum provider present on the page. Check if MetaMask is connected."
);
}
this.ethProvider = new ethers.providers.Web3Provider(ethereum, "any");
this.keystore = this.initKeystore();
}
@ -64,6 +56,8 @@ export class RLN implements IRLN {
}
this.initializing = true;
this.initProvider();
await this.initRLNWasm();
// emit keystore keys once app is ready
@ -73,6 +67,21 @@ export class RLN implements IRLN {
this.initializing = false;
}
private initProvider() {
if (typeof window === "undefined") {
return;
}
const ethereum =
window.ethereum as unknown as ethers.providers.ExternalProvider;
if (!isBrowserProviderValid(ethereum)) {
throw Error(
"Invalid Ethereum provider present on the page. Check if MetaMask is connected."
);
}
this.ethProvider = new ethers.providers.Web3Provider(ethereum, "any");
}
private async initRLNWasm(): Promise<void> {
this.emitStatusEvent(StatusEventPayload.WASM_LOADING);
try {
@ -89,7 +98,7 @@ export class RLN implements IRLN {
}
public async initRLNContract(rlnInstance: RLNInstance): Promise<void> {
if (this.rlnContract) {
if (this.rlnContract || !this.ethProvider) {
return;
}
@ -110,8 +119,12 @@ export class RLN implements IRLN {
private initKeystore(): Keystore {
const localKeystoreString = localStorage.getItem("keystore");
if (!localKeystoreString) {
return Keystore.create();
}
try {
return Keystore.fromString(localKeystoreString || "");
return Keystore.fromString(localKeystoreString || "") || Keystore.create();
} catch(error) {
return Keystore.create();
}