diff --git a/examples/eth-dm/src/App.tsx b/examples/eth-dm/src/App.tsx
index 516b5b055f..c57df3e3c5 100644
--- a/examples/eth-dm/src/App.tsx
+++ b/examples/eth-dm/src/App.tsx
@@ -12,13 +12,14 @@ import {
validatePublicKeyMessage,
} from './crypto';
import * as EthCrypto from 'eth-crypto';
-import { DirectMessage, PublicKeyMessage } from './messages';
+import { decode, DirectMessage, encode, PublicKeyMessage } from './messages';
import { Message, Messages } from './Messages';
import 'fontsource-roboto';
import { Button } from '@material-ui/core';
+import { SendMessage } from './SendMessage';
-const PublicKeyContentTopic = '/eth-dm/1/public-key/json';
-const DirectMessageContentTopic = '/eth-dm/1/direct-message/json';
+export const PublicKeyContentTopic = '/eth-dm/1/public-key/json';
+export const DirectMessageContentTopic = '/eth-dm/1/direct-message/json';
declare let window: any;
@@ -126,54 +127,38 @@ function App() {
}
};
- const sendDummyMessage = () => {
- if (!waku) return;
-
- console.log(`Sending messages to ${publicKeys.size} peers`);
- publicKeys.forEach(async (publicKey, address) => {
- const msg = await encodeEncryptedWakuMessage(
- 'Here is a secret message',
- publicKey,
- address
- );
- await waku?.lightPush.push(msg);
- });
- };
-
const wakuReady = !!waku ? 'Waku is ready' : 'Waku is loading';
return (
);
@@ -208,22 +193,6 @@ function encodePublicKeyWakuMessage(ethDmMsg: PublicKeyMessage): WakuMessage {
return WakuMessage.fromBytes(payload, PublicKeyContentTopic);
}
-async function encodeEncryptedWakuMessage(
- message: string,
- publicKey: string,
- address: string
-): Promise {
- const encryptedMsg = await EthCrypto.encryptWithPublicKey(publicKey, message);
-
- const directMsg: DirectMessage = {
- toAddress: address,
- encMessage: encryptedMsg,
- };
-
- const payload = encode(directMsg);
- return WakuMessage.fromBytes(payload, DirectMessageContentTopic);
-}
-
function handlePublicKeyMessage(
setter: Dispatch>>,
msg: WakuMessage
@@ -264,14 +233,3 @@ async function handleDirectMessage(
return copy;
});
}
-
-function encode(msg: T): Buffer {
- const jsonStr = JSON.stringify(msg);
- return Buffer.from(jsonStr, 'utf-8');
-}
-
-function decode(bytes: Uint8Array): T {
- const buf = Buffer.from(bytes);
- const str = buf.toString('utf-8');
- return JSON.parse(str);
-}
diff --git a/examples/eth-dm/src/SendMessage.tsx b/examples/eth-dm/src/SendMessage.tsx
new file mode 100644
index 0000000000..723c00d773
--- /dev/null
+++ b/examples/eth-dm/src/SendMessage.tsx
@@ -0,0 +1,146 @@
+import {
+ FormControl,
+ InputLabel,
+ makeStyles,
+ MenuItem,
+ Select,
+ TextField,
+} from '@material-ui/core';
+import React, { ChangeEvent, useState, KeyboardEvent } from 'react';
+import { Waku, WakuMessage } from 'js-waku';
+import * as EthCrypto from 'eth-crypto';
+import { DirectMessage, encode } from './messages';
+import { DirectMessageContentTopic } from './App';
+
+const useStyles = makeStyles((theme) => ({
+ formControl: {
+ margin: theme.spacing(1),
+ minWidth: 120,
+ },
+ selectEmpty: {
+ marginTop: theme.spacing(2),
+ },
+}));
+
+export interface Props {
+ waku: Waku | undefined;
+ // address, public key
+ recipients: Map;
+}
+
+export function SendMessage(props: Props) {
+ const classes = useStyles();
+ const [recipient, setRecipient] = useState('');
+ const [message, setMessage] = useState();
+
+ const waku = props.waku;
+
+ const handleRecipientChange = (
+ event: ChangeEvent<{ name?: string; value: unknown }>
+ ) => {
+ setRecipient(event.target.value as string);
+ };
+
+ const handleMessageChange = (event: ChangeEvent) => {
+ setMessage(event.target.value);
+ };
+
+ const items = Array.from(props.recipients.keys()).map((recipient) => {
+ return ;
+ });
+
+ const keyDownHandler = async (event: KeyboardEvent) => {
+ if (
+ event.key === 'Enter' &&
+ !event.altKey &&
+ !event.ctrlKey &&
+ !event.shiftKey
+ ) {
+ if (!waku) return;
+ if (!recipient) return;
+ if (!message) return;
+ const publicKey = props.recipients.get(recipient);
+ if (!publicKey) return;
+
+ sendMessage(waku, recipient, publicKey, message, (res) => {
+ if (res) {
+ console.log('callback called with', res);
+ setMessage('');
+ }
+ });
+ }
+ };
+
+ return (
+
+
+ Recipient
+
+
+
+
+ );
+}
+
+async function encodeEncryptedWakuMessage(
+ message: string,
+ publicKey: string,
+ address: string
+): Promise {
+ const encryptedMsg = await EthCrypto.encryptWithPublicKey(publicKey, message);
+
+ const directMsg: DirectMessage = {
+ toAddress: address,
+ encMessage: encryptedMsg,
+ };
+
+ const payload = encode(directMsg);
+ return WakuMessage.fromBytes(payload, DirectMessageContentTopic);
+}
+
+function sendMessage(
+ waku: Waku,
+ recipientAddress: string,
+ recipientPublicKey: string,
+ message: string,
+ callback: (res: boolean) => void
+) {
+ encodeEncryptedWakuMessage(message, recipientPublicKey, recipientAddress)
+ .then((msg) => {
+ console.log('pushing');
+ waku.lightPush
+ .push(msg)
+ .then((res) => {
+ console.log('Message sent', res);
+ callback(res ? res.isSuccess : false);
+ })
+ .catch((e) => {
+ console.error('Failed to send message', e);
+ callback(false);
+ });
+ })
+ .catch((e) => {
+ console.error('Cannot encode & encrypt message', e);
+ callback(false);
+ });
+}
diff --git a/examples/eth-dm/src/messages.ts b/examples/eth-dm/src/messages.ts
index 05d771387b..e76cbc8a89 100644
--- a/examples/eth-dm/src/messages.ts
+++ b/examples/eth-dm/src/messages.ts
@@ -16,3 +16,14 @@ export interface DirectMessage {
toAddress: string;
encMessage: EthCrypto.Encrypted;
}
+
+export function encode(msg: T): Buffer {
+ const jsonStr = JSON.stringify(msg);
+ return Buffer.from(jsonStr, 'utf-8');
+}
+
+export function decode(bytes: Uint8Array): T {
+ const buf = Buffer.from(bytes);
+ const str = buf.toString('utf-8');
+ return JSON.parse(str);
+}