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 }}
publish_dir: ./examples/web-chat/build
- name: "[eth-dm] install using npm i"
- name: "[eth-pm] install using npm i"
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
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
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./examples/eth-dm/build
destination_dir: eth-dm
publish_dir: ./examples/eth-pm/build
destination_dir: eth-pm
- name: "[eth-pm-wallet] install using npm i"
run: npm install

View File

@ -12,7 +12,7 @@ jobs:
examples_build_and_test:
strategy:
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
steps:

View File

@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Renamed `discover.getStatusFleetNodes` to `discovery.getBootstrapNodes`;
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
- 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 Messaging from './messaging/Messaging';
import {
DirectMessageContentTopic,
handleDirectMessage,
PrivateMessageContentTopic,
handlePrivateMessage,
handlePublicKeyMessage,
initWaku,
PublicKeyContentTopic,
@ -122,20 +122,22 @@ function App() {
if (!address) return;
if (!provider?.provider?.request) return;
const observerDirectMessage = handleDirectMessage.bind(
const observerPrivateMessage = handlePrivateMessage.bind(
{},
setMessages,
address,
provider.provider.request
);
waku.relay.addObserver(observerDirectMessage, [DirectMessageContentTopic]);
waku.relay.addObserver(observerPrivateMessage, [
PrivateMessageContentTopic,
]);
return function cleanUp() {
if (!waku) return;
if (!observerDirectMessage) return;
waku.relay.deleteObserver(observerDirectMessage, [
DirectMessageContentTopic,
if (!observerPrivateMessage) return;
waku.relay.deleteObserver(observerPrivateMessage, [
PrivateMessageContentTopic,
]);
};
}, [waku, address, provider?.provider?.request]);
@ -178,7 +180,7 @@ function App() {
light push
</Typography>
<Typography variant="h6" className={classes.title}>
Ethereum Direct Message
Ethereum Private Message with Wallet Encryption
</Typography>
<Typography>{addressDisplay}</Typography>
</Toolbar>

View File

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

View File

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

View File

@ -11,7 +11,7 @@ const Root = protobuf.Root,
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 {
private static Type = new Type('PublicKeyMessage')
@ -59,36 +59,36 @@ export class PublicKeyMessage {
}
}
export interface DirectMessagePayload {
export interface PrivateMessagePayload {
toAddress: Uint8Array;
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 {
private static Type = new Type('DirectMessage')
export class PrivateMessage {
private static Type = new Type('PrivateMessage')
.add(new Field('toAddress', 1, 'bytes'))
.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 {
const message = DirectMessage.Type.create(this.payload);
return DirectMessage.Type.encode(message).finish();
const message = PrivateMessage.Type.create(this.payload);
return PrivateMessage.Type.encode(message).finish();
}
public static decode(bytes: Uint8Array | Buffer): DirectMessage | undefined {
const payload = DirectMessage.Type.decode(
public static decode(bytes: Uint8Array | Buffer): PrivateMessage | undefined {
const payload = PrivateMessage.Type.decode(
bytes
) as unknown as DirectMessagePayload;
) as unknown as PrivateMessagePayload;
if (!payload.toAddress || !payload.message) {
console.log('Field missing on decoded Direct Message', payload);
console.log('Field missing on decoded PrivateMessage', payload);
return;
}
return new DirectMessage(payload);
return new PrivateMessage(payload);
}
get toAddress(): Uint8Array {

View File

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

View File

@ -1,4 +1,4 @@
# Ethereum Direct Message Web App
# Ethereum Private Message Web App
**Demonstrates**:
@ -10,13 +10,13 @@
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.
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.
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:
@ -24,7 +24,7 @@ To run a development version locally, do:
git clone https://github.com/status-im/js-waku/ ; cd js-waku
npm install # Install dependencies for 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 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",
"lockfileVersion": 2,
"requires": true,

View File

@ -1,8 +1,8 @@
{
"name": "eth-dm",
"name": "eth-pm",
"version": "0.1.0",
"private": true,
"homepage": "/js-waku/eth-dm",
"homepage": "/js-waku/eth-pm",
"dependencies": {
"@material-ui/core": "^4.11.4",
"@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 Messaging from './messaging/Messaging';
import {
DirectMessageContentTopic,
handleDirectMessage,
PrivateMessageContentTopic,
handlePrivateMessage,
handlePublicKeyMessage,
initWaku,
PublicKeyContentTopic,
@ -137,19 +137,21 @@ function App() {
if (!EncryptionKeyPair) return;
if (!address) return;
const observerDirectMessage = handleDirectMessage.bind(
const observerPrivateMessage = handlePrivateMessage.bind(
{},
setMessages,
address
);
waku.relay.addObserver(observerDirectMessage, [DirectMessageContentTopic]);
waku.relay.addObserver(observerPrivateMessage, [
PrivateMessageContentTopic,
]);
return function cleanUp() {
if (!waku) return;
if (!observerDirectMessage) return;
waku.relay.deleteObserver(observerDirectMessage, [
DirectMessageContentTopic,
if (!observerPrivateMessage) return;
waku.relay.deleteObserver(observerPrivateMessage, [
PrivateMessageContentTopic,
]);
};
}, [waku, address, EncryptionKeyPair]);
@ -192,7 +194,7 @@ function App() {
light push
</Typography>
<Typography variant="h6" className={classes.title}>
Ethereum Direct Message
Ethereum Private Message
</Typography>
<Typography>{addressDisplay}</Typography>
</Toolbar>

View File

@ -12,9 +12,7 @@ export interface KeyPair {
}
/**
* Use the signature of the Salt ("Salt for eth-dm...") as
* the entropy for the EthCrypto keypair. Note that the entropy is hashed with keccak256
* to make the private key.
* Generate new encryption keypair.
*/
export async function generateEncryptionKeyPair(): Promise<KeyPair> {
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
* users know to use this Eth-DM public key to encrypt messages for the
* Sign the encryption public key with Web3. This can then be published to let other
* users know to use this public key to encrypt messages for the
* Ethereum Address holder.
*/
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
* 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.
*/
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) {
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 { Waku, WakuMessage } from 'js-waku';
import { hexToBuf } from 'js-waku/lib/utils';
import { DirectMessage } from './wire';
import { DirectMessageContentTopic } from '../waku';
import { PrivateMessage } from './wire';
import { PrivateMessageContentTopic } from '../waku';
const useStyles = makeStyles((theme) => ({
formControl: {
@ -109,13 +109,13 @@ async function encodeEncryptedWakuMessage(
publicKey: Uint8Array,
address: string
): Promise<WakuMessage> {
const directMsg = new DirectMessage({
const privateMessage = new PrivateMessage({
toAddress: hexToBuf(address),
message: message,
});
const payload = directMsg.encode();
return WakuMessage.fromBytes(payload, DirectMessageContentTopic, {
const payload = privateMessage.encode();
return WakuMessage.fromBytes(payload, PrivateMessageContentTopic, {
encPublicKey: publicKey,
});
}

View File

@ -11,7 +11,7 @@ const Root = protobuf.Root,
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 {
private static Type = new Type('PublicKeyMessage')
@ -59,36 +59,36 @@ export class PublicKeyMessage {
}
}
export interface DirectMessagePayload {
export interface PrivateMessagePayload {
toAddress: Uint8Array;
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 {
private static Type = new Type('DirectMessage')
export class PrivateMessage {
private static Type = new Type('PrivateMessage')
.add(new Field('toAddress', 1, 'bytes'))
.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 {
const message = DirectMessage.Type.create(this.payload);
return DirectMessage.Type.encode(message).finish();
const message = PrivateMessage.Type.create(this.payload);
return PrivateMessage.Type.encode(message).finish();
}
public static decode(bytes: Uint8Array | Buffer): DirectMessage | undefined {
const payload = DirectMessage.Type.decode(
public static decode(bytes: Uint8Array | Buffer): PrivateMessage | undefined {
const payload = PrivateMessage.Type.decode(
bytes
) as unknown as DirectMessagePayload;
) as unknown as PrivateMessagePayload;
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 new DirectMessage(payload);
return new PrivateMessage(payload);
}
get toAddress(): Uint8Array {

View File

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

View File

@ -3,5 +3,5 @@
Here is the list of the code examples and the features they demonstrate:
- [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`.