Merge pull request #266 from status-im/rename-eth-pm

Rename Eth-DM to Eth-PM
This commit is contained in:
Franck Royer 2021-08-18 16:45:45 +10:00 committed by GitHub
commit 455c5843f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 108 additions and 104 deletions

View File

@ -49,20 +49,20 @@ jobs:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./examples/web-chat/build publish_dir: ./examples/web-chat/build
- name: "[eth-dm] install using npm i" - name: "[eth-pm] install using npm i"
run: npm install run: npm install
working-directory: examples/eth-dm working-directory: examples/eth-pm
- name: "[eth-dm] build" - name: "[eth-pm] build"
run: npm run build run: npm run build
working-directory: examples/eth-dm working-directory: examples/eth-pm
- name: "[eth-dm] Deploy on gh pages to /eth-dm" - name: "[eth-pm] Deploy on gh pages to /eth-pm"
uses: peaceiris/actions-gh-pages@v3 uses: peaceiris/actions-gh-pages@v3
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./examples/eth-dm/build publish_dir: ./examples/eth-pm/build
destination_dir: eth-dm destination_dir: eth-pm
- name: "[eth-pm-wallet] install using npm i" - name: "[eth-pm-wallet] install using npm i"
run: npm install run: npm install

View File

@ -12,7 +12,7 @@ jobs:
examples_build_and_test: examples_build_and_test:
strategy: strategy:
matrix: matrix:
example: [ web-chat, eth-dm, eth-pm-wallet-encryption, min-react-js-chat, store-reactjs-chat ] example: [ web-chat, eth-pm, eth-pm-wallet-encryption, min-react-js-chat, store-reactjs-chat ]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:

View File

@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- Renamed `discover.getStatusFleetNodes` to `discovery.getBootstrapNodes`; - Renamed `discover.getStatusFleetNodes` to `discovery.getBootstrapNodes`;
Changed the API to allow retrieval of bootstrap nodes from other sources. Changed the API to allow retrieval of bootstrap nodes from other sources.
- Examples: Renamed `eth-dm` to `eth-pm`: "Direct Message" can lead to confusion with "Direct Connection" that
refers to low latency network connections.
### Removed ### Removed
- Examples (cli-chat): The focus of this library is Web environment; - Examples (cli-chat): The focus of this library is Web environment;

View File

