@waku/rln 0.0.13-fae4bea → 0.0.14-360dc82

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/codec.ts CHANGED
@@ -1,55 +1,49 @@
1
+ import type {
2
+ IDecodedMessage,
3
+ IDecoder,
4
+ IEncoder,
5
+ IMessage,
6
+ IProtoMessage,
7
+ IRateLimitProof,
8
+ } from "@waku/interfaces";
1
9
  import debug from "debug";
2
- import {
3
- Decoder,
4
- Encoder,
5
- Message,
6
- ProtoMessage,
7
- RateLimitProof,
8
- } from "js-waku/lib/interfaces";
9
10
 
10
11
  import { RlnMessage, toRLNSignal } from "./message.js";
11
12
  import { MembershipKey, RLNInstance } from "./rln.js";
12
13
 
13
14
  const log = debug("waku:rln:encoder");
14
15
 
15
- export class RLNEncoder implements Encoder {
16
- public contentTopic: string;
16
+ export class RLNEncoder implements IEncoder {
17
17
  private readonly idKey: Uint8Array;
18
18
 
19
19
  constructor(
20
- private encoder: Encoder,
20
+ private encoder: IEncoder,
21
21
  private rlnInstance: RLNInstance,
22
22
  private index: number,
23
23
  membershipKey: MembershipKey
24
24
  ) {
25
25
  if (index < 0) throw "invalid membership index";
26
26
  this.idKey = membershipKey.IDKey;
27
- this.contentTopic = encoder.contentTopic;
28
27
  }
29
28
 
30
- async toWire(message: Partial<Message>): Promise<Uint8Array | undefined> {
31
- message.contentTopic = this.contentTopic;
29
+ async toWire(message: IMessage): Promise<Uint8Array | undefined> {
32
30
  message.rateLimitProof = await this.generateProof(message);
33
31
  log("Proof generated", message.rateLimitProof);
34
32
  return this.encoder.toWire(message);
35
33
  }
36
34
 
37
- async toProtoObj(
38
- message: Partial<Message>
39
- ): Promise<ProtoMessage | undefined> {
40
- message.contentTopic = this.contentTopic;
35
+ async toProtoObj(message: IMessage): Promise<IProtoMessage | undefined> {
41
36
  const protoMessage = await this.encoder.toProtoObj(message);
42
37
  if (!protoMessage) return;
43
38
 
39
+ protoMessage.contentTopic = this.contentTopic;
44
40
  protoMessage.rateLimitProof = await this.generateProof(message);
45
41
  log("Proof generated", protoMessage.rateLimitProof);
46
42
  return protoMessage;
47
43
  }
48
44
 
49
- private async generateProof(
50
- message: Partial<Message>
51
- ): Promise<RateLimitProof> {
52
- const signal = toRLNSignal(message);
45
+ private async generateProof(message: IMessage): Promise<IRateLimitProof> {
46
+ const signal = toRLNSignal(this.contentTopic, message);
53
47
 
54
48
  console.time("proof_gen_timer");
55
49
  const proof = await this.rlnInstance.generateRLNProof(
@@ -61,24 +55,67 @@ export class RLNEncoder implements Encoder {
61
55
  console.timeEnd("proof_gen_timer");
62
56
  return proof;
63
57
  }
58
+
59
+ get contentTopic(): string {
60
+ return this.encoder.contentTopic;
61
+ }
62
+
63
+ get ephemeral(): boolean {
64
+ return this.encoder.ephemeral;
65
+ }
64
66
  }
65
67
 
66
- export class RLNDecoder<T extends Message> implements Decoder<RlnMessage<T>> {
67
- constructor(private rlnInstance: RLNInstance, private decoder: Decoder<T>) {}
68
+ type RLNEncoderOptions = {
69
+ encoder: IEncoder;
70
+ rlnInstance: RLNInstance;
71
+ index: number;
72
+ membershipKey: MembershipKey;
73
+ };
74
+
75
+ export const createRLNEncoder = (options: RLNEncoderOptions): RLNEncoder => {
76
+ return new RLNEncoder(
77
+ options.encoder,
78
+ options.rlnInstance,
79
+ options.index,
80
+ options.membershipKey
81
+ );
82
+ };
83
+
84
+ export class RLNDecoder<T extends IDecodedMessage>
85
+ implements IDecoder<RlnMessage<T>>
86
+ {
87
+ constructor(private rlnInstance: RLNInstance, private decoder: IDecoder<T>) {}
68
88
 
69
89
  get contentTopic(): string {
70
90
  return this.decoder.contentTopic;
71
91
  }
72
92
 
73
- fromWireToProtoObj(bytes: Uint8Array): Promise<ProtoMessage | undefined> {
93
+ fromWireToProtoObj(bytes: Uint8Array): Promise<IProtoMessage | undefined> {
74
94
  const protoMessage = this.decoder.fromWireToProtoObj(bytes);
75
95
  log("Message decoded", protoMessage);
76
96
  return Promise.resolve(protoMessage);
77
97
  }
78
98
 
79
- async fromProtoObj(proto: ProtoMessage): Promise<RlnMessage<T> | undefined> {
80
- const msg: T | undefined = await this.decoder.fromProtoObj(proto);
99
+ async fromProtoObj(
100
+ pubSubTopic: string,
101
+ proto: IProtoMessage
102
+ ): Promise<RlnMessage<T> | undefined> {
103
+ const msg: T | undefined = await this.decoder.fromProtoObj(
104
+ pubSubTopic,
105
+ proto
106
+ );
81
107
  if (!msg) return;
82
108
  return new RlnMessage(this.rlnInstance, msg, proto.rateLimitProof);
83
109
  }
84
110
  }
111
+
112
+ type RLNDecoderOptions<T extends IDecodedMessage> = {
113
+ decoder: IDecoder<T>;
114
+ rlnInstance: RLNInstance;
115
+ };
116
+
117
+ export const createRLNDecoder = <T extends IDecodedMessage>(
118
+ options: RLNDecoderOptions<T>
119
+ ): RLNDecoder<T> => {
120
+ return new RLNDecoder(options.rlnInstance, options.decoder);
121
+ };
package/src/message.ts CHANGED
@@ -1,24 +1,33 @@
1
- import { utils } from "js-waku";
2
- import { Message, RateLimitProof } from "js-waku/lib/interfaces";
1
+ import type {
2
+ IDecodedMessage,
3
+ IMessage,
4
+ IRateLimitProof,
5
+ } from "@waku/interfaces";
6
+ import * as utils from "@waku/utils/bytes";
3
7
 
4
8
  import { epochBytesToInt } from "./epoch.js";
5
9
  import { RLNInstance } from "./rln.js";
6
10
 
7
- export function toRLNSignal(msg: Partial<Message>): Uint8Array {
8
- const contentTopicBytes = utils.utf8ToBytes(msg.contentTopic ?? "");
11
+ export function toRLNSignal(contentTopic: string, msg: IMessage): Uint8Array {
12
+ const contentTopicBytes = utils.utf8ToBytes(contentTopic ?? "");
9
13
  return new Uint8Array([...(msg.payload ?? []), ...contentTopicBytes]);
10
14
  }
11
15
 
12
- export class RlnMessage<T extends Message> implements Message {
16
+ export class RlnMessage<T extends IDecodedMessage> implements IDecodedMessage {
17
+ public pubSubTopic = "";
18
+
13
19
  constructor(
14
20
  public rlnInstance: RLNInstance,
15
21
  public msg: T,
16
- public rateLimitProof: RateLimitProof | undefined
22
+ public rateLimitProof: IRateLimitProof | undefined
17
23
  ) {}
18
24
 
19
25
  public verify(): boolean | undefined {
20
26
  return this.rateLimitProof
21
- ? this.rlnInstance.verifyWithRoots(this.rateLimitProof, toRLNSignal(this)) // this.rlnInstance.verifyRLNProof once issue status-im/nwaku#1248 is fixed
27
+ ? this.rlnInstance.verifyWithRoots(
28
+ this.rateLimitProof,
29
+ toRLNSignal(this.msg.contentTopic, this.msg)
30
+ ) // this.rlnInstance.verifyRLNProof once issue status-im/nwaku#1248 is fixed
22
31
  : undefined;
23
32
  }
24
33
 
@@ -26,16 +35,16 @@ export class RlnMessage<T extends Message> implements Message {
26
35
  return this.rateLimitProof
27
36
  ? this.rlnInstance.verifyWithNoRoot(
28
37
  this.rateLimitProof,
29
- toRLNSignal(this)
38
+ toRLNSignal(this.msg.contentTopic, this.msg)
30
39
  ) // this.rlnInstance.verifyRLNProof once issue status-im/nwaku#1248 is fixed
31
40
  : undefined;
32
41
  }
33
42
 
34
- get payload(): Uint8Array | undefined {
43
+ get payload(): Uint8Array {
35
44
  return this.msg.payload;
36
45
  }
37
46
 
38
- get contentTopic(): string | undefined {
47
+ get contentTopic(): string {
39
48
  return this.msg.contentTopic;
40
49
  }
41
50
 
@@ -43,6 +52,10 @@ export class RlnMessage<T extends Message> implements Message {
43
52
  return this.msg.timestamp;
44
53
  }
45
54
 
55
+ get ephemeral(): boolean | undefined {
56
+ return this.msg.ephemeral;
57
+ }
58
+
46
59
  get epoch(): number | undefined {
47
60
  const bytes = this.msg.rateLimitProof?.epoch;
48
61
  if (!bytes) return;
package/src/rln.ts CHANGED
@@ -1,5 +1,5 @@
1
+ import type { IRateLimitProof } from "@waku/interfaces";
1
2
  import init, * as zerokitRLN from "@waku/zerokit-rln-wasm";
2
- import { RateLimitProof } from "js-waku/lib/interfaces";
3
3
 
4
4
  import { writeUIntLE } from "./byte_utils.js";
5
5
  import { dateToEpoch, epochIntToBytes } from "./epoch.js";
@@ -89,7 +89,7 @@ const shareYOffset = shareXOffset + 32;
89
89
  const nullifierOffset = shareYOffset + 32;
90
90
  const rlnIdentifierOffset = nullifierOffset + 32;
91
91
 
92
- export class Proof implements RateLimitProof {
92
+ export class Proof implements IRateLimitProof {
93
93
  readonly proof: Uint8Array;
94
94
  readonly merkleRoot: Uint8Array;
95
95
  readonly epoch: Uint8Array;
@@ -114,7 +114,7 @@ export class Proof implements RateLimitProof {
114
114
  }
115
115
  }
116
116
 
117
- export function proofToBytes(p: RateLimitProof): Uint8Array {
117
+ export function proofToBytes(p: IRateLimitProof): Uint8Array {
118
118
  return concatenate(
119
119
  p.proof,
120
120
  p.merkleRoot,
@@ -175,7 +175,7 @@ export class RLNInstance {
175
175
  index: number,
176
176
  epoch: Uint8Array | Date | undefined,
177
177
  idKey: Uint8Array
178
- ): Promise<RateLimitProof> {
178
+ ): Promise<IRateLimitProof> {
179
179
  if (epoch == undefined) {
180
180
  epoch = epochIntToBytes(dateToEpoch(new Date()));
181
181
  } else if (epoch instanceof Date) {
@@ -206,7 +206,10 @@ export class RLNInstance {
206
206
  return new Proof(proofBytes);
207
207
  }
208
208
 
209
- verifyRLNProof(proof: RateLimitProof | Uint8Array, msg: Uint8Array): boolean {
209
+ verifyRLNProof(
210
+ proof: IRateLimitProof | Uint8Array,
211
+ msg: Uint8Array
212
+ ): boolean {
210
213
  let pBytes: Uint8Array;
211
214
  if (proof instanceof Uint8Array) {
212
215
  pBytes = proof;
@@ -224,7 +227,7 @@ export class RLNInstance {
224
227
  }
225
228
 
226
229
  verifyWithRoots(
227
- proof: RateLimitProof | Uint8Array,
230
+ proof: IRateLimitProof | Uint8Array,
228
231
  msg: Uint8Array
229
232
  ): boolean {
230
233
  let pBytes: Uint8Array;
@@ -248,7 +251,7 @@ export class RLNInstance {
248
251
  }
249
252
 
250
253
  verifyWithNoRoot(
251
- proof: RateLimitProof | Uint8Array,
254
+ proof: IRateLimitProof | Uint8Array,
252
255
  msg: Uint8Array
253
256
  ): boolean {
254
257
  let pBytes: Uint8Array;