Skip to content

Commit 2f5e751

Browse files
authored
Merge pull request #228 from status-im/eth-dm-proto
Use protobuf instead of JSON for direct messages
2 parents b829664 + c2cef05 commit 2f5e751

File tree

5 files changed

+50
-23
lines changed

5 files changed

+50
-23
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2525
- **Breaking**: `WakuMessage` constructor is now private, `from*` and `decode*` function should be used.
2626
- `WakuMessage` version 1 is partially supported, enabling asymmetrical encryption and signature of messages;
2727
this can be done by passing keys to `WakuMessage.from*` and `WakuMessage.decode*` methods.
28-
- Examples (eth-dm): Use Waku Message version 1 encryption scheme instead of `eth-crypto`.
28+
- Examples (eth-dm): Use Waku Message version 1 encryption scheme instead of `eth-crypto`.
29+
- Examples (eth-dm): Use Protobuf for direct messages instead of JSON ([#214](https://github.com/status-im/js-waku/issues/214)).
2930

3031
### Fixed
3132
- Disable `keepAlive` if set to `0`.

examples/eth-dm/src/messaging/SendMessage.tsx

+6-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import {
88
} from '@material-ui/core';
99
import React, { ChangeEvent, useState, KeyboardEvent } from 'react';
1010
import { Waku, WakuMessage } from 'js-waku';
11-
import { DirectMessage, encode } from './wire';
11+
import { hexToBuf } from 'js-waku/lib/utils';
12+
import { DirectMessage } from './wire';
1213
import { DirectMessageContentTopic } from '../waku';
1314

1415
const useStyles = makeStyles((theme) => ({
@@ -108,12 +109,12 @@ async function encodeEncryptedWakuMessage(
108109
publicKey: string,
109110
address: string
110111
): Promise<WakuMessage> {
111-
const directMsg: DirectMessage = {
112-
toAddress: address,
112+
const directMsg = new DirectMessage({
113+
toAddress: hexToBuf(address),
113114
message: message,
114-
};
115+
});
115116

116-
const payload = encode(directMsg);
117+
const payload = directMsg.encode();
117118
return WakuMessage.fromBytes(payload, {
118119
contentTopic: DirectMessageContentTopic,
119120
encPublicKey: publicKey,

examples/eth-dm/src/messaging/wire.ts

+34-12
Original file line numberDiff line numberDiff line change
@@ -55,21 +55,43 @@ export class PublicKeyMessage {
5555
}
5656
}
5757

58+
export interface DirectMessagePayload {
59+
toAddress: Uint8Array;
60+
message: string;
61+
}
62+
5863
/**
5964
* Direct Encrypted Message used for private communication over the Waku network.
6065
*/
61-
export interface DirectMessage {
62-
toAddress: string;
63-
message: string;
64-
}
66+
export class DirectMessage {
67+
private static Type = new Type('DirectMessage')
68+
.add(new Field('toAddress', 1, 'bytes'))
69+
.add(new Field('message', 2, 'string'));
70+
private static Root = new Root().define('messages').add(DirectMessage.Type);
6571

66-
export function encode<T>(msg: T): Buffer {
67-
const jsonStr = JSON.stringify(msg);
68-
return Buffer.from(jsonStr, 'utf-8');
69-
}
72+
constructor(public payload: DirectMessagePayload) {}
73+
74+
public encode(): Uint8Array {
75+
const message = DirectMessage.Type.create(this.payload);
76+
return DirectMessage.Type.encode(message).finish();
77+
}
7078

71-
export function decode<T>(bytes: Uint8Array): T {
72-
const buf = Buffer.from(bytes);
73-
const str = buf.toString('utf-8');
74-
return JSON.parse(str);
79+
public static decode(bytes: Uint8Array | Buffer): DirectMessage | undefined {
80+
const payload = DirectMessage.Type.decode(
81+
bytes
82+
) as unknown as DirectMessagePayload;
83+
if (!payload.toAddress || !payload.message) {
84+
console.log('Field missing on decoded Direct Message', payload);
85+
return;
86+
}
87+
return new DirectMessage(payload);
88+
}
89+
90+
get toAddress(): Uint8Array {
91+
return this.payload.toAddress;
92+
}
93+
94+
get message(): string {
95+
return this.payload.message;
96+
}
7597
}

examples/eth-dm/src/waku.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { Dispatch, SetStateAction } from 'react';
22
import { getStatusFleetNodes, Waku, WakuMessage } from 'js-waku';
3-
import { decode, DirectMessage, PublicKeyMessage } from './messaging/wire';
3+
import { DirectMessage, PublicKeyMessage } from './messaging/wire';
44
import { validatePublicKeyMessage } from './crypto';
55
import { Message } from './messaging/Messages';
66
import { bufToHex, equalByteArrays } from 'js-waku/lib/utils';
77

88
export const PublicKeyContentTopic = '/eth-dm/1/public-key/proto';
9-
export const DirectMessageContentTopic = '/eth-dm/1/direct-message/json';
9+
export const DirectMessageContentTopic = '/eth-dm/1/direct-message/proto';
1010

1111
export async function initWaku(): Promise<Waku> {
1212
const waku = await Waku.create({});
@@ -64,8 +64,11 @@ export async function handleDirectMessage(
6464
) {
6565
console.log('Direct Message received:', wakuMsg);
6666
if (!wakuMsg.payload) return;
67-
const directMessage: DirectMessage = decode(wakuMsg.payload);
68-
67+
const directMessage = DirectMessage.decode(wakuMsg.payload);
68+
if (!directMessage) {
69+
console.log('Failed to decode Direct Message');
70+
return;
71+
}
6972
if (!equalByteArrays(directMessage.toAddress, address)) return;
7073

7174
const timestamp = wakuMsg.timestamp ? wakuMsg.timestamp : new Date();

src/lib/waku_message/version_1.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export function clearEncode(
2828
): { payload: Uint8Array; sig?: Signature } {
2929
let envelope = Buffer.from([0]); // No flags
3030
envelope = addPayloadSizeField(envelope, messagePayload);
31-
envelope = Buffer.concat([envelope, messagePayload]);
31+
envelope = Buffer.concat([envelope, Buffer.from(messagePayload)]);
3232

3333
// Calculate padding:
3434
let rawSize =

0 commit comments

Comments
 (0)