diff --git a/examples/eth-dm/src/App.tsx b/examples/eth-dm/src/App.tsx index f93e02842a..4bd9496a9d 100644 --- a/examples/eth-dm/src/App.tsx +++ b/examples/eth-dm/src/App.tsx @@ -1,22 +1,18 @@ import '@ethersproject/shims'; -import React, { Dispatch, SetStateAction, useEffect, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import './App.css'; -import { Environment, getStatusFleetNodes, Waku, WakuMessage } from 'js-waku'; +import { Waku, WakuMessage } from 'js-waku'; import { ethers } from 'ethers'; import { Web3Provider } from '@ethersproject/providers'; -import { - createPublicKeyMessage, - decryptMessage, - KeyPair, - validatePublicKeyMessage, -} from './crypto'; -import { decode, DirectMessage, encode, PublicKeyMessage } from './messages'; -import { Message, Messages } from './Messages'; +import { createPublicKeyMessage, KeyPair } from './crypto'; +import { encode, PublicKeyMessage } from './messages'; +import Messages, { Message } from './Messages'; import 'fontsource-roboto'; import { Button } from '@material-ui/core'; -import { SendMessage } from './SendMessage'; -import { KeyPairHandling } from './key_pair_handling/KeyPairHandling'; +import SendMessage from './SendMessage'; +import KeyPairHandling from './key_pair_handling/KeyPairHandling'; +import InitWaku from './InitWaku'; export const PublicKeyContentTopic = '/eth-dm/1/public-key/json'; export const DirectMessageContentTopic = '/eth-dm/1/direct-message/json'; @@ -42,54 +38,6 @@ function App() { } }, [provider]); - useEffect(() => { - if (waku) return; - initWaku() - .then((wakuNode) => { - console.log('waku: ready'); - setWaku(wakuNode); - }) - .catch((e) => { - console.error('Failed to initiate Waku', e); - }); - }, [waku]); - - const observerPublicKeyMessage = handlePublicKeyMessage.bind( - {}, - ethDmKeyPair?.publicKey, - setPublicKeys - ); - - const observerDirectMessage = ethDmKeyPair - ? handleDirectMessage.bind({}, setMessages, ethDmKeyPair.privateKey) - : undefined; - - useEffect(() => { - if (!waku) return; - waku.relay.addObserver(observerPublicKeyMessage, [PublicKeyContentTopic]); - - return function cleanUp() { - if (!waku) return; - waku.relay.deleteObserver(observerPublicKeyMessage, [ - PublicKeyContentTopic, - ]); - }; - }); - - useEffect(() => { - if (!waku) return; - if (!observerDirectMessage) return; - waku.relay.addObserver(observerDirectMessage, [DirectMessageContentTopic]); - - return function cleanUp() { - if (!waku) return; - if (!observerDirectMessage) return; - waku.relay.deleteObserver(observerDirectMessage, [ - DirectMessageContentTopic, - ]); - }; - }); - const broadcastPublicKey = () => { if (!ethDmKeyPair) return; if (!provider) return; @@ -115,12 +63,16 @@ function App() { } }; - const wakuReady = !!waku ? 'Waku is ready' : 'Waku is loading'; - return (
- {wakuReady} + setEthDmKeyPair(keyPair)} @@ -144,69 +96,7 @@ function App() { export default App; -async function initWaku(): Promise { - const waku = await Waku.create({}); - - const nodes = await getNodes(); - await Promise.all( - nodes.map((addr) => { - return waku.dial(addr); - }) - ); - - return waku; -} - -function getNodes() { - // Works with react-scripts - if (process?.env?.NODE_ENV === 'development') { - return getStatusFleetNodes(Environment.Test); - } else { - return getStatusFleetNodes(Environment.Prod); - } -} - function encodePublicKeyWakuMessage(ethDmMsg: PublicKeyMessage): WakuMessage { const payload = encode(ethDmMsg); return WakuMessage.fromBytes(payload, PublicKeyContentTopic); } - -function handlePublicKeyMessage( - myPublicKey: string | undefined, - setter: Dispatch>>, - msg: WakuMessage -) { - if (!msg.payload) return; - const publicKeyMsg: PublicKeyMessage = decode(msg.payload); - if (publicKeyMsg.ethDmPublicKey === myPublicKey) return; - const res = validatePublicKeyMessage(publicKeyMsg); - console.log(`Public Key Message Received, valid: ${res}`, publicKeyMsg); - - setter((prevPks: Map) => { - prevPks.set(publicKeyMsg.ethAddress, publicKeyMsg.ethDmPublicKey); - return new Map(prevPks); - }); -} - -async function handleDirectMessage( - setter: Dispatch>, - privateKey: string, - wakuMsg: WakuMessage -) { - console.log('Waku Message received:', wakuMsg); - if (!wakuMsg.payload) return; - const directMessage: DirectMessage = decode(wakuMsg.payload); - const text = await decryptMessage(privateKey, directMessage); - - const timestamp = wakuMsg.timestamp ? wakuMsg.timestamp : new Date(); - - console.log('Message decrypted:', text); - setter((prevMsgs: Message[]) => { - const copy = prevMsgs.slice(); - copy.push({ - text: text, - timestamp: timestamp, - }); - return copy; - }); -} diff --git a/examples/eth-dm/src/InitWaku.tsx b/examples/eth-dm/src/InitWaku.tsx new file mode 100644 index 0000000000..4c59e851e9 --- /dev/null +++ b/examples/eth-dm/src/InitWaku.tsx @@ -0,0 +1,137 @@ +import { Dispatch, SetStateAction, useEffect } from 'react'; +import { Environment, getStatusFleetNodes, Waku, WakuMessage } from 'js-waku'; +import { decode, DirectMessage, PublicKeyMessage } from './messages'; +import { decryptMessage, KeyPair, validatePublicKeyMessage } from './crypto'; +import { Message } from './Messages'; +import { DirectMessageContentTopic, PublicKeyContentTopic } from './App'; + +interface Props { + waku: Waku | undefined; + setWaku: (waku: Waku) => void; + ethDmKeyPair: KeyPair | undefined; + setPublicKeys: Dispatch>>; + setMessages: Dispatch>; +} + +/** + * Does all the waku initialisation + */ +export default function InitWaku({ + waku, + setWaku, + ethDmKeyPair, + setPublicKeys, + setMessages, +}: Props) { + useEffect(() => { + if (waku) return; + initWaku() + .then((wakuNode) => { + console.log('waku: ready'); + setWaku(wakuNode); + }) + .catch((e) => { + console.error('Failed to initiate Waku', e); + }); + }, [waku, setWaku]); + + const observerPublicKeyMessage = handlePublicKeyMessage.bind( + {}, + ethDmKeyPair?.publicKey, + setPublicKeys + ); + + const observerDirectMessage = ethDmKeyPair + ? handleDirectMessage.bind({}, setMessages, ethDmKeyPair.privateKey) + : undefined; + + useEffect(() => { + if (!waku) return; + waku.relay.addObserver(observerPublicKeyMessage, [PublicKeyContentTopic]); + + return function cleanUp() { + if (!waku) return; + waku.relay.deleteObserver(observerPublicKeyMessage, [ + PublicKeyContentTopic, + ]); + }; + }); + + useEffect(() => { + if (!waku) return; + if (!observerDirectMessage) return; + waku.relay.addObserver(observerDirectMessage, [DirectMessageContentTopic]); + + return function cleanUp() { + if (!waku) return; + if (!observerDirectMessage) return; + waku.relay.deleteObserver(observerDirectMessage, [ + DirectMessageContentTopic, + ]); + }; + }); + + return

{!!waku ? 'Waku is ready' : 'Waku is loading'}

; +} + +async function initWaku(): Promise { + const waku = await Waku.create({}); + + const nodes = await getNodes(); + await Promise.all( + nodes.map((addr) => { + return waku.dial(addr); + }) + ); + + return waku; +} + +function getNodes() { + // Works with react-scripts + if (process?.env?.NODE_ENV === 'development') { + return getStatusFleetNodes(Environment.Test); + } else { + return getStatusFleetNodes(Environment.Prod); + } +} + +function handlePublicKeyMessage( + myPublicKey: string | undefined, + setter: Dispatch>>, + msg: WakuMessage +) { + if (!msg.payload) return; + const publicKeyMsg: PublicKeyMessage = decode(msg.payload); + if (publicKeyMsg.ethDmPublicKey === myPublicKey) return; + const res = validatePublicKeyMessage(publicKeyMsg); + console.log(`Public Key Message Received, valid: ${res}`, publicKeyMsg); + + setter((prevPks: Map) => { + prevPks.set(publicKeyMsg.ethAddress, publicKeyMsg.ethDmPublicKey); + return new Map(prevPks); + }); +} + +async function handleDirectMessage( + setter: Dispatch>, + privateKey: string, + wakuMsg: WakuMessage +) { + console.log('Waku Message received:', wakuMsg); + if (!wakuMsg.payload) return; + const directMessage: DirectMessage = decode(wakuMsg.payload); + const text = await decryptMessage(privateKey, directMessage); + + const timestamp = wakuMsg.timestamp ? wakuMsg.timestamp : new Date(); + + console.log('Message decrypted:', text); + setter((prevMsgs: Message[]) => { + const copy = prevMsgs.slice(); + copy.push({ + text: text, + timestamp: timestamp, + }); + return copy; + }); +} diff --git a/examples/eth-dm/src/Messages.tsx b/examples/eth-dm/src/Messages.tsx index d12756f91a..1d3384bc4d 100644 --- a/examples/eth-dm/src/Messages.tsx +++ b/examples/eth-dm/src/Messages.tsx @@ -7,7 +7,7 @@ export interface Props { messages: Message[]; } -export function Messages(props: Props) { +export default function Messages(props: Props) { const messages = props.messages.map((msg) => { return (
  • diff --git a/examples/eth-dm/src/SendMessage.tsx b/examples/eth-dm/src/SendMessage.tsx index 95de6cb41f..d38cba8437 100644 --- a/examples/eth-dm/src/SendMessage.tsx +++ b/examples/eth-dm/src/SendMessage.tsx @@ -28,7 +28,7 @@ export interface Props { recipients: Map; } -export function SendMessage({ waku, recipients }: Props) { +export default function SendMessage({ waku, recipients }: Props) { const classes = useStyles(); const [recipient, setRecipient] = useState(''); const [message, setMessage] = useState(); diff --git a/examples/eth-dm/src/key_pair_handling/KeyPairHandling.tsx b/examples/eth-dm/src/key_pair_handling/KeyPairHandling.tsx index 69030649f9..ea22c6a91c 100644 --- a/examples/eth-dm/src/key_pair_handling/KeyPairHandling.tsx +++ b/examples/eth-dm/src/key_pair_handling/KeyPairHandling.tsx @@ -9,7 +9,10 @@ export interface Props { setEthDmKeyPair: (keyPair: KeyPair) => void; } -export function KeyPairHandling({ ethDmKeyPair, setEthDmKeyPair }: Props) { +export default function KeyPairHandling({ + ethDmKeyPair, + setEthDmKeyPair, +}: Props) { const generateKeyPair = () => { if (ethDmKeyPair) return;