chore: move args for `createEncoder` into non-repeating `options` & fix typedoc (#1146)

* move args for `createEncoder` into non-repeating `options` & fix typedoc

* update tests with new API
This commit is contained in:
Danish Arora 2023-02-02 11:37:28 +05:30 committed by GitHub
parent 10b3898762
commit 8910a6d76a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 142 additions and 79 deletions

View File

@ -9,7 +9,9 @@ describe("Waku Message version 0", function () {
it("Round trip binary serialization", async function () { it("Round trip binary serialization", async function () {
await fc.assert( await fc.assert(
fc.asyncProperty(fc.uint8Array({ minLength: 1 }), async (payload) => { fc.asyncProperty(fc.uint8Array({ minLength: 1 }), async (payload) => {
const encoder = createEncoder(TestContentTopic); const encoder = createEncoder({
contentTopic: TestContentTopic,
});
const bytes = await encoder.toWire({ payload }); const bytes = await encoder.toWire({ payload });
const decoder = createDecoder(TestContentTopic); const decoder = createDecoder(TestContentTopic);
const protoResult = await decoder.fromWireToProtoObj(bytes); const protoResult = await decoder.fromWireToProtoObj(bytes);
@ -29,7 +31,10 @@ describe("Waku Message version 0", function () {
it("Ephemeral field set to true", async function () { it("Ephemeral field set to true", async function () {
await fc.assert( await fc.assert(
fc.asyncProperty(fc.uint8Array({ minLength: 1 }), async (payload) => { fc.asyncProperty(fc.uint8Array({ minLength: 1 }), async (payload) => {
const encoder = createEncoder(TestContentTopic, true); const encoder = createEncoder({
contentTopic: TestContentTopic,
ephemeral: true,
});
const bytes = await encoder.toWire({ payload }); const bytes = await encoder.toWire({ payload });
const decoder = createDecoder(TestContentTopic); const decoder = createDecoder(TestContentTopic);
const protoResult = await decoder.fromWireToProtoObj(bytes); const protoResult = await decoder.fromWireToProtoObj(bytes);

View File

@ -1,4 +1,5 @@
import type { import type {
EncoderOptions,
IDecodedMessage, IDecodedMessage,
IDecoder, IDecoder,
IEncoder, IEncoder,
@ -99,14 +100,11 @@ export class Encoder implements IEncoder {
* pass to { @link @waku/interfaces.LightPush.push } or * pass to { @link @waku/interfaces.LightPush.push } or
* { @link @waku/interfaces.Relay.send } to automatically encode outgoing * { @link @waku/interfaces.Relay.send } to automatically encode outgoing
* messages. * messages.
*
* @param contentTopic The content topic to set on outgoing messages.
* @param ephemeral An optional flag to mark message as ephemeral, ie, not to be stored by Waku Store nodes.
*/ */
export function createEncoder( export function createEncoder({
contentTopic: string, contentTopic,
ephemeral = false ephemeral,
): Encoder { }: EncoderOptions): Encoder {
return new Encoder(contentTopic, ephemeral); return new Encoder(contentTopic, ephemeral);
} }

View File

@ -263,7 +263,10 @@ export class WakuNode implements Waku {
const relay = this.relay; const relay = this.relay;
if (relay && relayPeriodSecs !== 0) { if (relay && relayPeriodSecs !== 0) {
const encoder = createEncoder(RelayPingContentTopic, true); const encoder = createEncoder({
contentTopic: RelayPingContentTopic,
ephemeral: true,
});
this.relayKeepAliveTimers[peerIdStr] = setInterval(() => { this.relayKeepAliveTimers[peerIdStr] = setInterval(() => {
log("Sending Waku Relay ping message"); log("Sending Waku Relay ping message");
relay relay

View File

@ -30,6 +30,16 @@ export interface IMessage {
rateLimitProof?: IRateLimitProof; rateLimitProof?: IRateLimitProof;
} }
export interface EncoderOptions {
/** The content topic to set on outgoing messages. */
contentTopic: string;
/**
* An optional flag to mark message as ephemeral, i.e., not to be stored by Waku Store nodes.
* @defaultValue `false`
*/
ephemeral?: boolean;
}
export interface IEncoder { export interface IEncoder {
contentTopic: string; contentTopic: string;
ephemeral: boolean; ephemeral: boolean;

View File

@ -15,7 +15,10 @@ describe("Ecies Encryption", function () {
async (payload, privateKey) => { async (payload, privateKey) => {
const publicKey = getPublicKey(privateKey); const publicKey = getPublicKey(privateKey);
const encoder = createEncoder(TestContentTopic, publicKey); const encoder = createEncoder({
contentTopic: TestContentTopic,
publicKey,
});
const bytes = await encoder.toWire({ payload }); const bytes = await encoder.toWire({ payload });
const decoder = createDecoder(TestContentTopic, privateKey); const decoder = createDecoder(TestContentTopic, privateKey);
@ -46,11 +49,11 @@ describe("Ecies Encryption", function () {
const alicePublicKey = getPublicKey(alicePrivateKey); const alicePublicKey = getPublicKey(alicePrivateKey);
const bobPublicKey = getPublicKey(bobPrivateKey); const bobPublicKey = getPublicKey(bobPrivateKey);
const encoder = createEncoder( const encoder = createEncoder({
TestContentTopic, contentTopic: TestContentTopic,
bobPublicKey, publicKey: bobPublicKey,
alicePrivateKey sigPrivKey: alicePrivateKey,
); });
const bytes = await encoder.toWire({ payload }); const bytes = await encoder.toWire({ payload });
const decoder = createDecoder(TestContentTopic, bobPrivateKey); const decoder = createDecoder(TestContentTopic, bobPrivateKey);

View File

@ -1,5 +1,6 @@
import { Decoder as DecoderV0 } from "@waku/core/lib/message/version_0"; import { Decoder as DecoderV0 } from "@waku/core/lib/message/version_0";
import type { import type {
EncoderOptions,
IDecoder, IDecoder,
IEncoder, IEncoder,
IMessage, IMessage,
@ -63,6 +64,13 @@ export class Encoder implements IEncoder {
} }
} }
export interface EciesEncoderOptions extends EncoderOptions {
/** The public key to encrypt the payload for. */
publicKey: Uint8Array;
/** An optional private key to be used to sign the payload before encryption. */
sigPrivKey?: Uint8Array;
}
/** /**
* Creates an encoder that encrypts messages using ECIES for the given public, * Creates an encoder that encrypts messages using ECIES for the given public,
* as defined in [26/WAKU2-PAYLOAD](https://rfc.vac.dev/spec/26/). * as defined in [26/WAKU2-PAYLOAD](https://rfc.vac.dev/spec/26/).
@ -72,21 +80,15 @@ export class Encoder implements IEncoder {
* pass to { @link @waku/interfaces.LightPush.push } or * pass to { @link @waku/interfaces.LightPush.push } or
* { @link @waku/interfaces.Relay.send } to automatically encrypt * { @link @waku/interfaces.Relay.send } to automatically encrypt
* and encode outgoing messages. * and encode outgoing messages.
*
* The payload can optionally be signed with the given private key as defined * The payload can optionally be signed with the given private key as defined
* in [26/WAKU2-PAYLOAD](https://rfc.vac.dev/spec/26/). * in [26/WAKU2-PAYLOAD](https://rfc.vac.dev/spec/26/).
*
* @param contentTopic The content topic to set on outgoing messages.
* @param publicKey The public key to encrypt the payload for.
* @param sigPrivKey An optional private key to used to sign the payload before encryption.
* @param ephemeral An optional flag to mark message as ephemeral, ie, not to be stored by Waku Store nodes.
*/ */
export function createEncoder( export function createEncoder({
contentTopic: string, contentTopic,
publicKey: Uint8Array, publicKey,
sigPrivKey?: Uint8Array, sigPrivKey,
ephemeral = false ephemeral = false,
): Encoder { }: EciesEncoderOptions): Encoder {
return new Encoder(contentTopic, publicKey, sigPrivKey, ephemeral); return new Encoder(contentTopic, publicKey, sigPrivKey, ephemeral);
} }

View File

@ -13,7 +13,10 @@ describe("Symmetric Encryption", function () {
fc.uint8Array({ minLength: 1 }), fc.uint8Array({ minLength: 1 }),
fc.uint8Array({ min: 1, minLength: 32, maxLength: 32 }), fc.uint8Array({ min: 1, minLength: 32, maxLength: 32 }),
async (payload, symKey) => { async (payload, symKey) => {
const encoder = createEncoder(TestContentTopic, symKey); const encoder = createEncoder({
contentTopic: TestContentTopic,
symKey,
});
const bytes = await encoder.toWire({ payload }); const bytes = await encoder.toWire({ payload });
const decoder = createDecoder(TestContentTopic, symKey); const decoder = createDecoder(TestContentTopic, symKey);
@ -41,7 +44,11 @@ describe("Symmetric Encryption", function () {
async (payload, sigPrivKey, symKey) => { async (payload, sigPrivKey, symKey) => {
const sigPubKey = getPublicKey(sigPrivKey); const sigPubKey = getPublicKey(sigPrivKey);
const encoder = createEncoder(TestContentTopic, symKey, sigPrivKey); const encoder = createEncoder({
contentTopic: TestContentTopic,
symKey,
sigPrivKey,
});
const bytes = await encoder.toWire({ payload }); const bytes = await encoder.toWire({ payload });
const decoder = createDecoder(TestContentTopic, symKey); const decoder = createDecoder(TestContentTopic, symKey);

View File

@ -1,5 +1,6 @@
import { Decoder as DecoderV0 } from "@waku/core/lib/message/version_0"; import { Decoder as DecoderV0 } from "@waku/core/lib/message/version_0";
import type { import type {
EncoderOptions,
IDecoder, IDecoder,
IEncoder, IEncoder,
IMessage, IMessage,
@ -61,6 +62,13 @@ export class Encoder implements IEncoder {
} }
} }
export interface SymmetricEncoderOptions extends EncoderOptions {
/** The symmetric key to encrypt the payload with. */
symKey: Uint8Array;
/** An optional private key to be used to sign the payload before encryption. */
sigPrivKey?: Uint8Array;
}
/** /**
* Creates an encoder that encrypts messages using symmetric encryption for the * Creates an encoder that encrypts messages using symmetric encryption for the
* given key, as defined in [26/WAKU2-PAYLOAD](https://rfc.vac.dev/spec/26/). * given key, as defined in [26/WAKU2-PAYLOAD](https://rfc.vac.dev/spec/26/).
@ -73,18 +81,13 @@ export class Encoder implements IEncoder {
* *
* The payload can optionally be signed with the given private key as defined * The payload can optionally be signed with the given private key as defined
* in [26/WAKU2-PAYLOAD](https://rfc.vac.dev/spec/26/). * in [26/WAKU2-PAYLOAD](https://rfc.vac.dev/spec/26/).
*
* @param contentTopic The content topic to set on outgoing messages.
* @param symKey The symmetric key to encrypt the payload with.
* @param sigPrivKey An optional private key to used to sign the payload before encryption.
* @param ephemeral An optional flag to mark message as ephemeral, ie, not to be stored by Waku Store nodes.
*/ */
export function createEncoder( export function createEncoder({
contentTopic: string, contentTopic,
symKey: Uint8Array, symKey,
sigPrivKey?: Uint8Array, sigPrivKey,
ephemeral = false ephemeral = false,
): Encoder { }: SymmetricEncoderOptions): Encoder {
return new Encoder(contentTopic, symKey, sigPrivKey, ephemeral); return new Encoder(contentTopic, symKey, sigPrivKey, ephemeral);
} }

View File

@ -33,7 +33,9 @@ import {
const log = debug("waku:test:ephemeral"); const log = debug("waku:test:ephemeral");
const TestContentTopic = "/test/1/ephemeral/utf8"; const TestContentTopic = "/test/1/ephemeral/utf8";
const TestEncoder = createEncoder(TestContentTopic); const TestEncoder = createEncoder({
contentTopic: TestContentTopic,
});
const TestDecoder = createDecoder(TestContentTopic); const TestDecoder = createDecoder(TestContentTopic);
describe("Waku Message Ephemeral field", () => { describe("Waku Message Ephemeral field", () => {
@ -92,14 +94,20 @@ describe("Waku Message Ephemeral field", () => {
const AsymContentTopic = "/test/1/ephemeral-asym/utf8"; const AsymContentTopic = "/test/1/ephemeral-asym/utf8";
const SymContentTopic = "/test/1/ephemeral-sym/utf8"; const SymContentTopic = "/test/1/ephemeral-sym/utf8";
const asymEncoder = eciesEncoder( const asymEncoder = eciesEncoder({
AsymContentTopic, contentTopic: AsymContentTopic,
publicKey, publicKey,
undefined, ephemeral: true,
true });
); const symEncoder = eciesEncoder({
const symEncoder = eciesEncoder(SymContentTopic, symKey, undefined, true); contentTopic: SymContentTopic,
const clearEncoder = createEncoder(TestContentTopic, true); publicKey: symKey,
ephemeral: true,
});
const clearEncoder = createEncoder({
contentTopic: TestContentTopic,
ephemeral: true,
});
const asymDecoder = eciesDecoder(AsymContentTopic, privateKey); const asymDecoder = eciesDecoder(AsymContentTopic, privateKey);
const symDecoder = eciesDecoder(SymContentTopic, symKey); const symDecoder = eciesDecoder(SymContentTopic, symKey);
@ -159,7 +167,10 @@ describe("Waku Message Ephemeral field", () => {
it("Ephemeral field is preserved - encoder v0", async function () { it("Ephemeral field is preserved - encoder v0", async function () {
this.timeout(10000); this.timeout(10000);
const ephemeralEncoder = createEncoder(TestContentTopic, true); const ephemeralEncoder = createEncoder({
contentTopic: TestContentTopic,
ephemeral: true,
});
const messages: DecodedMessage[] = []; const messages: DecodedMessage[] = [];
const callback = (msg: DecodedMessage): void => { const callback = (msg: DecodedMessage): void => {
@ -199,13 +210,15 @@ describe("Waku Message Ephemeral field", () => {
const symKey = generateSymmetricKey(); const symKey = generateSymmetricKey();
const ephemeralEncoder = symEncoder( const ephemeralEncoder = symEncoder({
TestContentTopic, contentTopic: TestContentTopic,
symKey, symKey,
undefined, ephemeral: true,
true });
); const encoder = symEncoder({
const encoder = symEncoder(TestContentTopic, symKey); contentTopic: TestContentTopic,
symKey,
});
const decoder = symDecoder(TestContentTopic, symKey); const decoder = symDecoder(TestContentTopic, symKey);
const messages: DecodedMessage[] = []; const messages: DecodedMessage[] = [];
@ -247,13 +260,15 @@ describe("Waku Message Ephemeral field", () => {
const privKey = generatePrivateKey(); const privKey = generatePrivateKey();
const pubKey = getPublicKey(privKey); const pubKey = getPublicKey(privKey);
const ephemeralEncoder = eciesEncoder( const ephemeralEncoder = eciesEncoder({
TestContentTopic, contentTopic: TestContentTopic,
pubKey, publicKey: pubKey,
undefined, ephemeral: true,
true });
); const encoder = eciesEncoder({
const encoder = eciesEncoder(TestContentTopic, pubKey); contentTopic: TestContentTopic,
publicKey: pubKey,
});
const decoder = eciesDecoder(TestContentTopic, privKey); const decoder = eciesDecoder(TestContentTopic, privKey);
const messages: DecodedMessage[] = []; const messages: DecodedMessage[] = [];

View File

@ -16,7 +16,7 @@ import { delay, makeLogFileName, NOISE_KEY_1, Nwaku } from "../src/index.js";
const log = debug("waku:test"); const log = debug("waku:test");
const TestContentTopic = "/test/1/waku-filter"; const TestContentTopic = "/test/1/waku-filter";
const TestEncoder = createEncoder(TestContentTopic); const TestEncoder = createEncoder({ contentTopic: TestContentTopic });
const TestDecoder = createDecoder(TestContentTopic); const TestDecoder = createDecoder(TestContentTopic);
describe("Waku Filter", () => { describe("Waku Filter", () => {

View File

@ -17,7 +17,9 @@ import {
const log = debug("waku:test:lightpush"); const log = debug("waku:test:lightpush");
const TestContentTopic = "/test/1/waku-light-push/utf8"; const TestContentTopic = "/test/1/waku-light-push/utf8";
const TestEncoder = createEncoder(TestContentTopic); const TestEncoder = createEncoder({
contentTopic: TestContentTopic,
});
describe("Waku Light Push [node only]", () => { describe("Waku Light Push [node only]", () => {
let waku: LightNode; let waku: LightNode;

View File

@ -37,7 +37,7 @@ import {
const log = debug("waku:test"); const log = debug("waku:test");
const TestContentTopic = "/test/1/waku-relay/utf8"; const TestContentTopic = "/test/1/waku-relay/utf8";
const TestEncoder = createEncoder(TestContentTopic); const TestEncoder = createEncoder({ contentTopic: TestContentTopic });
const TestDecoder = createDecoder(TestContentTopic); const TestDecoder = createDecoder(TestContentTopic);
describe("Waku Relay [node only]", () => { describe("Waku Relay [node only]", () => {
@ -144,8 +144,8 @@ describe("Waku Relay [node only]", () => {
const fooContentTopic = "foo"; const fooContentTopic = "foo";
const barContentTopic = "bar"; const barContentTopic = "bar";
const fooEncoder = createEncoder(fooContentTopic); const fooEncoder = createEncoder({ contentTopic: fooContentTopic });
const barEncoder = createEncoder(barContentTopic); const barEncoder = createEncoder({ contentTopic: barContentTopic });
const fooDecoder = createDecoder(fooContentTopic); const fooDecoder = createDecoder(fooContentTopic);
const barDecoder = createDecoder(barContentTopic); const barDecoder = createDecoder(barContentTopic);
@ -193,8 +193,14 @@ describe("Waku Relay [node only]", () => {
const symKey = generateSymmetricKey(); const symKey = generateSymmetricKey();
const publicKey = getPublicKey(privateKey); const publicKey = getPublicKey(privateKey);
const eciesEncoder = createEciesEncoder(asymTopic, publicKey); const eciesEncoder = createEciesEncoder({
const symEncoder = createSymEncoder(symTopic, symKey); contentTopic: asymTopic,
publicKey,
});
const symEncoder = createSymEncoder({
contentTopic: symTopic,
symKey,
});
const eciesDecoder = createEciesDecoder(asymTopic, privateKey); const eciesDecoder = createEciesDecoder(asymTopic, privateKey);
const symDecoder = createSymDecoder(symTopic, symKey); const symDecoder = createSymDecoder(symTopic, symKey);
@ -240,7 +246,7 @@ describe("Waku Relay [node only]", () => {
setTimeout(resolve, 500); setTimeout(resolve, 500);
} }
); );
await waku1.relay.send(createEncoder(contentTopic), { await waku1.relay.send(createEncoder({ contentTopic }), {
payload: utf8ToBytes(messageText), payload: utf8ToBytes(messageText),
}); });

View File

@ -34,7 +34,7 @@ import {
const log = debug("waku:test:store"); const log = debug("waku:test:store");
const TestContentTopic = "/test/1/waku-store/utf8"; const TestContentTopic = "/test/1/waku-store/utf8";
const TestEncoder = createEncoder(TestContentTopic); const TestEncoder = createEncoder({ contentTopic: TestContentTopic });
const TestDecoder = createDecoder(TestContentTopic); const TestDecoder = createDecoder(TestContentTopic);
describe("Waku Store", () => { describe("Waku Store", () => {
@ -371,13 +371,19 @@ describe("Waku Store", () => {
const symKey = generateSymmetricKey(); const symKey = generateSymmetricKey();
const publicKey = getPublicKey(privateKey); const publicKey = getPublicKey(privateKey);
const eciesEncoder = createEciesEncoder(asymTopic, publicKey); const eciesEncoder = createEciesEncoder({
const symEncoder = createSymEncoder(symTopic, symKey); contentTopic: asymTopic,
publicKey,
});
const symEncoder = createSymEncoder({
contentTopic: symTopic,
symKey,
});
const otherEncoder = createEciesEncoder( const otherEncoder = createEciesEncoder({
TestContentTopic, contentTopic: TestContentTopic,
getPublicKey(generatePrivateKey()) publicKey: getPublicKey(generatePrivateKey()),
); });
const eciesDecoder = createEciesDecoder(asymTopic, privateKey); const eciesDecoder = createEciesDecoder(asymTopic, privateKey);
const symDecoder = createSymDecoder(symTopic, symKey); const symDecoder = createSymDecoder(symTopic, symKey);

View File

@ -171,7 +171,10 @@ describe("Decryption Keys", () => {
const symKey = generateSymmetricKey(); const symKey = generateSymmetricKey();
const decoder = createDecoder(TestContentTopic, symKey); const decoder = createDecoder(TestContentTopic, symKey);
const encoder = createEncoder(TestContentTopic, symKey); const encoder = createEncoder({
contentTopic: TestContentTopic,
symKey,
});
const messageText = "Message is encrypted"; const messageText = "Message is encrypted";
const messageTimestamp = new Date("1995-12-17T03:24:00"); const messageTimestamp = new Date("1995-12-17T03:24:00");
const message = { const message = {