Merge pull request #18 from waku-org/weboko/update-js-waku

chore: update js-waku version
This commit is contained in:
Sasha 2023-02-08 23:29:57 +01:00 committed by GitHub
commit ad8035a012
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 1584 additions and 11202 deletions

View File

@ -1,7 +1,7 @@
{
"extension": ["ts"],
"spec": "src/**/*.spec.ts",
"require": ["ts-node/register", "isomorphic-fetch", "jsdom-global/register"],
"require": ["ts-node/register", "jsdom-global/register"],
"loader": "ts-node/esm",
"node-option": ["experimental-specifier-resolution=node", "loader=ts-node/esm"],
"exit": true

View File

@ -36,6 +36,11 @@ module.exports = function (config) {
},
webpack: {
mode: "production",
optimization: {
// minification is disabled due to an issue with missing variable
// https://github.com/waku-org/js-noise/pull/18#discussion_r1100712310
minimize: false,
},
resolve: {
// Add `.ts` and `.tsx` as a resolvable extension.
extensions: [".ts", ".tsx", ".js"],

12643
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,7 @@
"test:tsc": "tsc -p tsconfig.dev.json",
"test:browser": "karma start karma.conf.cjs",
"watch:build": "tsc -p tsconfig.json -w",
"watch:test": "mocha --watch",
"watch:test": "mocha --watch --parallel",
"prepublish": "npm run build",
"reset-hard": "git clean -dfx && git reset --hard && npm i && npm run build"
},
@ -59,6 +59,7 @@
"@types/uuid": "^8.3.0",
"@typescript-eslint/eslint-plugin": "^5.8.1",
"@typescript-eslint/parser": "^5.8.1",
"@waku/interfaces": "^0.0.7",
"app-root-path": "^3.0.0",
"chai": "^4.3.4",
"cspell": "^5.14.0",
@ -72,7 +73,6 @@
"gh-pages": "^3.2.3",
"husky": "^7.0.4",
"ignore-loader": "^0.1.2",
"js-waku": "^0.29.0-29436ea",
"jsdom": "^19.0.0",
"jsdom-global": "^3.0.2",
"karma": "^6.3.12",
@ -121,6 +121,8 @@
"@stablelib/random": "^1.0.2",
"@stablelib/sha256": "^1.0.1",
"@stablelib/x25519": "^1.0.1",
"@waku/core": "^0.0.10",
"@waku/proto": "^0.0.2",
"bn.js": "^5.2.1",
"eventemitter3": "^5.0.0",
"js-base64": "^3.7.3",

View File

@ -1,7 +1,7 @@
import { DecodedMessage } from "@waku/core";
import type { IDecodedMessage, IDecoder, IEncoder, IMessage, IProtoMessage } from "@waku/interfaces";
import { WakuMessage } from "@waku/proto";
import debug from "debug";
import { proto_message } from "js-waku";
import { Decoder, Encoder, Message, ProtoMessage } from "js-waku/lib/interfaces";
import { MessageV0 } from "js-waku/lib/waku_message/version_0";
import { HandshakeResult, HandshakeStepResult } from "./handshake.js";
import { PayloadV2 } from "./payload.js";
@ -16,7 +16,7 @@ const version = 2;
/**
* Used internally in the pairing object to represent a handshake message
*/
export class NoiseHandshakeMessage extends MessageV0 implements Message {
export class NoiseHandshakeMessage extends DecodedMessage implements IDecodedMessage {
get payloadV2(): PayloadV2 {
if (!this.payload) throw new Error("no payload available");
return PayloadV2.deserialize(this.payload);
@ -27,22 +27,29 @@ export class NoiseHandshakeMessage extends MessageV0 implements Message {
* Used in the pairing object for encoding the messages exchanged
* during the handshake process
*/
export class NoiseHandshakeEncoder implements Encoder {
export class NoiseHandshakeEncoder implements IEncoder {
/**
* @param contentTopic content topic on which the encoded WakuMessages will be sent
* @param hsStepResult the result of a step executed while performing the handshake process
* @param ephemeral makes messages ephemeral in the Waku network
*/
constructor(public contentTopic: string, private hsStepResult: HandshakeStepResult) {}
constructor(
public contentTopic: string,
private hsStepResult: HandshakeStepResult,
public ephemeral: boolean = true
) {}
async encode(message: Message): Promise<Uint8Array | undefined> {
const protoMessage = await this.encodeProto(message);
async toWire(message: IMessage): Promise<Uint8Array | undefined> {
const protoMessage = await this.toProtoObj(message);
if (!protoMessage) return;
return proto_message.WakuMessage.encode(protoMessage);
return WakuMessage.encode(protoMessage);
}
async encodeProto(message: Message): Promise<ProtoMessage | undefined> {
async toProtoObj(message: IMessage): Promise<IProtoMessage | undefined> {
const timestamp = message.timestamp ?? new Date();
return {
ephemeral: this.ephemeral,
rateLimitProof: undefined,
payload: this.hsStepResult.payload2.serialize(),
version: version,
contentTopic: this.contentTopic,
@ -55,19 +62,19 @@ export class NoiseHandshakeEncoder implements Encoder {
* Used in the pairing object for decoding the messages exchanged
* during the handshake process
*/
export class NoiseHandshakeDecoder implements Decoder<NoiseHandshakeMessage> {
export class NoiseHandshakeDecoder implements IDecoder<NoiseHandshakeMessage> {
/**
* @param contentTopic content topic on which the encoded WakuMessages were sent
*/
constructor(public contentTopic: string) {}
decodeProto(bytes: Uint8Array): Promise<ProtoMessage | undefined> {
const protoMessage = proto_message.WakuMessage.decode(bytes);
fromWireToProtoObj(bytes: Uint8Array): Promise<IProtoMessage | undefined> {
const protoMessage = WakuMessage.decode(bytes);
log("Message decoded", protoMessage);
return Promise.resolve(protoMessage);
return Promise.resolve(protoMessage as IProtoMessage);
}
async decode(proto: ProtoMessage): Promise<NoiseHandshakeMessage | undefined> {
async fromProtoObj(proto: IProtoMessage): Promise<NoiseHandshakeMessage | undefined> {
// https://github.com/status-im/js-waku/issues/921
if (proto.version === undefined) {
proto.version = 0;
@ -91,10 +98,10 @@ export class NoiseHandshakeDecoder implements Decoder<NoiseHandshakeMessage> {
* Represents a secure message. These are messages that are transmitted
* after a successful handshake is performed.
*/
export class NoiseSecureMessage extends MessageV0 implements Message {
export class NoiseSecureMessage extends DecodedMessage implements IDecodedMessage {
private readonly _decodedPayload: Uint8Array;
constructor(proto: proto_message.WakuMessage, decodedPayload: Uint8Array) {
constructor(proto: WakuMessage, decodedPayload: Uint8Array) {
super(proto);
this._decodedPayload = decodedPayload;
}
@ -110,20 +117,20 @@ export class NoiseSecureMessage extends MessageV0 implements Message {
* codec will be encrypted with the cipherstates and message nametags that were
* created after a handshake is complete
*/
export class NoiseSecureTransferEncoder implements Encoder {
export class NoiseSecureTransferEncoder implements IEncoder {
/**
* @param contentTopic content topic on which the encoded WakuMessages were sent
* @param hsResult handshake result obtained after the handshake is successful
*/
constructor(public contentTopic: string, private hsResult: HandshakeResult) {}
constructor(public contentTopic: string, private hsResult: HandshakeResult, public ephemeral: boolean = true) {}
async encode(message: Message): Promise<Uint8Array | undefined> {
const protoMessage = await this.encodeProto(message);
async toWire(message: IMessage): Promise<Uint8Array | undefined> {
const protoMessage = await this.toProtoObj(message);
if (!protoMessage) return;
return proto_message.WakuMessage.encode(protoMessage);
return WakuMessage.encode(protoMessage);
}
async encodeProto(message: Message): Promise<ProtoMessage | undefined> {
async toProtoObj(message: IMessage): Promise<IProtoMessage | undefined> {
const timestamp = message.timestamp ?? new Date();
if (!message.payload) {
log("No payload to encrypt, skipping: ", message);
@ -136,6 +143,8 @@ export class NoiseSecureTransferEncoder implements Encoder {
return {
payload,
rateLimitProof: undefined,
ephemeral: this.ephemeral,
version: version,
contentTopic: this.contentTopic,
timestamp: BigInt(timestamp.valueOf()) * OneMillion,
@ -149,35 +158,32 @@ export class NoiseSecureTransferEncoder implements Encoder {
* messages with the cipherstates and message nametags that were created after a
* handshake is complete
*/
export class NoiseSecureTransferDecoder implements Decoder<NoiseSecureMessage> {
export class NoiseSecureTransferDecoder implements IDecoder<NoiseSecureMessage> {
/**
* @param contentTopic content topic on which the encoded WakuMessages were sent
* @param hsResult handshake result obtained after the handshake is successful
*/
constructor(public contentTopic: string, private hsResult: HandshakeResult) {}
decodeProto(bytes: Uint8Array): Promise<ProtoMessage | undefined> {
const protoMessage = proto_message.WakuMessage.decode(bytes);
fromWireToProtoObj(bytes: Uint8Array): Promise<IProtoMessage | undefined> {
const protoMessage = WakuMessage.decode(bytes);
log("Message decoded", protoMessage);
return Promise.resolve(protoMessage);
return Promise.resolve(protoMessage as IProtoMessage);
}
async decode(proto: ProtoMessage): Promise<NoiseSecureMessage | undefined> {
async fromProtoObj(proto: IProtoMessage): Promise<NoiseSecureMessage | undefined> {
// https://github.com/status-im/js-waku/issues/921
if (proto.version === undefined) {
proto.version = 0;
}
if (proto.version !== version) {
log("Failed to decode due to incorrect version, expected:", version, ", actual:", proto.version);
return Promise.resolve(undefined);
}
if (!proto.payload) {
log("No payload, skipping: ", proto);
return;
}
try {
const payloadV2 = PayloadV2.deserialize(proto.payload);
const decryptedPayload = this.hsResult.readMessage(payloadV2);

View File

@ -6,7 +6,7 @@ import { bytes32 } from "./@types/basic.js";
import { MessageNametag } from "./@types/handshake.js";
import type { KeyPair } from "./@types/keypair.js";
import { Curve25519KeySize, dh, generateX25519KeyPair, HKDF, intoCurve25519Key } from "./crypto.js";
import { MessageNametagLength } from "./messagenametag";
import { MessageNametagLength } from "./messagenametag.js";
import { SymmetricState } from "./noise.js";
import { HandshakePattern, MessageDirection, NoiseTokens, PreMessagePattern } from "./patterns.js";
import { NoisePublicKey } from "./publickey.js";

View File

@ -1,8 +1,8 @@
import { HMACDRBG } from "@stablelib/hmac-drbg";
import { randomBytes } from "@stablelib/random";
import type { IDecoder, IEncoder, IMessage } from "@waku/interfaces";
import { expect } from "chai";
import { EventEmitter } from "eventemitter3";
import { Decoder, Encoder, Message } from "js-waku/lib/interfaces";
import { pEvent } from "p-event";
import { equals as uint8ArrayEquals } from "uint8arrays/equals";
@ -24,14 +24,14 @@ describe("js-noise: pairing object", () => {
// Simulate waku. This code is not meant to be used IRL
const msgEmitter = new EventEmitter();
const sender = {
async publish(encoder: Encoder, msg: Message): Promise<void> {
const protoMsg = await encoder.encodeProto(msg);
async publish(encoder: IEncoder, msg: IMessage): Promise<void> {
const protoMsg = await encoder.toProtoObj(msg);
msgEmitter.emit(encoder.contentTopic, protoMsg);
},
};
const decoderMap: { [key: string]: Decoder<NoiseHandshakeMessage> } = {};
const decoderMap: { [key: string]: IDecoder<NoiseHandshakeMessage> } = {};
const responder = {
subscribe(decoder: Decoder<NoiseHandshakeMessage>): Promise<void> {
subscribe(decoder: IDecoder<NoiseHandshakeMessage>): Promise<void> {
return new Promise((resolve) => {
decoderMap[decoder.contentTopic] = decoder;
resolve();
@ -39,7 +39,7 @@ describe("js-noise: pairing object", () => {
},
async nextMessage(contentTopic: string): Promise<NoiseHandshakeMessage> {
const msg = await pEvent(msgEmitter, contentTopic);
const decodedMessage = await decoderMap[contentTopic].decode(msg);
const decodedMessage = await decoderMap[contentTopic].fromProtoObj(msg);
return decodedMessage!;
},
async stop(contentTopic: string): Promise<void> {
@ -79,17 +79,17 @@ describe("js-noise: pairing object", () => {
for (let i = 0; i < 10 * MessageNametagBufferSize; i++) {
// Alice writes to Bob
let message = randomBytes(32, rng);
let encodedMsg = await aliceEncoder.encode({ payload: message });
let readMessageProto = await bobDecoder.decodeProto(encodedMsg!);
let readMessage = await bobDecoder.decode(readMessageProto!);
let encodedMsg = await aliceEncoder.toWire({ payload: message });
let readMessageProto = await bobDecoder.fromWireToProtoObj(encodedMsg!);
let readMessage = await bobDecoder.fromProtoObj(readMessageProto!);
expect(uint8ArrayEquals(message, readMessage!.payload)).to.be.true;
// Bob writes to Alice
message = randomBytes(32, rng);
encodedMsg = await bobEncoder.encode({ payload: message });
readMessageProto = await aliceDecoder.decodeProto(encodedMsg!);
readMessage = await aliceDecoder.decode(readMessageProto!);
encodedMsg = await bobEncoder.toWire({ payload: message });
readMessageProto = await aliceDecoder.fromWireToProtoObj(encodedMsg!);
readMessage = await aliceDecoder.fromProtoObj(readMessageProto!);
expect(uint8ArrayEquals(message, readMessage!.payload)).to.be.true;
}

View File

@ -1,8 +1,8 @@
import { HMACDRBG } from "@stablelib/hmac-drbg";
import { randomBytes } from "@stablelib/random";
import type { IDecoder, IEncoder, IMessage } from "@waku/interfaces";
import debug from "debug";
import { EventEmitter } from "eventemitter3";
import { Decoder, Encoder, Message } from "js-waku/lib/interfaces";
import { pEvent } from "p-event";
import { equals as uint8ArrayEquals } from "uint8arrays/equals";
@ -32,7 +32,7 @@ export interface Sender {
* @param encoder NoiseHandshakeEncoder encoder to use to encrypt the messages
* @param msg message to broadcast
*/
publish(encoder: Encoder, msg: Message): Promise<void>;
publish(encoder: IEncoder, msg: IMessage): Promise<void>;
}
/**
@ -43,7 +43,7 @@ export interface Responder {
* subscribe to receive the messages from a content topic
* @param decoder Decoder to use to decrypt the NoiseHandshakeMessages
*/
subscribe(decoder: Decoder<NoiseHandshakeMessage>): Promise<void>;
subscribe(decoder: IDecoder<NoiseHandshakeMessage>): Promise<void>;
/**
* should return messages received in a content topic

View File

@ -113,12 +113,12 @@ describe("Waku Noise Sessions", () => {
// We prepare a Waku message from Alice's payload2
// At this point wakuMsg is sent over the Waku network and is received
// We simulate this by creating the ProtoBuffer from wakuMsg
let wakuMsgBytes = await encoder.encode({});
let wakuMsgBytes = await encoder.toWire({});
// We decode the WakuMessage from the ProtoBuffer
let decoder = new NoiseHandshakeDecoder(contentTopic);
let wakuMsgProto = await decoder.decodeProto(wakuMsgBytes!);
let v2Msg = await decoder.decode(wakuMsgProto!);
let wakuMsgProto = await decoder.fromWireToProtoObj(wakuMsgBytes!);
let v2Msg = await decoder.fromProtoObj(wakuMsgProto!);
expect(v2Msg!.contentTopic).to.be.equals(contentTopic);
expect(v2Msg?.payloadV2.equals(aliceStep.payload2)).to.be.true;
@ -155,12 +155,12 @@ describe("Waku Noise Sessions", () => {
// At this point wakuMsg is sent over the Waku network and is received
// We simulate this by creating the ProtoBuffer from wakuMsg
wakuMsgBytes = await encoder.encode({});
wakuMsgBytes = await encoder.toWire({});
// We decode the WakuMessage from the ProtoBuffer
decoder = new NoiseHandshakeDecoder(contentTopic);
wakuMsgProto = await decoder.decodeProto(wakuMsgBytes!);
v2Msg = await decoder.decode(wakuMsgProto!);
wakuMsgProto = await decoder.fromWireToProtoObj(wakuMsgBytes!);
v2Msg = await decoder.fromProtoObj(wakuMsgProto!);
expect(v2Msg?.payloadV2.equals(bobStep.payload2)).to.be.true;
@ -192,12 +192,12 @@ describe("Waku Noise Sessions", () => {
// At this point wakuMsg is sent over the Waku network and is received
// We simulate this by creating the ProtoBuffer from wakuMsg
wakuMsgBytes = await encoder.encode({});
wakuMsgBytes = await encoder.toWire({});
// We decode the WakuMessage from the ProtoBuffer
decoder = new NoiseHandshakeDecoder(contentTopic);
wakuMsgProto = await decoder.decodeProto(wakuMsgBytes!);
v2Msg = await decoder.decode(wakuMsgProto!);
wakuMsgProto = await decoder.fromWireToProtoObj(wakuMsgBytes!);
v2Msg = await decoder.fromProtoObj(wakuMsgProto!);
expect(v2Msg?.payloadV2.equals(aliceStep.payload2)).to.be.true;
@ -229,17 +229,17 @@ describe("Waku Noise Sessions", () => {
for (let i = 0; i < 10 * MessageNametagBufferSize; i++) {
// Alice writes to Bob
let message = randomBytes(32, rng);
let encodedMsg = await aliceEncoder.encode({ payload: message });
let readMessageProto = await bobDecoder.decodeProto(encodedMsg!);
let readMessage = await bobDecoder.decode(readMessageProto!);
let encodedMsg = await aliceEncoder.toWire({ payload: message });
let readMessageProto = await bobDecoder.fromWireToProtoObj(encodedMsg!);
let readMessage = await bobDecoder.fromProtoObj(readMessageProto!);
expect(uint8ArrayEquals(message, readMessage!.payload)).to.be.true;
// Bob writes to Alice
message = randomBytes(32, rng);
encodedMsg = await bobEncoder.encode({ payload: message });
readMessageProto = await aliceDecoder.decodeProto(encodedMsg!);
readMessage = await aliceDecoder.decode(readMessageProto!);
encodedMsg = await bobEncoder.toWire({ payload: message });
readMessageProto = await aliceDecoder.fromWireToProtoObj(encodedMsg!);
readMessage = await aliceDecoder.fromProtoObj(readMessageProto!);
expect(uint8ArrayEquals(message, readMessage!.payload)).to.be.true;
}