feat: add RlnMessage for handy helpers

This commit is contained in:
fryorcraken.eth 2022-09-28 14:23:10 +10:00
parent b0b9e1e46b
commit 382794d25f
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
3 changed files with 56 additions and 23 deletions

View File

@ -1,9 +1,5 @@
import { expect } from "chai";
import {
DecoderV0,
EncoderV0,
MessageV0,
} from "js-waku/lib/waku_message/version_0";
import { DecoderV0, EncoderV0 } from "js-waku/lib/waku_message/version_0";
import { RLNDecoder, RLNEncoder } from "./codec.js";
@ -26,7 +22,10 @@ describe("js-rln: encoder", () => {
index,
memKeys
);
const rlnDecoder = new RLNDecoder(new DecoderV0(TestContentTopic));
const rlnDecoder = new RLNDecoder(
rlnInstance,
new DecoderV0(TestContentTopic)
);
const bytes = await rlnEncoder.encode({ payload });
const protoResult = await rlnDecoder.decodeProto(bytes!);
@ -34,13 +33,11 @@ describe("js-rln: encoder", () => {
const msg = (await rlnDecoder.decode(protoResult!))!;
// Validate proof
const verifResult = rlnInstance.verifyProof(msg.rateLimitProof!);
expect(verifResult).to.be.true;
expect(msg.verify()).to.be.true;
const msgV0 = msg as MessageV0;
expect(msgV0.contentTopic).to.eq(TestContentTopic);
expect(msgV0.version).to.eq(0);
expect(msgV0.payload).to.deep.eq(payload);
expect(msgV0.timestamp).to.not.be.undefined;
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;
});
});

View File

@ -7,6 +7,7 @@ import {
ProtoMessage,
} from "js-waku/lib/interfaces";
import { RlnMessage } from "./message.js";
import { MembershipKey, RLNInstance } from "./rln.js";
const log = debug("waku:message:rln-encoder");
@ -53,11 +54,11 @@ export class RLNEncoder implements Encoder {
}
}
export class RLNDecoder implements Decoder<Message> {
public contentTopic: string;
export class RLNDecoder<T extends Message> implements Decoder<RlnMessage<T>> {
constructor(private rlnInstance: RLNInstance, private decoder: Decoder<T>) {}
constructor(private decoder: Decoder<Message>) {
this.contentTopic = decoder.contentTopic;
get contentTopic(): string {
return this.decoder.contentTopic;
}
decodeProto(bytes: Uint8Array): Promise<ProtoMessage | undefined> {
@ -66,12 +67,10 @@ export class RLNDecoder implements Decoder<Message> {
return Promise.resolve(protoMessage);
}
async decode(proto: ProtoMessage): Promise<Message | undefined> {
const msg = await this.decoder.decode(proto);
if (msg) {
msg.rateLimitProof = proto.rateLimitProof;
}
return msg;
async decode(proto: ProtoMessage): Promise<RlnMessage<T> | undefined> {
const msg: T | undefined = await this.decoder.decode(proto);
if (!msg) return;
return new RlnMessage(this.rlnInstance, msg, proto.rateLimitProof);
}
}

37
src/message.ts Normal file
View File

@ -0,0 +1,37 @@
import { Message, RateLimitProof } from "js-waku/lib/interfaces";
import { epochBytesToInt } from "./epoch.js";
import { RLNInstance } from "./rln.js";
export class RlnMessage<T extends Message> implements Message {
constructor(
public rlnInstance: RLNInstance,
public msg: T,
public rateLimitProof?: RateLimitProof
) {}
public verify(): boolean | undefined {
return this.rateLimitProof
? this.rlnInstance.verifyProof(this.rateLimitProof)
: undefined;
}
get payload(): Uint8Array | undefined {
return this.msg.payload;
}
get contentTopic(): string | undefined {
return this.msg.contentTopic;
}
get timestamp(): Date | undefined {
return this.msg.timestamp;
}
get epoch(): number | undefined {
const bytes = this.msg.rateLimitProof?.epoch;
if (!bytes) return;
return epochBytesToInt(bytes);
}
}