feat!: hide `Decoder`/`Encoder` classes to user

Reasoning: by exposing the `Decoder` and `Encoder` classes to the user,
the user may care about them, try to use the method etc.

By "hiding" them away and providing `create*` help, the aim is for the
user to just call a function instead of instantiating a class.

Also, `V0` does not provide much information to the user so removing it.
This commit is contained in:
fryorcraken.eth 2022-11-23 16:25:50 +11:00
parent 0f5bef78d1
commit ad15f861c3
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
11 changed files with 165 additions and 103 deletions

View File

@ -12,7 +12,7 @@ import {
LightPushCodec,
LightPushComponents,
} from "./waku_light_push/index.js";
import { EncoderV0 } from "./waku_message/version_0.js";
import { createEncoder } from "./waku_message/version_0.js";
import * as relayConstants from "./waku_relay/constants.js";
import { RelayCodecs, RelayPingContentTopic } from "./waku_relay/constants.js";
import { StoreCodec, StoreComponents } from "./waku_store/index.js";
@ -214,7 +214,7 @@ export class WakuNode implements Waku {
const relay = this.relay;
if (relay && relayPeriodSecs !== 0) {
const encoder = new EncoderV0(RelayPingContentTopic);
const encoder = createEncoder(RelayPingContentTopic);
this.relayKeepAliveTimers[peerIdStr] = setInterval(() => {
log("Sending Waku Relay ping message");
relay

View File

@ -1,7 +1,7 @@
import { expect } from "chai";
import fc from "fast-check";
import { DecoderV0, EncoderV0, MessageV0 } from "./version_0.js";
import { createDecoder, createEncoder, DecodedMessage } from "./version_0.js";
const TestContentTopic = "/test/1/waku-message/utf8";
@ -9,11 +9,13 @@ describe("Waku Message version 0", function () {
it("Round trip binary serialization", async function () {
await fc.assert(
fc.asyncProperty(fc.uint8Array({ minLength: 1 }), async (payload) => {
const encoder = new EncoderV0(TestContentTopic);
const encoder = createEncoder(TestContentTopic);
const bytes = await encoder.toWire({ payload });
const decoder = new DecoderV0(TestContentTopic);
const decoder = createDecoder(TestContentTopic);
const protoResult = await decoder.fromWireToProtoObj(bytes);
const result = (await decoder.fromProtoObj(protoResult!)) as MessageV0;
const result = (await decoder.fromProtoObj(
protoResult!
)) as DecodedMessage;
expect(result.contentTopic).to.eq(TestContentTopic);
expect(result.version).to.eq(0);
@ -27,11 +29,13 @@ describe("Waku Message version 0", function () {
it("Ephemeral field set to true", async function () {
await fc.assert(
fc.asyncProperty(fc.uint8Array({ minLength: 1 }), async (payload) => {
const encoder = new EncoderV0(TestContentTopic, true);
const encoder = createEncoder(TestContentTopic, true);
const bytes = await encoder.toWire({ payload });
const decoder = new DecoderV0(TestContentTopic);
const decoder = createDecoder(TestContentTopic);
const protoResult = await decoder.fromWireToProtoObj(bytes);
const result = (await decoder.fromProtoObj(protoResult!)) as MessageV0;
const result = (await decoder.fromProtoObj(
protoResult!
)) as DecodedMessage;
expect(result.contentTopic).to.eq(TestContentTopic);
expect(result.version).to.eq(0);

View File

@ -71,7 +71,7 @@ export class DecodedMessage implements IDecodedMessage {
}
}
class Encoder implements IEncoder {
export class Encoder implements IEncoder {
constructor(public contentTopic: string, public ephemeral: boolean = false) {}
async toWire(message: Partial<Message>): Promise<Uint8Array> {
@ -138,6 +138,6 @@ export class Decoder implements IDecoder<DecodedMessage> {
export function createDecoder(
contentTopic: string,
ephemeral = false
): Encoder {
): Decoder {
return new Decoder(contentTopic, ephemeral);
}

View File

@ -4,16 +4,16 @@ import fc from "fast-check";
import { getPublicKey } from "./crypto.js";
import {
AsymDecoder,
AsymEncoder,
createAsymDecoder,
createAsymEncoder,
createSymDecoder,
createSymEncoder,
decryptAsymmetric,
decryptSymmetric,
encryptAsymmetric,
encryptSymmetric,
postCipher,
preCipher,
SymDecoder,
SymEncoder,
} from "./index.js";
const TestContentTopic = "/test/1/waku-message/utf8";
@ -27,10 +27,10 @@ describe("Waku Message version 1", function () {
async (payload, privateKey) => {
const publicKey = getPublicKey(privateKey);
const encoder = new AsymEncoder(TestContentTopic, publicKey);
const encoder = createAsymEncoder(TestContentTopic, publicKey);
const bytes = await encoder.toWire({ payload });
const decoder = new AsymDecoder(TestContentTopic, privateKey);
const decoder = createAsymDecoder(TestContentTopic, privateKey);
const protoResult = await decoder.fromWireToProtoObj(bytes!);
if (!protoResult) throw "Failed to proto decode";
const result = await decoder.fromProtoObj(protoResult);
@ -58,14 +58,14 @@ describe("Waku Message version 1", function () {
const alicePublicKey = getPublicKey(alicePrivateKey);
const bobPublicKey = getPublicKey(bobPrivateKey);
const encoder = new AsymEncoder(
const encoder = createAsymEncoder(
TestContentTopic,
bobPublicKey,
alicePrivateKey
);
const bytes = await encoder.toWire({ payload });
const decoder = new AsymDecoder(TestContentTopic, bobPrivateKey);
const decoder = createAsymDecoder(TestContentTopic, bobPrivateKey);
const protoResult = await decoder.fromWireToProtoObj(bytes!);
if (!protoResult) throw "Failed to proto decode";
const result = await decoder.fromProtoObj(protoResult);
@ -87,10 +87,10 @@ describe("Waku Message version 1", function () {
fc.uint8Array({ minLength: 1 }),
fc.uint8Array({ min: 1, minLength: 32, maxLength: 32 }),
async (payload, symKey) => {
const encoder = new SymEncoder(TestContentTopic, symKey);
const encoder = createSymEncoder(TestContentTopic, symKey);
const bytes = await encoder.toWire({ payload });
const decoder = new SymDecoder(TestContentTopic, symKey);
const decoder = createSymDecoder(TestContentTopic, symKey);
const protoResult = await decoder.fromWireToProtoObj(bytes!);
if (!protoResult) throw "Failed to proto decode";
const result = await decoder.fromProtoObj(protoResult);
@ -115,10 +115,14 @@ describe("Waku Message version 1", function () {
async (payload, sigPrivKey, symKey) => {
const sigPubKey = getPublicKey(sigPrivKey);
const encoder = new SymEncoder(TestContentTopic, symKey, sigPrivKey);
const encoder = createSymEncoder(
TestContentTopic,
symKey,
sigPrivKey
);
const bytes = await encoder.toWire({ payload });
const decoder = new SymDecoder(TestContentTopic, symKey);
const decoder = createSymDecoder(TestContentTopic, symKey);
const protoResult = await decoder.fromWireToProtoObj(bytes!);
if (!protoResult) throw "Failed to proto decode";
const result = await decoder.fromProtoObj(protoResult);

View File

@ -1,14 +1,14 @@
import * as secp from "@noble/secp256k1";
import { concat, hexToBytes } from "@waku/byte-utils";
import {
DecoderV0,
MessageV0,
DecodedMessage as DecodedMessageV0,
Decoder as DecoderV0,
proto,
} from "@waku/core/lib/waku_message/version_0";
import type {
DecodedMessage,
Decoder,
Encoder,
DecodedMessage as IDecodedMessage,
Decoder as IDecoder,
Encoder as IEncoder,
Message,
ProtoMessage,
} from "@waku/interfaces";
@ -44,7 +44,10 @@ export type Signature = {
publicKey: Uint8Array | undefined;
};
export class MessageV1 extends MessageV0 implements DecodedMessage {
export class DecodedMessage
extends DecodedMessageV0
implements IDecodedMessage
{
private readonly _decodedPayload: Uint8Array;
constructor(
@ -62,7 +65,7 @@ export class MessageV1 extends MessageV0 implements DecodedMessage {
}
}
export class AsymEncoder implements Encoder {
class AsymEncoder implements IEncoder {
constructor(
public contentTopic: string,
private publicKey: Uint8Array,
@ -100,7 +103,16 @@ export class AsymEncoder implements Encoder {
}
}
export class SymEncoder implements Encoder {
export function createAsymEncoder(
contentTopic: string,
publicKey: Uint8Array,
sigPrivKey?: Uint8Array,
ephemeral = false
): AsymEncoder {
return new AsymEncoder(contentTopic, publicKey, sigPrivKey, ephemeral);
}
class SymEncoder implements IEncoder {
constructor(
public contentTopic: string,
private symKey: Uint8Array,
@ -137,14 +149,23 @@ export class SymEncoder implements Encoder {
}
}
export class AsymDecoder extends DecoderV0 implements Decoder<MessageV1> {
export function createSymEncoder(
contentTopic: string,
symKey: Uint8Array,
sigPrivKey?: Uint8Array,
ephemeral = false
): SymEncoder {
return new SymEncoder(contentTopic, symKey, sigPrivKey, ephemeral);
}
class AsymDecoder extends DecoderV0 implements IDecoder<DecodedMessage> {
constructor(contentTopic: string, private privateKey: Uint8Array) {
super(contentTopic);
}
async fromProtoObj(
protoMessage: ProtoMessage
): Promise<MessageV1 | undefined> {
): Promise<DecodedMessage | undefined> {
const cipherPayload = protoMessage.payload;
if (protoMessage.version !== Version) {
@ -186,7 +207,7 @@ export class AsymDecoder extends DecoderV0 implements Decoder<MessageV1> {
}
log("Message decrypted", protoMessage);
return new MessageV1(
return new DecodedMessage(
protoMessage,
res.payload,
res.sig?.signature,
@ -195,14 +216,21 @@ export class AsymDecoder extends DecoderV0 implements Decoder<MessageV1> {
}
}
export class SymDecoder extends DecoderV0 implements Decoder<MessageV1> {
export function createAsymDecoder(
contentTopic: string,
privateKey: Uint8Array
): AsymDecoder {
return new AsymDecoder(contentTopic, privateKey);
}
class SymDecoder extends DecoderV0 implements IDecoder<DecodedMessage> {
constructor(contentTopic: string, private symKey: Uint8Array) {
super(contentTopic);
}
async fromProtoObj(
protoMessage: ProtoMessage
): Promise<MessageV1 | undefined> {
): Promise<DecodedMessage | undefined> {
const cipherPayload = protoMessage.payload;
if (protoMessage.version !== Version) {
@ -244,7 +272,7 @@ export class SymDecoder extends DecoderV0 implements Decoder<MessageV1> {
}
log("Message decrypted", protoMessage);
return new MessageV1(
return new DecodedMessage(
protoMessage,
res.payload,
res.sig?.signature,
@ -253,6 +281,13 @@ export class SymDecoder extends DecoderV0 implements Decoder<MessageV1> {
}
}
export function createSymDecoder(
contentTopic: string,
symKey: Uint8Array
): SymDecoder {
return new SymDecoder(contentTopic, symKey);
}
function getSizeOfPayloadSizeField(message: Uint8Array): number {
const messageDataView = new DataView(message.buffer);
return messageDataView.getUint8(0) & FlagMask;

View File

@ -1,16 +1,20 @@
import { bytesToUtf8, utf8ToBytes } from "@waku/byte-utils";
import { waitForRemotePeer } from "@waku/core/lib/wait_for_remote_peer";
import { DecoderV0, EncoderV0 } from "@waku/core/lib/waku_message/version_0";
import { createLightNode } from "@waku/create";
import { DecodedMessage, Protocols, WakuLight } from "@waku/interfaces";
import {
AsymDecoder,
AsymEncoder,
createDecoder,
createEncoder,
DecodedMessage,
} from "@waku/core/lib/waku_message/version_0";
import { createLightNode } from "@waku/create";
import { Protocols, WakuLight } from "@waku/interfaces";
import {
createAsymDecoder,
createAsymEncoder,
createSymDecoder,
createSymEncoder,
generatePrivateKey,
generateSymmetricKey,
getPublicKey,
SymDecoder,
SymEncoder,
} from "@waku/message-encryption";
import { expect } from "chai";
import debug from "debug";
@ -26,8 +30,8 @@ import {
const log = debug("waku:test:ephemeral");
const TestContentTopic = "/test/1/ephemeral/utf8";
const TestEncoder = new EncoderV0(TestContentTopic);
const TestDecoder = new DecoderV0(TestContentTopic);
const TestEncoder = createEncoder(TestContentTopic);
const TestDecoder = createDecoder(TestContentTopic);
describe("Waku Message Ephemeral field", () => {
let waku: WakuLight;
@ -75,17 +79,22 @@ describe("Waku Message Ephemeral field", () => {
const AsymContentTopic = "/test/1/ephemeral-asym/utf8";
const SymContentTopic = "/test/1/ephemeral-sym/utf8";
const asymEncoder = new AsymEncoder(
const asymEncoder = createAsymEncoder(
AsymContentTopic,
publicKey,
undefined,
true
);
const symEncoder = new SymEncoder(SymContentTopic, symKey, undefined, true);
const clearEncoder = new EncoderV0(TestContentTopic, true);
const symEncoder = createSymEncoder(
SymContentTopic,
symKey,
undefined,
true
);
const clearEncoder = createEncoder(TestContentTopic, true);
const asymDecoder = new AsymDecoder(AsymContentTopic, privateKey);
const symDecoder = new SymDecoder(SymContentTopic, symKey);
const asymDecoder = createAsymDecoder(AsymContentTopic, privateKey);
const symDecoder = createSymDecoder(SymContentTopic, symKey);
const [waku1, waku2, nimWakuMultiaddr] = await Promise.all([
createLightNode({
@ -142,7 +151,7 @@ describe("Waku Message Ephemeral field", () => {
it("Ephemeral field is preserved - encoder v0", async function () {
this.timeout(10000);
const ephemeralEncoder = new EncoderV0(TestContentTopic, true);
const ephemeralEncoder = createEncoder(TestContentTopic, true);
const messages: DecodedMessage[] = [];
const callback = (msg: DecodedMessage): void => {
@ -182,14 +191,14 @@ describe("Waku Message Ephemeral field", () => {
const symKey = generateSymmetricKey();
const ephemeralEncoder = new SymEncoder(
const ephemeralEncoder = createSymEncoder(
TestContentTopic,
symKey,
undefined,
true
);
const encoder = new SymEncoder(TestContentTopic, symKey);
const decoder = new SymDecoder(TestContentTopic, symKey);
const encoder = createSymEncoder(TestContentTopic, symKey);
const decoder = createSymDecoder(TestContentTopic, symKey);
const messages: DecodedMessage[] = [];
const callback = (msg: DecodedMessage): void => {
@ -230,14 +239,14 @@ describe("Waku Message Ephemeral field", () => {
const privKey = generatePrivateKey();
const pubKey = getPublicKey(privKey);
const ephemeralEncoder = new AsymEncoder(
const ephemeralEncoder = createAsymEncoder(
TestContentTopic,
pubKey,
undefined,
true
);
const encoder = new AsymEncoder(TestContentTopic, pubKey);
const decoder = new AsymDecoder(TestContentTopic, privKey);
const encoder = createAsymEncoder(TestContentTopic, pubKey);
const decoder = createAsymDecoder(TestContentTopic, privKey);
const messages: DecodedMessage[] = [];
const callback = (msg: DecodedMessage): void => {

View File

@ -1,6 +1,9 @@
import { bytesToUtf8, utf8ToBytes } from "@waku/byte-utils";
import { waitForRemotePeer } from "@waku/core/lib/wait_for_remote_peer";
import { DecoderV0, EncoderV0 } from "@waku/core/lib/waku_message/version_0";
import {
createDecoder,
createEncoder,
} from "@waku/core/lib/waku_message/version_0";
import { createLightNode } from "@waku/create";
import type { DecodedMessage, WakuLight } from "@waku/interfaces";
import { Protocols } from "@waku/interfaces";
@ -12,8 +15,8 @@ import { delay, makeLogFileName, NOISE_KEY_1, Nwaku } from "../src/index.js";
const log = debug("waku:test");
const TestContentTopic = "/test/1/waku-filter";
const TestEncoder = new EncoderV0(TestContentTopic);
const TestDecoder = new DecoderV0(TestContentTopic);
const TestEncoder = createEncoder(TestContentTopic);
const TestDecoder = createDecoder(TestContentTopic);
describe("Waku Filter", () => {
let waku: WakuLight;

View File

@ -1,6 +1,6 @@
import { bytesToUtf8, utf8ToBytes } from "@waku/byte-utils";
import { waitForRemotePeer } from "@waku/core/lib/wait_for_remote_peer";
import { EncoderV0 } from "@waku/core/lib/waku_message/version_0";
import { createEncoder } from "@waku/core/lib/waku_message/version_0";
import { createLightNode } from "@waku/create";
import type { WakuLight } from "@waku/interfaces";
import { Protocols } from "@waku/interfaces";
@ -18,7 +18,7 @@ import {
const log = debug("waku:test:lightpush");
const TestContentTopic = "/test/1/waku-light-push/utf8";
const TestEncoder = new EncoderV0(TestContentTopic);
const TestEncoder = createEncoder(TestContentTopic);
describe("Waku Light Push [node only]", () => {
let waku: WakuLight;

View File

@ -3,21 +3,21 @@ import { bytesToUtf8, utf8ToBytes } from "@waku/byte-utils";
import { DefaultPubSubTopic } from "@waku/core";
import { waitForRemotePeer } from "@waku/core/lib/wait_for_remote_peer";
import {
DecoderV0,
EncoderV0,
MessageV0,
createDecoder,
createEncoder,
DecodedMessage,
} from "@waku/core/lib/waku_message/version_0";
import { createPrivacyNode } from "@waku/create";
import type { DecodedMessage, WakuPrivacy } from "@waku/interfaces";
import type { WakuPrivacy } from "@waku/interfaces";
import { Protocols } from "@waku/interfaces";
import {
AsymDecoder,
AsymEncoder,
createAsymDecoder,
createAsymEncoder,
createSymDecoder,
createSymEncoder,
generatePrivateKey,
generateSymmetricKey,
getPublicKey,
SymDecoder,
SymEncoder,
} from "@waku/message-encryption";
import { expect } from "chai";
import debug from "debug";
@ -35,8 +35,8 @@ import {
const log = debug("waku:test");
const TestContentTopic = "/test/1/waku-relay/utf8";
const TestEncoder = new EncoderV0(TestContentTopic);
const TestDecoder = new DecoderV0(TestContentTopic);
const TestEncoder = createEncoder(TestContentTopic);
const TestDecoder = createDecoder(TestContentTopic);
describe("Waku Relay [node only]", () => {
// Node needed as we don't have a way to connect 2 js waku
@ -142,11 +142,11 @@ describe("Waku Relay [node only]", () => {
const fooContentTopic = "foo";
const barContentTopic = "bar";
const fooEncoder = new EncoderV0(fooContentTopic);
const barEncoder = new EncoderV0(barContentTopic);
const fooEncoder = createEncoder(fooContentTopic);
const barEncoder = createEncoder(barContentTopic);
const fooDecoder = new DecoderV0(fooContentTopic);
const barDecoder = new DecoderV0(barContentTopic);
const fooDecoder = createDecoder(fooContentTopic);
const barDecoder = createDecoder(barContentTopic);
const fooMessages: DecodedMessage[] = [];
waku2.relay.addObserver(fooDecoder, (msg) => {
@ -191,11 +191,11 @@ describe("Waku Relay [node only]", () => {
const symKey = generateSymmetricKey();
const publicKey = getPublicKey(privateKey);
const asymEncoder = new AsymEncoder(asymTopic, publicKey);
const symEncoder = new SymEncoder(symTopic, symKey);
const asymEncoder = createAsymEncoder(asymTopic, publicKey);
const symEncoder = createSymEncoder(symTopic, symKey);
const asymDecoder = new AsymDecoder(asymTopic, privateKey);
const symDecoder = new SymDecoder(symTopic, symKey);
const asymDecoder = createAsymDecoder(asymTopic, privateKey);
const symDecoder = createSymDecoder(symTopic, symKey);
const msgs: DecodedMessage[] = [];
waku2.relay.addObserver(asymDecoder, (wakuMsg) => {
@ -231,14 +231,14 @@ describe("Waku Relay [node only]", () => {
const receivedMsgPromise: Promise<DecodedMessage> = new Promise(
(resolve, reject) => {
const deleteObserver = waku2.relay.addObserver(
new DecoderV0(contentTopic),
createDecoder(contentTopic),
reject
);
deleteObserver();
setTimeout(resolve, 500);
}
);
await waku1.relay.send(new EncoderV0(contentTopic), {
await waku1.relay.send(createEncoder(contentTopic), {
payload: utf8ToBytes(messageText),
});
@ -391,9 +391,13 @@ describe("Waku Relay [node only]", () => {
const messageText = "Here is another message.";
const receivedMsgPromise: Promise<MessageV0> = new Promise((resolve) => {
waku.relay.addObserver<MessageV0>(TestDecoder, (msg) => resolve(msg));
});
const receivedMsgPromise: Promise<DecodedMessage> = new Promise(
(resolve) => {
waku.relay.addObserver<DecodedMessage>(TestDecoder, (msg) =>
resolve(msg)
);
}
);
await nwaku.sendMessage(
Nwaku.toMessageRpcQuery({
@ -405,7 +409,7 @@ describe("Waku Relay [node only]", () => {
const receivedMsg = await receivedMsgPromise;
expect(receivedMsg.contentTopic).to.eq(TestContentTopic);
expect(receivedMsg.version).to.eq(0);
expect(receivedMsg.version!).to.eq(0);
expect(bytesToUtf8(receivedMsg.payload!)).to.eq(messageText);
});

View File

@ -1,18 +1,21 @@
import { bytesToUtf8, utf8ToBytes } from "@waku/byte-utils";
import { createCursor, PageDirection } from "@waku/core";
import { waitForRemotePeer } from "@waku/core/lib/wait_for_remote_peer";
import { DecoderV0, EncoderV0 } from "@waku/core/lib/waku_message/version_0";
import {
createDecoder,
createEncoder,
} from "@waku/core/lib/waku_message/version_0";
import { createLightNode } from "@waku/create";
import { DecodedMessage, Message, WakuLight } from "@waku/interfaces";
import { Protocols } from "@waku/interfaces";
import {
AsymDecoder,
AsymEncoder,
createAsymDecoder,
createAsymEncoder,
createSymDecoder,
createSymEncoder,
generatePrivateKey,
generateSymmetricKey,
getPublicKey,
SymDecoder,
SymEncoder,
} from "@waku/message-encryption";
import { expect } from "chai";
import debug from "debug";
@ -28,8 +31,8 @@ import {
const log = debug("waku:test:store");
const TestContentTopic = "/test/1/waku-store/utf8";
const TestEncoder = new EncoderV0(TestContentTopic);
const TestDecoder = new DecoderV0(TestContentTopic);
const TestEncoder = createEncoder(TestContentTopic);
const TestDecoder = createDecoder(TestContentTopic);
describe("Waku Store", () => {
let waku: WakuLight;
@ -365,16 +368,16 @@ describe("Waku Store", () => {
const symKey = generateSymmetricKey();
const publicKey = getPublicKey(privateKey);
const asymEncoder = new AsymEncoder(asymTopic, publicKey);
const symEncoder = new SymEncoder(symTopic, symKey);
const asymEncoder = createAsymEncoder(asymTopic, publicKey);
const symEncoder = createSymEncoder(symTopic, symKey);
const otherEncoder = new AsymEncoder(
const otherEncoder = createAsymEncoder(
TestContentTopic,
getPublicKey(generatePrivateKey())
);
const asymDecoder = new AsymDecoder(asymTopic, privateKey);
const symDecoder = new SymDecoder(symTopic, symKey);
const asymDecoder = createAsymDecoder(asymTopic, privateKey);
const symDecoder = createSymDecoder(symTopic, symKey);
const [waku1, waku2, nimWakuMultiaddr] = await Promise.all([
createLightNode({

View File

@ -12,9 +12,9 @@ import type {
} from "@waku/interfaces";
import { Protocols } from "@waku/interfaces";
import {
createSymDecoder,
createSymEncoder,
generateSymmetricKey,
SymDecoder,
SymEncoder,
} from "@waku/message-encryption";
import { expect } from "chai";
@ -167,9 +167,9 @@ describe("Decryption Keys", () => {
this.timeout(10000);
const symKey = generateSymmetricKey();
const decoder = new SymDecoder(TestContentTopic, symKey);
const decoder = createSymDecoder(TestContentTopic, symKey);
const encoder = new SymEncoder(TestContentTopic, symKey);
const encoder = createSymEncoder(TestContentTopic, symKey);
const messageText = "Message is encrypted";
const messageTimestamp = new Date("1995-12-17T03:24:00");
const message = {