@ -17,8 +17,8 @@ import WifiIcon from '@material-ui/icons/Wifi';
import BroadcastPublicKey from './BroadcastPublicKey'; import BroadcastPublicKey from './BroadcastPublicKey';
import Messaging from './messaging/Messaging'; import Messaging from './messaging/Messaging';
import { import {
DirectMessageContentTopic, PrivateMessageContentTopic,
handleDirectMessage, handlePrivateMessage,
handlePublicKeyMessage, handlePublicKeyMessage,
initWaku, initWaku,
PublicKeyContentTopic, PublicKeyContentTopic,
@ -122,20 +122,22 @@ function App() {
if (!address) return; if (!address) return;
if (!provider?.provider?.request) return; if (!provider?.provider?.request) return;
const observerDirectMessage = handleDirectMessage.bind( const observerPrivateMessage = handlePrivateMessage.bind(
{}, {},
setMessages, setMessages,
address, address,
provider.provider.request provider.provider.request
); );
waku.relay.addObserver(observerDirectMessage, [DirectMessageContentTopic]); waku.relay.addObserver(observerPrivateMessage, [
PrivateMessageContentTopic,
]);
return function cleanUp() { return function cleanUp() {
if (!waku) return; if (!waku) return;
if (!observerDirectMessage) return; if (!observerPrivateMessage) return;
waku.relay.deleteObserver(observerDirectMessage, [ waku.relay.deleteObserver(observerPrivateMessage, [
DirectMessageContentTopic, PrivateMessageContentTopic,
]); ]);
}; };
}, [waku, address, provider?.provider?.request]); }, [waku, address, provider?.provider?.request]);
@ -178,7 +180,7 @@ function App() {
light push light push
</Typography> </Typography>
<Typography variant="h6" className={classes.title}> <Typography variant="h6" className={classes.title}>
Ethereum Direct Message Ethereum Private Message with Wallet Encryption
</Typography> </Typography>
<Typography>{addressDisplay}</Typography> <Typography>{addressDisplay}</Typography>
</Toolbar> </Toolbar>

View File

@ -6,8 +6,8 @@ import { hexToBuf, equalByteArrays, bufToHex } from 'js-waku/lib/utils';
import * as sigUtil from 'eth-sig-util'; import * as sigUtil from 'eth-sig-util';
/** /**
* Sign the Eth-DM public key with Web3. This can then be published to let other * Sign the encryption public key with Web3. This can then be published to let other
* users know to use this Eth-DM public key to encrypt messages for the * users know to use this encryption public key to encrypt messages for the
* Ethereum Address holder. * Ethereum Address holder.
*/ */
export async function createPublicKeyMessage( export async function createPublicKeyMessage(

View File

@ -9,8 +9,8 @@ import {
import React, { ChangeEvent, useState, KeyboardEvent } from 'react'; import React, { ChangeEvent, useState, KeyboardEvent } from 'react';
import { Waku, WakuMessage } from 'js-waku'; import { Waku, WakuMessage } from 'js-waku';
import { bufToHex, hexToBuf } from 'js-waku/lib/utils'; import { bufToHex, hexToBuf } from 'js-waku/lib/utils';
import { DirectMessage } from './wire'; import { PrivateMessage } from './wire';
import { DirectMessageContentTopic } from '../waku'; import { PrivateMessageContentTopic } from '../waku';
import * as sigUtil from 'eth-sig-util'; import * as sigUtil from 'eth-sig-util';
const useStyles = makeStyles((theme) => ({ const useStyles = makeStyles((theme) => ({
@ -110,12 +110,12 @@ async function encodeEncryptedWakuMessage(
publicKey: Uint8Array, publicKey: Uint8Array,
address: string address: string
): Promise<WakuMessage> { ): Promise<WakuMessage> {
const directMsg = new DirectMessage({ const privateMessage = new PrivateMessage({
toAddress: hexToBuf(address), toAddress: hexToBuf(address),
message: message, message: message,
}); });
const payload = directMsg.encode(); const payload = privateMessage.encode();
const encObj = sigUtil.encrypt( const encObj = sigUtil.encrypt(
Buffer.from(publicKey).toString('base64'), Buffer.from(publicKey).toString('base64'),
@ -124,7 +124,7 @@ async function encodeEncryptedWakuMessage(
); );
const encryptedPayload = Buffer.from(JSON.stringify(encObj), 'utf8'); const encryptedPayload = Buffer.from(JSON.stringify(encObj), 'utf8');
return WakuMessage.fromBytes(encryptedPayload, DirectMessageContentTopic); return WakuMessage.fromBytes(encryptedPayload, PrivateMessageContentTopic);
} }
function sendMessage( function sendMessage(

View File

@ -11,7 +11,7 @@ const Root = protobuf.Root,
Field = protobuf.Field; Field = protobuf.Field;
/** /**
* Message used to communicate the Eth-Dm public key linked to a given Ethereum account * Message used to communicate the encryption public key linked to a given Ethereum account
*/ */
export class PublicKeyMessage { export class PublicKeyMessage {
private static Type = new Type('PublicKeyMessage') private static Type = new Type('PublicKeyMessage')
@ -59,36 +59,36 @@ export class PublicKeyMessage {
} }
} }
export interface DirectMessagePayload { export interface PrivateMessagePayload {
toAddress: Uint8Array; toAddress: Uint8Array;
message: string; message: string;
} }
/** /**
* Direct Encrypted Message used for private communication over the Waku network. * Encrypted Message used for private communication over the Waku network.
*/ */
export class DirectMessage { export class PrivateMessage {
private static Type = new Type('DirectMessage') private static Type = new Type('PrivateMessage')
.add(new Field('toAddress', 1, 'bytes')) .add(new Field('toAddress', 1, 'bytes'))
.add(new Field('message', 2, 'string')); .add(new Field('message', 2, 'string'));
private static Root = new Root().define('messages').add(DirectMessage.Type); private static Root = new Root().define('messages').add(PrivateMessage.Type);
constructor(public payload: DirectMessagePayload) {} constructor(public payload: PrivateMessagePayload) {}
public encode(): Uint8Array { public encode(): Uint8Array {
const message = DirectMessage.Type.create(this.payload); const message = PrivateMessage.Type.create(this.payload);
return DirectMessage.Type.encode(message).finish(); return PrivateMessage.Type.encode(message).finish();
} }
public static decode(bytes: Uint8Array | Buffer): DirectMessage | undefined { public static decode(bytes: Uint8Array | Buffer): PrivateMessage | undefined {
const payload = DirectMessage.Type.decode( const payload = PrivateMessage.Type.decode(
bytes bytes
) as unknown as DirectMessagePayload; ) as unknown as PrivateMessagePayload;
if (!payload.toAddress || !payload.message) { if (!payload.toAddress || !payload.message) {
console.log('Field missing on decoded Direct Message', payload); console.log('Field missing on decoded PrivateMessage', payload);
return; return;
} }
return new DirectMessage(payload); return new PrivateMessage(payload);
} }
get toAddress(): Uint8Array { get toAddress(): Uint8Array {

View File

@ -1,14 +1,14 @@
import { Dispatch, SetStateAction } from 'react'; import { Dispatch, SetStateAction } from 'react';
import { Waku, WakuMessage } from 'js-waku'; import { Waku, WakuMessage } from 'js-waku';
import { DirectMessage, PublicKeyMessage } from './messaging/wire'; import { PrivateMessage, PublicKeyMessage } from './messaging/wire';
import { validatePublicKeyMessage } from './crypto'; import { validatePublicKeyMessage } from './crypto';
import { Message } from './messaging/Messages'; import { Message } from './messaging/Messages';
import { bufToHex, equalByteArrays } from 'js-waku/lib/utils'; import { bufToHex, equalByteArrays } from 'js-waku/lib/utils';
export const PublicKeyContentTopic = export const PublicKeyContentTopic =
'/eth-pm-wallet/1/encryption-public-key/proto'; '/eth-pm-wallet/1/encryption-public-key/proto';
export const DirectMessageContentTopic = export const PrivateMessageContentTopic =
'/eth-pm-wallet/1/direct-message/proto'; '/eth-pm-wallet/1/private-message/proto';
export async function initWaku(): Promise<Waku> { export async function initWaku(): Promise<Waku> {
const waku = await Waku.create({ bootstrap: true }); const waku = await Waku.create({ bootstrap: true });
@ -52,7 +52,7 @@ export function handlePublicKeyMessage(
} }
} }
export async function handleDirectMessage( export async function handlePrivateMessage(
setter: Dispatch<SetStateAction<Message[]>>, setter: Dispatch<SetStateAction<Message[]>>,
address: string, address: string,
providerRequest: (request: { providerRequest: (request: {
@ -61,7 +61,7 @@ export async function handleDirectMessage(
}) => Promise<any>, }) => Promise<any>,
wakuMsg: WakuMessage wakuMsg: WakuMessage
) { ) {
console.log('Direct Message received:', wakuMsg); console.log('Private Message received:', wakuMsg);
if (!wakuMsg.payload) return; if (!wakuMsg.payload) return;
const decryptedPayload = await providerRequest({ const decryptedPayload = await providerRequest({
@ -70,22 +70,22 @@ export async function handleDirectMessage(
}).catch((error) => console.log(error.message)); }).catch((error) => console.log(error.message));
console.log('Decrypted Payload:', decryptedPayload); console.log('Decrypted Payload:', decryptedPayload);
const directMessage = DirectMessage.decode( const privateMessage = PrivateMessage.decode(
Buffer.from(decryptedPayload, 'hex') Buffer.from(decryptedPayload, 'hex')
); );
if (!directMessage) { if (!privateMessage) {
console.log('Failed to decode Direct Message'); console.log('Failed to decode Private Message');
return; return;
} }
if (!equalByteArrays(directMessage.toAddress, address)) return; if (!equalByteArrays(privateMessage.toAddress, address)) return;
const timestamp = wakuMsg.timestamp ? wakuMsg.timestamp : new Date(); const timestamp = wakuMsg.timestamp ? wakuMsg.timestamp : new Date();
console.log('Message decrypted:', directMessage.message); console.log('Message decrypted:', privateMessage.message);
setter((prevMsgs: Message[]) => { setter((prevMsgs: Message[]) => {
const copy = prevMsgs.slice(); const copy = prevMsgs.slice();
copy.push({ copy.push({
text: directMessage.message, text: privateMessage.message,
timestamp: timestamp, timestamp: timestamp,
}); });
return copy; return copy;

View File

@ -1,4 +1,4 @@
# Ethereum Direct Message Web App # Ethereum Private Message Web App
**Demonstrates**: **Demonstrates**:
@ -10,13 +10,13 @@
A PoC implementation of [20/ETH-DM](https://rfc.vac.dev/spec/20/). A PoC implementation of [20/ETH-DM](https://rfc.vac.dev/spec/20/).
Ethereum Direct Message, or Eth-DM, is a protocol that allows sending encrypted message to a recipient, Ethereum Private Message, or Eth-PM, is a protocol that allows sending encrypted message to a recipient,
only knowing their Ethereum Address. only knowing their Ethereum Address.
This is protocol has been created to demonstrated how encryption and signature could be added to messages This protocol has been created to demonstrated how encryption and signature could be added to message
sent over the Waku v2 network. sent over the Waku v2 network.
The `main` branch's HEAD is deployed on GitHub Pages at https://status-im.github.io/js-waku/eth-dm/. The `main` branch's HEAD is deployed on GitHub Pages at https://status-im.github.io/js-waku/eth-pm/.
To run a development version locally, do: To run a development version locally, do:
@ -24,7 +24,7 @@ To run a development version locally, do:
git clone https://github.com/status-im/js-waku/ ; cd js-waku git clone https://github.com/status-im/js-waku/ ; cd js-waku
npm install # Install dependencies for js-waku npm install # Install dependencies for js-waku
npm run build # Build js-waku npm run build # Build js-waku
cd examples/eth-dm cd examples/eth-pm
npm install # Install dependencies for the web app npm install # Install dependencies for the web app
npm run start # Start development server to serve the web app on http://localhost:3000/js-waku/eth-dm npm run start # Start development server to serve the web app on http://localhost:3000/js-waku/eth-pm
``` ```

View File

@ -1,5 +1,5 @@
{ {
"name": "eth-dm", "name": "eth-pm",
"version": "0.1.0", "version": "0.1.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,

View File

@ -1,8 +1,8 @@
{ {
"name": "eth-dm", "name": "eth-pm",
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"homepage": "/js-waku/eth-dm", "homepage": "/js-waku/eth-pm",
"dependencies": { "dependencies": {
"@material-ui/core": "^4.11.4", "@material-ui/core": "^4.11.4",
"@material-ui/icons": "^4.11.2", "@material-ui/icons": "^4.11.2",

View File

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@ -19,8 +19,8 @@ import WifiIcon from '@material-ui/icons/Wifi';
import BroadcastPublicKey from './BroadcastPublicKey'; import BroadcastPublicKey from './BroadcastPublicKey';
import Messaging from './messaging/Messaging'; import Messaging from './messaging/Messaging';
import { import {
DirectMessageContentTopic, PrivateMessageContentTopic,
handleDirectMessage, handlePrivateMessage,
handlePublicKeyMessage, handlePublicKeyMessage,
initWaku, initWaku,
PublicKeyContentTopic, PublicKeyContentTopic,
@ -137,19 +137,21 @@ function App() {
if (!EncryptionKeyPair) return; if (!EncryptionKeyPair) return;
if (!address) return; if (!address) return;
const observerDirectMessage = handleDirectMessage.bind( const observerPrivateMessage = handlePrivateMessage.bind(
{}, {},
setMessages, setMessages,
address address
); );
waku.relay.addObserver(observerDirectMessage, [DirectMessageContentTopic]); waku.relay.addObserver(observerPrivateMessage, [
PrivateMessageContentTopic,
]);
return function cleanUp() { return function cleanUp() {
if (!waku) return; if (!waku) return;
if (!observerDirectMessage) return; if (!observerPrivateMessage) return;
waku.relay.deleteObserver(observerDirectMessage, [ waku.relay.deleteObserver(observerPrivateMessage, [
DirectMessageContentTopic, PrivateMessageContentTopic,
]); ]);
}; };
}, [waku, address, EncryptionKeyPair]); }, [waku, address, EncryptionKeyPair]);
@ -192,7 +194,7 @@ function App() {
light push light push
</Typography> </Typography>
<Typography variant="h6" className={classes.title}> <Typography variant="h6" className={classes.title}>
Ethereum Direct Message Ethereum Private Message
</Typography> </Typography>
<Typography>{addressDisplay}</Typography> <Typography>{addressDisplay}</Typography>
</Toolbar> </Toolbar>

View File

@ -12,9 +12,7 @@ export interface KeyPair {
} }
/** /**
* Use the signature of the Salt ("Salt for eth-dm...") as * Generate new encryption keypair.
* the entropy for the EthCrypto keypair. Note that the entropy is hashed with keccak256
* to make the private key.
*/ */
export async function generateEncryptionKeyPair(): Promise<KeyPair> { export async function generateEncryptionKeyPair(): Promise<KeyPair> {
const privateKey = generatePrivateKey(); const privateKey = generatePrivateKey();
@ -23,8 +21,8 @@ export async function generateEncryptionKeyPair(): Promise<KeyPair> {
} }
/** /**
* Sign the Eth-DM public key with Web3. This can then be published to let other * Sign the encryption public key with Web3. This can then be published to let other
* users know to use this Eth-DM public key to encrypt messages for the * users know to use this public key to encrypt messages for the
* Ethereum Address holder. * Ethereum Address holder.
*/ */
export async function createPublicKeyMessage( export async function createPublicKeyMessage(
@ -62,10 +60,10 @@ export function validatePublicKeyMessage(msg: PublicKeyMessage): boolean {
} }
/** /**
* Prepare Eth-Dm Public key to be signed for publication. * Prepare encryption public key to be signed for publication.
* The public key is set in on Object `{ encryptionPublicKey: string; }`, converted * The public key is set in on Object `{ encryptionPublicKey: string; }`, converted
* to JSON and then hashed with Keccak256. * to JSON and then hashed with Keccak256.
* The usage of the object helps ensure the signature is only used in an Eth-DM * The usage of the object helps ensure the signature is only used in an Eth-PM
* context. * context.
*/ */
function formatPublicKeyForSignature(encryptionPublicKey: Uint8Array): string { function formatPublicKeyForSignature(encryptionPublicKey: Uint8Array): string {

View File

@ -69,7 +69,7 @@ function getWrapKey(keyMaterial: CryptoKey, salt: Uint8Array) {
} }
/** /**
* Encrypt Eth-DM KeyPair using provided password * Encrypt encryption KeyPair using provided password.
*/ */
async function encryptKey(encryptionKeyPair: KeyPair, password: string) { async function encryptKey(encryptionKeyPair: KeyPair, password: string) {
const keyMaterial = await getKeyMaterial(password); const keyMaterial = await getKeyMaterial(password);

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -9,8 +9,8 @@ import {
import React, { ChangeEvent, useState, KeyboardEvent } from 'react'; import React, { ChangeEvent, useState, KeyboardEvent } from 'react';
import { Waku, WakuMessage } from 'js-waku'; import { Waku, WakuMessage } from 'js-waku';
import { hexToBuf } from 'js-waku/lib/utils'; import { hexToBuf } from 'js-waku/lib/utils';
import { DirectMessage } from './wire'; import { PrivateMessage } from './wire';
import { DirectMessageContentTopic } from '../waku'; import { PrivateMessageContentTopic } from '../waku';
const useStyles = makeStyles((theme) => ({ const useStyles = makeStyles((theme) => ({
formControl: { formControl: {
@ -109,13 +109,13 @@ async function encodeEncryptedWakuMessage(
publicKey: Uint8Array, publicKey: Uint8Array,
address: string address: string
): Promise<WakuMessage> { ): Promise<WakuMessage> {
const directMsg = new DirectMessage({ const privateMessage = new PrivateMessage({
toAddress: hexToBuf(address), toAddress: hexToBuf(address),
message: message, message: message,
}); });
const payload = directMsg.encode(); const payload = privateMessage.encode();
return WakuMessage.fromBytes(payload, DirectMessageContentTopic, { return WakuMessage.fromBytes(payload, PrivateMessageContentTopic, {
encPublicKey: publicKey, encPublicKey: publicKey,
}); });
} }

View File

@ -11,7 +11,7 @@ const Root = protobuf.Root,
Field = protobuf.Field; Field = protobuf.Field;
/** /**
* Message used to communicate the Eth-Dm public key linked to a given Ethereum account * Message used to communicate the encryption public key linked to a given Ethereum account
*/ */
export class PublicKeyMessage { export class PublicKeyMessage {
private static Type = new Type('PublicKeyMessage') private static Type = new Type('PublicKeyMessage')
@ -59,36 +59,36 @@ export class PublicKeyMessage {
} }
} }
export interface DirectMessagePayload { export interface PrivateMessagePayload {
toAddress: Uint8Array; toAddress: Uint8Array;
message: string; message: string;
} }
/** /**
* Direct Encrypted Message used for private communication over the Waku network. * Encrypted Message used for private communication over the Waku network.
*/ */
export class DirectMessage { export class PrivateMessage {
private static Type = new Type('DirectMessage') private static Type = new Type('PrivateMessage')
.add(new Field('toAddress', 1, 'bytes')) .add(new Field('toAddress', 1, 'bytes'))
.add(new Field('message', 2, 'string')); .add(new Field('message', 2, 'string'));
private static Root = new Root().define('messages').add(DirectMessage.Type); private static Root = new Root().define('messages').add(PrivateMessage.Type);
constructor(public payload: DirectMessagePayload) {} constructor(public payload: PrivateMessagePayload) {}
public encode(): Uint8Array { public encode(): Uint8Array {
const message = DirectMessage.Type.create(this.payload); const message = PrivateMessage.Type.create(this.payload);
return DirectMessage.Type.encode(message).finish(); return PrivateMessage.Type.encode(message).finish();
} }
public static decode(bytes: Uint8Array | Buffer): DirectMessage | undefined { public static decode(bytes: Uint8Array | Buffer): PrivateMessage | undefined {
const payload = DirectMessage.Type.decode( const payload = PrivateMessage.Type.decode(
bytes bytes
) as unknown as DirectMessagePayload; ) as unknown as PrivateMessagePayload;
if (!payload.toAddress || !payload.message) { if (!payload.toAddress || !payload.message) {
console.log('Field missing on decoded Direct Message', payload); console.log('Field missing on decoded Private Message', payload);
return; return;
} }
return new DirectMessage(payload); return new PrivateMessage(payload);
} }
get toAddress(): Uint8Array { get toAddress(): Uint8Array {

View File

@ -1,12 +1,12 @@
import { Dispatch, SetStateAction } from 'react'; import { Dispatch, SetStateAction } from 'react';
import { Waku, WakuMessage } from 'js-waku'; import { Waku, WakuMessage } from 'js-waku';
import { DirectMessage, PublicKeyMessage } from './messaging/wire'; import { PrivateMessage, PublicKeyMessage } from './messaging/wire';
import { validatePublicKeyMessage } from './crypto'; import { validatePublicKeyMessage } from './crypto';
import { Message } from './messaging/Messages'; import { Message } from './messaging/Messages';
import { bufToHex, equalByteArrays } from 'js-waku/lib/utils'; import { bufToHex, equalByteArrays } from 'js-waku/lib/utils';
export const PublicKeyContentTopic = '/eth-dm/1/public-key/proto'; export const PublicKeyContentTopic = '/eth-pm/1/public-key/proto';
export const DirectMessageContentTopic = '/eth-dm/1/direct-message/proto'; export const PrivateMessageContentTopic = '/eth-pm/1/private-message/proto';
export async function initWaku(): Promise<Waku> { export async function initWaku(): Promise<Waku> {
const waku = await Waku.create({ bootstrap: true }); const waku = await Waku.create({ bootstrap: true });
@ -50,27 +50,27 @@ export function handlePublicKeyMessage(
} }
} }
export async function handleDirectMessage( export async function handlePrivateMessage(
setter: Dispatch<SetStateAction<Message[]>>, setter: Dispatch<SetStateAction<Message[]>>,
address: string, address: string,
wakuMsg: WakuMessage wakuMsg: WakuMessage
) { ) {
console.log('Direct Message received:', wakuMsg); console.log('Private Message received:', wakuMsg);
if (!wakuMsg.payload) return; if (!wakuMsg.payload) return;
const directMessage = DirectMessage.decode(wakuMsg.payload); const privateMessage = PrivateMessage.decode(wakuMsg.payload);
if (!directMessage) { if (!privateMessage) {
console.log('Failed to decode Direct Message'); console.log('Failed to decode Private Message');
return; return;
} }
if (!equalByteArrays(directMessage.toAddress, address)) return; if (!equalByteArrays(privateMessage.toAddress, address)) return;
const timestamp = wakuMsg.timestamp ? wakuMsg.timestamp : new Date(); const timestamp = wakuMsg.timestamp ? wakuMsg.timestamp : new Date();
console.log('Message decrypted:', directMessage.message); console.log('Message decrypted:', privateMessage.message);
setter((prevMsgs: Message[]) => { setter((prevMsgs: Message[]) => {
const copy = prevMsgs.slice(); const copy = prevMsgs.slice();
copy.push({ copy.push({
text: directMessage.message, text: privateMessage.message,
timestamp: timestamp, timestamp: timestamp,
}); });
return copy; return copy;

View File

@ -3,5 +3,5 @@
Here is the list of the code examples and the features they demonstrate: Here is the list of the code examples and the features they demonstrate:
- [Web Chat App](web-chat): Group chat, React/TypeScript, Relay, Store. - [Web Chat App](web-chat): Group chat, React/TypeScript, Relay, Store.
- [Ethereum Direct Message Web App](eth-dm): Private Messaging, React/TypeScript, Light Push, Signature with Web3, Asymmetric Encryption. - [Ethereum Private Message Web App](eth-pm): Private Messaging, React/TypeScript, Light Push, Signature with Web3, Asymmetric Encryption.
- [Minimal ReactJS Chat App](min-react-js-chat): Group chat, React/JavaScript, Relay, Protobuf using `protons`. - [Minimal ReactJS Chat App](min-react-js-chat): Group chat, React/JavaScript, Relay, Protobuf using `protons`.