diff --git a/src/codec.spec.ts b/src/codec.spec.ts index 9462d71..5f6249f 100644 --- a/src/codec.spec.ts +++ b/src/codec.spec.ts @@ -3,6 +3,7 @@ import { createEncoder, DecodedMessage, } from "@waku/core/lib/message/version_0"; +import type { IProtoMessage } from "@waku/interfaces"; import { generatePrivateKey, generateSymmetricKey, @@ -32,6 +33,15 @@ import * as rln from "./index.js"; const TestContentTopic = "/test/1/waku-message/utf8"; const EMPTY_PUBSUB_TOPIC = ""; +const EMPTY_PROTO_MESSAGE = { + timestamp: undefined, + contentTopic: "", + ephemeral: undefined, + meta: undefined, + rateLimitProof: undefined, + version: undefined, +}; + describe("RLN codec with version 0", () => { it("toWire", async function () { const rlnInstance = await rln.create(); @@ -352,3 +362,110 @@ describe("RLN Codec - epoch", () => { expect(msg.timestamp).to.not.be.undefined; }); }); + +describe("RLN codec with version 0 and meta setter", () => { + // Encode the length of the payload + // Not a relevant real life example + const metaSetter = (msg: IProtoMessage & { meta: undefined }): Uint8Array => { + const buffer = new ArrayBuffer(4); + const view = new DataView(buffer); + view.setUint32(0, msg.payload.length, false); + return new Uint8Array(buffer); + }; + + it("toWire", async function () { + const rlnInstance = await rln.create(); + const credential = rlnInstance.generateIdentityCredentials(); + const index = 0; + const payload = new Uint8Array([1, 2, 3, 4, 5]); + + rlnInstance.insertMember(credential.IDCommitment); + + const rlnEncoder = createRLNEncoder({ + encoder: createEncoder({ contentTopic: TestContentTopic, metaSetter }), + rlnInstance, + index, + credential, + }); + const rlnDecoder = createRLNDecoder({ + rlnInstance, + decoder: createDecoder(TestContentTopic), + }); + + const bytes = await rlnEncoder.toWire({ payload }); + + expect(bytes).to.not.be.undefined; + const protoResult = await rlnDecoder.fromWireToProtoObj(bytes!); + expect(protoResult).to.not.be.undefined; + const msg = (await rlnDecoder.fromProtoObj( + EMPTY_PUBSUB_TOPIC, + protoResult! + ))!; + + const expectedMeta = metaSetter({ + ...EMPTY_PROTO_MESSAGE, + payload: protoResult!.payload, + }); + + expect(msg!.meta).to.deep.eq(expectedMeta); + + expect(msg.rateLimitProof).to.not.be.undefined; + expect(msg.verify([rlnInstance.getMerkleRoot()])).to.be.true; + expect(msg.verifyNoRoot()).to.be.true; + expect(msg.epoch).to.not.be.undefined; + expect(msg.epoch).to.be.gt(0); + + expect(msg.contentTopic).to.eq(TestContentTopic); + expect(msg.msg.version).to.eq(0); + expect(msg.payload).to.deep.eq(payload); + expect(msg.timestamp).to.not.be.undefined; + }); + + it("toProtoObj", async function () { + const rlnInstance = await rln.create(); + const credential = rlnInstance.generateIdentityCredentials(); + const index = 0; + const payload = new Uint8Array([1, 2, 3, 4, 5]); + + rlnInstance.insertMember(credential.IDCommitment); + + const rlnEncoder = new RLNEncoder( + createEncoder({ contentTopic: TestContentTopic, metaSetter }), + rlnInstance, + index, + credential + ); + const rlnDecoder = new RLNDecoder( + rlnInstance, + createDecoder(TestContentTopic) + ); + + const proto = await rlnEncoder.toProtoObj({ payload }); + + expect(proto).to.not.be.undefined; + const msg = (await rlnDecoder.fromProtoObj( + EMPTY_PUBSUB_TOPIC, + proto! + )) as RlnMessage; + + const expectedMeta = metaSetter({ + ...EMPTY_PROTO_MESSAGE, + payload: msg!.payload, + }); + + expect(msg!.meta).to.deep.eq(expectedMeta); + + expect(msg).to.not.be.undefined; + expect(msg.rateLimitProof).to.not.be.undefined; + + expect(msg.verify([rlnInstance.getMerkleRoot()])).to.be.true; + expect(msg.verifyNoRoot()).to.be.true; + expect(msg.epoch).to.not.be.undefined; + expect(msg.epoch).to.be.gt(0); + + expect(msg.contentTopic).to.eq(TestContentTopic); + expect(msg.msg.version).to.eq(0); + expect(msg.payload).to.deep.eq(payload); + expect(msg.timestamp).to.not.be.undefined; + }); +}); diff --git a/src/index.spec.ts b/src/index.spec.ts index cd231ce..30f5fea 100644 --- a/src/index.spec.ts +++ b/src/index.spec.ts @@ -113,6 +113,7 @@ describe("js-rln", () => { console.log(err); } }); + it("should generate the same membership key if the same seed is provided", async function () { const rlnInstance = await rln.create(); const seed = "This is a test seed"; diff --git a/src/message.ts b/src/message.ts index 2e8afc6..ffb5c00 100644 --- a/src/message.ts +++ b/src/message.ts @@ -57,6 +57,10 @@ export class RlnMessage implements IDecodedMessage { return this.msg.ephemeral; } + get meta(): Uint8Array | undefined { + return this.msg.meta; + } + get epoch(): number | undefined { const bytes = this.msg.rateLimitProof?.epoch; if (!bytes) return;