import "@ethersproject/shims"; import React, { useEffect, useState } from "react"; import "./App.css"; import type { WakuLight } from "js-waku/lib/interfaces"; import { AsymDecoder, SymDecoder } from "js-waku/lib/waku_message/version_1"; import { KeyPair, PublicKeyMessageEncryptionKey } from "./crypto"; import { Message } from "./messaging/Messages"; import "fontsource-roboto"; import { AppBar, IconButton, Toolbar, Typography } from "@material-ui/core"; import KeyPairHandling from "./key_pair_handling/KeyPairHandling"; import { createMuiTheme, ThemeProvider, makeStyles, } from "@material-ui/core/styles"; import { teal, purple, green } from "@material-ui/core/colors"; import WifiIcon from "@material-ui/icons/Wifi"; import BroadcastPublicKey from "./BroadcastPublicKey"; import Messaging from "./messaging/Messaging"; import { PrivateMessageContentTopic, handlePrivateMessage, handlePublicKeyMessage, initWaku, PublicKeyContentTopic, } from "./waku"; import { Web3Provider } from "@ethersproject/providers/src.ts/web3-provider"; import ConnectWallet from "./ConnectWallet"; const theme = createMuiTheme({ palette: { primary: { main: purple[500], }, secondary: { main: teal[600], }, }, }); const useStyles = makeStyles({ root: { textAlign: "center", display: "flex", flexDirection: "column", minHeight: "100vh", }, appBar: { // height: '200p', }, container: { display: "flex", flex: 1, }, main: { flex: 1, margin: "10px", }, wakuStatus: { marginRight: theme.spacing(2), }, title: { flexGrow: 1, }, peers: {}, }); function App() { const [waku, setWaku] = useState(); const [provider, setProvider] = useState(); const [encryptionKeyPair, setEncryptionKeyPair] = useState< KeyPair | undefined >(); const [privateMessageDecoder, setPrivateMessageDecoder] = useState(); const [publicKeys, setPublicKeys] = useState>( new Map() ); const [messages, setMessages] = useState([]); const [address, setAddress] = useState(); const [peerStats, setPeerStats] = useState<{ filterPeers: number; lightPushPeers: number; }>({ filterPeers: 0, lightPushPeers: 0, }); const classes = useStyles(); // Waku initialization useEffect(() => { (async () => { if (waku) return; const _waku = await initWaku(); console.log("waku: ready"); setWaku(_waku); })().catch((e) => { console.error("Failed to initiate Waku", e); }); }, [waku]); useEffect(() => { if (!waku) return; const observerPublicKeyMessage = handlePublicKeyMessage.bind( {}, address, setPublicKeys ); const publicKeyMessageDecoder = new SymDecoder( PublicKeyContentTopic, PublicKeyMessageEncryptionKey ); let unsubscribe: undefined | (() => Promise); waku.filter .subscribe([publicKeyMessageDecoder], observerPublicKeyMessage) .then( (_unsubscribe) => { console.log("subscribed to ", PublicKeyContentTopic); unsubscribe = _unsubscribe; }, (e) => { console.error("Failed to subscribe", e); } ); return function cleanUp() { if (typeof unsubscribe === "undefined") return; unsubscribe().then( () => { console.log("unsubscribed to ", PublicKeyContentTopic); }, (e) => console.error("Failed to unsubscribe", e) ); }; }, [waku, address]); useEffect(() => { if (!encryptionKeyPair) return; setPrivateMessageDecoder( new AsymDecoder(PrivateMessageContentTopic, encryptionKeyPair.privateKey) ); }, [encryptionKeyPair]); useEffect(() => { if (!waku) return; if (!privateMessageDecoder) return; if (!address) return; const observerPrivateMessage = handlePrivateMessage.bind( {}, setMessages, address ); let unsubscribe: undefined | (() => Promise); waku.filter.subscribe([privateMessageDecoder], observerPrivateMessage).then( (_unsubscribe) => { unsubscribe = _unsubscribe; }, (e) => { console.error("Failed to subscribe", e); } ); return function cleanUp() { if (typeof unsubscribe === "undefined") return; unsubscribe().catch((e) => console.error("Failed to unsubscribe", e)); }; }, [waku, address, privateMessageDecoder]); useEffect(() => { if (!waku) return; const interval = setInterval(async () => { const lightPushPeers = await waku.store.peers(); const filterPeers = await waku.filter.peers(); setPeerStats({ filterPeers: filterPeers.length, lightPushPeers: lightPushPeers.length, }); }, 1000); return () => clearInterval(interval); }, [waku]); let addressDisplay = ""; if (address) { addressDisplay = address.substr(0, 6) + "..." + address.substr(address.length - 4, 4); } return (
Peers: {peerStats.filterPeers} filter, {peerStats.lightPushPeers}{" "} light push Ethereum Private Message {addressDisplay}
Wallet
Encryption Key Pair
Messaging
); } export default App;