@waku/rln 0.1.0 → 0.1.1-5d7f77f

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.
@@ -1,13 +1,16 @@
1
1
  import { ethers } from "ethers";
2
2
  import { RLN_ABI } from "./constants.js";
3
+ import { MerkleRootTracker } from "./root_tracker.js";
3
4
  export class RLNContract {
4
- constructor({ address, provider }) {
5
+ constructor(rlnInstance, { address, provider }) {
5
6
  this._members = [];
7
+ const initialRoot = rlnInstance.getMerkleRoot();
6
8
  this._contract = new ethers.Contract(address, RLN_ABI, provider);
9
+ this.merkleRootTracker = new MerkleRootTracker(5, initialRoot);
7
10
  this.membersFilter = this.contract.filters.MemberRegistered();
8
11
  }
9
12
  static async init(rlnInstance, options) {
10
- const rlnContract = new RLNContract(options);
13
+ const rlnContract = new RLNContract(rlnInstance, options);
11
14
  await rlnContract.fetchMembers(rlnInstance);
12
15
  rlnContract.subscribeToMembers(rlnInstance);
13
16
  return rlnContract;
@@ -23,22 +26,69 @@ export class RLNContract {
23
26
  ...options,
24
27
  membersFilter: this.membersFilter,
25
28
  });
26
- for (const event of registeredMemberEvents) {
27
- this.addMemberFromEvent(rlnInstance, event);
28
- }
29
+ this.processEvents(rlnInstance, registeredMemberEvents);
30
+ }
31
+ processEvents(rlnInstance, events) {
32
+ const toRemoveTable = new Map();
33
+ const toInsertTable = new Map();
34
+ events.forEach((evt) => {
35
+ if (!evt.args) {
36
+ return;
37
+ }
38
+ if (evt.removed) {
39
+ const index = evt.args.index;
40
+ const toRemoveVal = toRemoveTable.get(evt.blockNumber);
41
+ if (toRemoveVal != undefined) {
42
+ toRemoveVal.push(index);
43
+ toRemoveTable.set(evt.blockNumber, toRemoveVal);
44
+ }
45
+ else {
46
+ toRemoveTable.set(evt.blockNumber, [index]);
47
+ }
48
+ }
49
+ else {
50
+ let eventsPerBlock = toInsertTable.get(evt.blockNumber);
51
+ if (eventsPerBlock == undefined) {
52
+ eventsPerBlock = [];
53
+ }
54
+ eventsPerBlock.push(evt);
55
+ toInsertTable.set(evt.blockNumber, eventsPerBlock);
56
+ }
57
+ this.removeMembers(rlnInstance, toRemoveTable);
58
+ this.insertMembers(rlnInstance, toInsertTable);
59
+ });
60
+ }
61
+ insertMembers(rlnInstance, toInsert) {
62
+ toInsert.forEach((events, blockNumber) => {
63
+ events.forEach((evt) => {
64
+ if (!evt.args) {
65
+ return;
66
+ }
67
+ const pubkey = evt.args.pubkey;
68
+ const index = evt.args.index;
69
+ const idCommitment = ethers.utils.zeroPad(ethers.utils.arrayify(pubkey), 32);
70
+ rlnInstance.insertMember(idCommitment);
71
+ this.members.push({ index, pubkey });
72
+ });
73
+ const currentRoot = rlnInstance.getMerkleRoot();
74
+ this.merkleRootTracker.pushRoot(blockNumber, currentRoot);
75
+ });
76
+ }
77
+ removeMembers(rlnInstance, toRemove) {
78
+ const removeDescending = new Map([...toRemove].sort().reverse());
79
+ removeDescending.forEach((indexes, blockNumber) => {
80
+ indexes.forEach((index) => {
81
+ const idx = this.members.findIndex((m) => m.index === index);
82
+ if (idx > -1) {
83
+ this.members.splice(idx, 1);
84
+ }
85
+ rlnInstance.deleteMember(index);
86
+ });
87
+ this.merkleRootTracker.backFill(blockNumber);
88
+ });
29
89
  }
30
90
  subscribeToMembers(rlnInstance) {
31
- this.contract.on(this.membersFilter, (_pubkey, _index, event) => this.addMemberFromEvent(rlnInstance, event));
32
- }
33
- addMemberFromEvent(rlnInstance, event) {
34
- if (!event.args) {
35
- return;
36
- }
37
- const pubkey = event.args.pubkey;
38
- const index = event.args.index;
39
- this.members.push({ index, pubkey });
40
- const idCommitment = ethers.utils.zeroPad(ethers.utils.arrayify(pubkey), 32);
41
- rlnInstance.insertMember(idCommitment);
91
+ this.contract.on(this.membersFilter, (_pubkey, _index, event) => this.processEvents(rlnInstance, event));
42
92
  }
43
93
  async registerWithSignature(rlnInstance, signature) {
44
94
  const identityCredential = await rlnInstance.generateSeededIdentityCredential(signature);
@@ -52,6 +102,9 @@ export class RLNContract {
52
102
  const txRegisterReceipt = await txRegisterResponse.wait();
53
103
  return txRegisterReceipt?.events?.[0];
54
104
  }
105
+ roots() {
106
+ return this.merkleRootTracker.roots();
107
+ }
55
108
  }
56
109
  // these value should be tested on other networks
57
110
  const FETCH_CHUNK = 5;
@@ -1 +1 @@
1
- {"version":3,"file":"rln_contract.js","sourceRoot":"","sources":["../src/rln_contract.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rln_contract.js","sourceRoot":"","sources":["../src/rln_contract.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@waku/rln",
3
- "version": "0.1.0",
3
+ "version": "0.1.1-5d7f77f",
4
4
  "description": "Rate Limit Nullifier for js-waku",
5
5
  "types": "./dist/index.d.ts",
6
6
  "module": "./dist/index.js",
@@ -83,9 +83,9 @@
83
83
  "husky": "^7.0.4",
84
84
  "ignore-loader": "^0.1.2",
85
85
  "isomorphic-fetch": "^3.0.0",
86
- "@waku/interfaces": "^0.0.12",
87
- "@waku/message-encryption": "^0.0.15",
88
- "@waku/core": "^0.0.17",
86
+ "@waku/interfaces": "^0.0.13",
87
+ "@waku/message-encryption": "^0.0.16",
88
+ "@waku/core": "^0.0.18",
89
89
  "jsdom": "^19.0.0",
90
90
  "jsdom-global": "^3.0.2",
91
91
  "karma": "^6.3.12",
@@ -129,7 +129,7 @@
129
129
  ]
130
130
  },
131
131
  "dependencies": {
132
- "@waku/utils": "^0.0.5",
132
+ "@waku/utils": "^0.0.6",
133
133
  "@waku/zerokit-rln-wasm": "^0.0.10",
134
134
  "ethers": "^5.7.2"
135
135
  }
package/src/constants.ts CHANGED
@@ -6,9 +6,9 @@ export const RLN_ABI = [
6
6
  "event MemberWithdrawn(uint256 pubkey, uint256 index)",
7
7
  ];
8
8
 
9
- export const GOERLI_CONTRACT = {
10
- chainId: 5,
11
- startBlock: 7109391,
12
- address: "0x4252105670fe33d2947e8ead304969849e64f2a6",
9
+ export const SEPOLIA_CONTRACT = {
10
+ chainId: 11155111,
11
+ startBlock: 3193048,
12
+ address: "0x9C09146844C1326c2dBC41c451766C7138F88155",
13
13
  abi: RLN_ABI,
14
14
  };
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { RLNDecoder, RLNEncoder } from "./codec.js";
2
- import { GOERLI_CONTRACT, RLN_ABI } from "./constants.js";
2
+ import { RLN_ABI, SEPOLIA_CONTRACT } from "./constants.js";
3
3
  import {
4
4
  IdentityCredential,
5
5
  Proof,
@@ -28,5 +28,5 @@ export {
28
28
  MerkleRootTracker,
29
29
  RLNContract,
30
30
  RLN_ABI,
31
- GOERLI_CONTRACT,
31
+ SEPOLIA_CONTRACT,
32
32
  };
package/src/message.ts CHANGED
@@ -22,11 +22,12 @@ export class RlnMessage<T extends IDecodedMessage> implements IDecodedMessage {
22
22
  public rateLimitProof: IRateLimitProof | undefined
23
23
  ) {}
24
24
 
25
- public verify(): boolean | undefined {
25
+ public verify(roots: Uint8Array[]): boolean | undefined {
26
26
  return this.rateLimitProof
27
27
  ? this.rlnInstance.verifyWithRoots(
28
28
  this.rateLimitProof,
29
- toRLNSignal(this.msg.contentTopic, this.msg)
29
+ toRLNSignal(this.msg.contentTopic, this.msg),
30
+ ...roots
30
31
  ) // this.rlnInstance.verifyRLNProof once issue status-im/nwaku#1248 is fixed
31
32
  : undefined;
32
33
  }
@@ -56,6 +57,10 @@ export class RlnMessage<T extends IDecodedMessage> implements IDecodedMessage {
56
57
  return this.msg.ephemeral;
57
58
  }
58
59
 
60
+ get meta(): Uint8Array | undefined {
61
+ return this.msg.meta;
62
+ }
63
+
59
64
  get epoch(): number | undefined {
60
65
  const bytes = this.msg.rateLimitProof?.epoch;
61
66
  if (!bytes) return;
package/src/rln.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { IRateLimitProof } from "@waku/interfaces";
2
- import init, * as zerokitRLN from "@waku/zerokit-rln-wasm";
2
+ import { default as init } from "@waku/zerokit-rln-wasm";
3
+ import * as zerokitRLN from "@waku/zerokit-rln-wasm";
3
4
 
4
5
  import { writeUIntLE } from "./byte_utils.js";
5
6
  import { dateToEpoch, epochIntToBytes } from "./epoch.js";
@@ -2,6 +2,7 @@ import { ethers } from "ethers";
2
2
 
3
3
  import { RLN_ABI } from "./constants.js";
4
4
  import { IdentityCredential, RLNInstance } from "./rln.js";
5
+ import { MerkleRootTracker } from "./root_tracker.js";
5
6
 
6
7
  type Member = {
7
8
  pubkey: string;
@@ -22,6 +23,7 @@ type FetchMembersOptions = {
22
23
  export class RLNContract {
23
24
  private _contract: ethers.Contract;
24
25
  private membersFilter: ethers.EventFilter;
26
+ private merkleRootTracker: MerkleRootTracker;
25
27
 
26
28
  private _members: Member[] = [];
27
29
 
@@ -29,7 +31,7 @@ export class RLNContract {
29
31
  rlnInstance: RLNInstance,
30
32
  options: ContractOptions
31
33
  ): Promise<RLNContract> {
32
- const rlnContract = new RLNContract(options);
34
+ const rlnContract = new RLNContract(rlnInstance, options);
33
35
 
34
36
  await rlnContract.fetchMembers(rlnInstance);
35
37
  rlnContract.subscribeToMembers(rlnInstance);
@@ -37,8 +39,14 @@ export class RLNContract {
37
39
  return rlnContract;
38
40
  }
39
41
 
40
- constructor({ address, provider }: ContractOptions) {
42
+ constructor(
43
+ rlnInstance: RLNInstance,
44
+ { address, provider }: ContractOptions
45
+ ) {
46
+ const initialRoot = rlnInstance.getMerkleRoot();
47
+
41
48
  this._contract = new ethers.Contract(address, RLN_ABI, provider);
49
+ this.merkleRootTracker = new MerkleRootTracker(5, initialRoot);
42
50
  this.membersFilter = this.contract.filters.MemberRegistered();
43
51
  }
44
52
 
@@ -58,36 +66,89 @@ export class RLNContract {
58
66
  ...options,
59
67
  membersFilter: this.membersFilter,
60
68
  });
61
-
62
- for (const event of registeredMemberEvents) {
63
- this.addMemberFromEvent(rlnInstance, event);
64
- }
69
+ this.processEvents(rlnInstance, registeredMemberEvents);
65
70
  }
66
71
 
67
- public subscribeToMembers(rlnInstance: RLNInstance): void {
68
- this.contract.on(this.membersFilter, (_pubkey, _index, event) =>
69
- this.addMemberFromEvent(rlnInstance, event)
70
- );
72
+ public processEvents(rlnInstance: RLNInstance, events: ethers.Event[]): void {
73
+ const toRemoveTable = new Map<number, number[]>();
74
+ const toInsertTable = new Map<number, ethers.Event[]>();
75
+
76
+ events.forEach((evt) => {
77
+ if (!evt.args) {
78
+ return;
79
+ }
80
+
81
+ if (evt.removed) {
82
+ const index: number = evt.args.index;
83
+ const toRemoveVal = toRemoveTable.get(evt.blockNumber);
84
+ if (toRemoveVal != undefined) {
85
+ toRemoveVal.push(index);
86
+ toRemoveTable.set(evt.blockNumber, toRemoveVal);
87
+ } else {
88
+ toRemoveTable.set(evt.blockNumber, [index]);
89
+ }
90
+ } else {
91
+ let eventsPerBlock = toInsertTable.get(evt.blockNumber);
92
+ if (eventsPerBlock == undefined) {
93
+ eventsPerBlock = [];
94
+ }
95
+
96
+ eventsPerBlock.push(evt);
97
+ toInsertTable.set(evt.blockNumber, eventsPerBlock);
98
+ }
99
+
100
+ this.removeMembers(rlnInstance, toRemoveTable);
101
+ this.insertMembers(rlnInstance, toInsertTable);
102
+ });
71
103
  }
72
104
 
73
- private addMemberFromEvent(
105
+ private insertMembers(
74
106
  rlnInstance: RLNInstance,
75
- event: ethers.Event
107
+ toInsert: Map<number, ethers.Event[]>
76
108
  ): void {
77
- if (!event.args) {
78
- return;
79
- }
109
+ toInsert.forEach((events: ethers.Event[], blockNumber: number) => {
110
+ events.forEach((evt) => {
111
+ if (!evt.args) {
112
+ return;
113
+ }
114
+
115
+ const pubkey = evt.args.pubkey;
116
+ const index = evt.args.index;
117
+ const idCommitment = ethers.utils.zeroPad(
118
+ ethers.utils.arrayify(pubkey),
119
+ 32
120
+ );
121
+ rlnInstance.insertMember(idCommitment);
122
+ this.members.push({ index, pubkey });
123
+ });
124
+
125
+ const currentRoot = rlnInstance.getMerkleRoot();
126
+ this.merkleRootTracker.pushRoot(blockNumber, currentRoot);
127
+ });
128
+ }
80
129
 
81
- const pubkey: string = event.args.pubkey;
82
- const index: number = event.args.index;
130
+ private removeMembers(
131
+ rlnInstance: RLNInstance,
132
+ toRemove: Map<number, number[]>
133
+ ): void {
134
+ const removeDescending = new Map([...toRemove].sort().reverse());
135
+ removeDescending.forEach((indexes: number[], blockNumber: number) => {
136
+ indexes.forEach((index) => {
137
+ const idx = this.members.findIndex((m) => m.index === index);
138
+ if (idx > -1) {
139
+ this.members.splice(idx, 1);
140
+ }
141
+ rlnInstance.deleteMember(index);
142
+ });
83
143
 
84
- this.members.push({ index, pubkey });
144
+ this.merkleRootTracker.backFill(blockNumber);
145
+ });
146
+ }
85
147
 
86
- const idCommitment = ethers.utils.zeroPad(
87
- ethers.utils.arrayify(pubkey),
88
- 32
148
+ public subscribeToMembers(rlnInstance: RLNInstance): void {
149
+ this.contract.on(this.membersFilter, (_pubkey, _index, event) =>
150
+ this.processEvents(rlnInstance, event)
89
151
  );
90
- rlnInstance.insertMember(idCommitment);
91
152
  }
92
153
 
93
154
  public async registerWithSignature(
@@ -113,6 +174,10 @@ export class RLNContract {
113
174
 
114
175
  return txRegisterReceipt?.events?.[0];
115
176
  }
177
+
178
+ public roots(): Uint8Array[] {
179
+ return this.merkleRootTracker.roots();
180
+ }
116
181
  }
117
182
 
118
183
  type CustomQueryOptions = FetchMembersOptions & {
Binary file