@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.
package/bundle/index.js CHANGED
@@ -1909,9 +1909,9 @@ class RlnMessage {
1909
1909
  this.rateLimitProof = rateLimitProof;
1910
1910
  this.pubSubTopic = "";
1911
1911
  }
1912
- verify() {
1912
+ verify(roots) {
1913
1913
  return this.rateLimitProof
1914
- ? this.rlnInstance.verifyWithRoots(this.rateLimitProof, toRLNSignal(this.msg.contentTopic, this.msg)) // this.rlnInstance.verifyRLNProof once issue status-im/nwaku#1248 is fixed
1914
+ ? this.rlnInstance.verifyWithRoots(this.rateLimitProof, toRLNSignal(this.msg.contentTopic, this.msg), ...roots) // this.rlnInstance.verifyRLNProof once issue status-im/nwaku#1248 is fixed
1915
1915
  : undefined;
1916
1916
  }
1917
1917
  verifyNoRoot() {
@@ -1931,6 +1931,9 @@ class RlnMessage {
1931
1931
  get ephemeral() {
1932
1932
  return this.msg.ephemeral;
1933
1933
  }
1934
+ get meta() {
1935
+ return this.msg.meta;
1936
+ }
1934
1937
  get epoch() {
1935
1938
  const bytes = this.msg.rateLimitProof?.epoch;
1936
1939
  if (!bytes)
@@ -2005,10 +2008,10 @@ const RLN_ABI = [
2005
2008
  "event MemberRegistered(uint256 pubkey, uint256 index)",
2006
2009
  "event MemberWithdrawn(uint256 pubkey, uint256 index)",
2007
2010
  ];
2008
- const GOERLI_CONTRACT = {
2009
- chainId: 5,
2010
- startBlock: 7109391,
2011
- address: "0x4252105670fe33d2947e8ead304969849e64f2a6",
2011
+ const SEPOLIA_CONTRACT = {
2012
+ chainId: 11155111,
2013
+ startBlock: 3193048,
2014
+ address: "0x9C09146844C1326c2dBC41c451766C7138F88155",
2012
2015
  abi: RLN_ABI,
2013
2016
  };
2014
2017
 
@@ -27147,14 +27150,88 @@ try {
27147
27150
  }
27148
27151
  catch (error) { }
27149
27152
 
27153
+ class RootPerBlock {
27154
+ constructor(root, blockNumber) {
27155
+ this.root = root;
27156
+ this.blockNumber = blockNumber;
27157
+ }
27158
+ }
27159
+ const maxBufferSize = 20;
27160
+ class MerkleRootTracker {
27161
+ constructor(acceptableRootWindowSize, initialRoot) {
27162
+ this.acceptableRootWindowSize = acceptableRootWindowSize;
27163
+ this.validMerkleRoots = new Array();
27164
+ this.merkleRootBuffer = new Array();
27165
+ this.pushRoot(0, initialRoot);
27166
+ }
27167
+ backFill(fromBlockNumber) {
27168
+ if (this.validMerkleRoots.length == 0)
27169
+ return;
27170
+ let numBlocks = 0;
27171
+ for (let i = this.validMerkleRoots.length - 1; i >= 0; i--) {
27172
+ if (this.validMerkleRoots[i].blockNumber >= fromBlockNumber) {
27173
+ numBlocks++;
27174
+ }
27175
+ }
27176
+ if (numBlocks == 0)
27177
+ return;
27178
+ const olderBlock = fromBlockNumber < this.validMerkleRoots[0].blockNumber;
27179
+ // Remove last roots
27180
+ let rootsToPop = numBlocks;
27181
+ if (this.validMerkleRoots.length < rootsToPop) {
27182
+ rootsToPop = this.validMerkleRoots.length;
27183
+ }
27184
+ this.validMerkleRoots = this.validMerkleRoots.slice(0, this.validMerkleRoots.length - rootsToPop);
27185
+ if (this.merkleRootBuffer.length == 0)
27186
+ return;
27187
+ if (olderBlock) {
27188
+ const idx = this.merkleRootBuffer.findIndex((x) => x.blockNumber == fromBlockNumber);
27189
+ if (idx > -1) {
27190
+ this.merkleRootBuffer = this.merkleRootBuffer.slice(0, idx);
27191
+ }
27192
+ }
27193
+ // Backfill the tree's acceptable roots
27194
+ let rootsToRestore = this.acceptableRootWindowSize - this.validMerkleRoots.length;
27195
+ if (this.merkleRootBuffer.length < rootsToRestore) {
27196
+ rootsToRestore = this.merkleRootBuffer.length;
27197
+ }
27198
+ for (let i = 0; i < rootsToRestore; i++) {
27199
+ const x = this.merkleRootBuffer.pop();
27200
+ if (x)
27201
+ this.validMerkleRoots.unshift(x);
27202
+ }
27203
+ }
27204
+ pushRoot(blockNumber, root) {
27205
+ this.validMerkleRoots.push(new RootPerBlock(root, blockNumber));
27206
+ // Maintain valid merkle root window
27207
+ if (this.validMerkleRoots.length > this.acceptableRootWindowSize) {
27208
+ const x = this.validMerkleRoots.shift();
27209
+ if (x)
27210
+ this.merkleRootBuffer.push(x);
27211
+ }
27212
+ // Maintain merkle root buffer
27213
+ if (this.merkleRootBuffer.length > maxBufferSize) {
27214
+ this.merkleRootBuffer.shift();
27215
+ }
27216
+ }
27217
+ roots() {
27218
+ return this.validMerkleRoots.map((x) => x.root);
27219
+ }
27220
+ buffer() {
27221
+ return this.merkleRootBuffer.map((x) => x.root);
27222
+ }
27223
+ }
27224
+
27150
27225
  class RLNContract {
27151
- constructor({ address, provider }) {
27226
+ constructor(rlnInstance, { address, provider }) {
27152
27227
  this._members = [];
27228
+ const initialRoot = rlnInstance.getMerkleRoot();
27153
27229
  this._contract = new Contract(address, RLN_ABI, provider);
27230
+ this.merkleRootTracker = new MerkleRootTracker(5, initialRoot);
27154
27231
  this.membersFilter = this.contract.filters.MemberRegistered();
27155
27232
  }
27156
27233
  static async init(rlnInstance, options) {
27157
- const rlnContract = new RLNContract(options);
27234
+ const rlnContract = new RLNContract(rlnInstance, options);
27158
27235
  await rlnContract.fetchMembers(rlnInstance);
27159
27236
  rlnContract.subscribeToMembers(rlnInstance);
27160
27237
  return rlnContract;
@@ -27170,22 +27247,69 @@ class RLNContract {
27170
27247
  ...options,
27171
27248
  membersFilter: this.membersFilter,
27172
27249
  });
27173
- for (const event of registeredMemberEvents) {
27174
- this.addMemberFromEvent(rlnInstance, event);
27175
- }
27250
+ this.processEvents(rlnInstance, registeredMemberEvents);
27176
27251
  }
27177
- subscribeToMembers(rlnInstance) {
27178
- this.contract.on(this.membersFilter, (_pubkey, _index, event) => this.addMemberFromEvent(rlnInstance, event));
27252
+ processEvents(rlnInstance, events) {
27253
+ const toRemoveTable = new Map();
27254
+ const toInsertTable = new Map();
27255
+ events.forEach((evt) => {
27256
+ if (!evt.args) {
27257
+ return;
27258
+ }
27259
+ if (evt.removed) {
27260
+ const index = evt.args.index;
27261
+ const toRemoveVal = toRemoveTable.get(evt.blockNumber);
27262
+ if (toRemoveVal != undefined) {
27263
+ toRemoveVal.push(index);
27264
+ toRemoveTable.set(evt.blockNumber, toRemoveVal);
27265
+ }
27266
+ else {
27267
+ toRemoveTable.set(evt.blockNumber, [index]);
27268
+ }
27269
+ }
27270
+ else {
27271
+ let eventsPerBlock = toInsertTable.get(evt.blockNumber);
27272
+ if (eventsPerBlock == undefined) {
27273
+ eventsPerBlock = [];
27274
+ }
27275
+ eventsPerBlock.push(evt);
27276
+ toInsertTable.set(evt.blockNumber, eventsPerBlock);
27277
+ }
27278
+ this.removeMembers(rlnInstance, toRemoveTable);
27279
+ this.insertMembers(rlnInstance, toInsertTable);
27280
+ });
27179
27281
  }
27180
- addMemberFromEvent(rlnInstance, event) {
27181
- if (!event.args) {
27182
- return;
27183
- }
27184
- const pubkey = event.args.pubkey;
27185
- const index = event.args.index;
27186
- this.members.push({ index, pubkey });
27187
- const idCommitment = zeroPad(arrayify(pubkey), 32);
27188
- rlnInstance.insertMember(idCommitment);
27282
+ insertMembers(rlnInstance, toInsert) {
27283
+ toInsert.forEach((events, blockNumber) => {
27284
+ events.forEach((evt) => {
27285
+ if (!evt.args) {
27286
+ return;
27287
+ }
27288
+ const pubkey = evt.args.pubkey;
27289
+ const index = evt.args.index;
27290
+ const idCommitment = zeroPad(arrayify(pubkey), 32);
27291
+ rlnInstance.insertMember(idCommitment);
27292
+ this.members.push({ index, pubkey });
27293
+ });
27294
+ const currentRoot = rlnInstance.getMerkleRoot();
27295
+ this.merkleRootTracker.pushRoot(blockNumber, currentRoot);
27296
+ });
27297
+ }
27298
+ removeMembers(rlnInstance, toRemove) {
27299
+ const removeDescending = new Map([...toRemove].sort().reverse());
27300
+ removeDescending.forEach((indexes, blockNumber) => {
27301
+ indexes.forEach((index) => {
27302
+ const idx = this.members.findIndex((m) => m.index === index);
27303
+ if (idx > -1) {
27304
+ this.members.splice(idx, 1);
27305
+ }
27306
+ rlnInstance.deleteMember(index);
27307
+ });
27308
+ this.merkleRootTracker.backFill(blockNumber);
27309
+ });
27310
+ }
27311
+ subscribeToMembers(rlnInstance) {
27312
+ this.contract.on(this.membersFilter, (_pubkey, _index, event) => this.processEvents(rlnInstance, event));
27189
27313
  }
27190
27314
  async registerWithSignature(rlnInstance, signature) {
27191
27315
  const identityCredential = await rlnInstance.generateSeededIdentityCredential(signature);
@@ -27199,6 +27323,9 @@ class RLNContract {
27199
27323
  const txRegisterReceipt = await txRegisterResponse.wait();
27200
27324
  return txRegisterReceipt?.events?.[0];
27201
27325
  }
27326
+ roots() {
27327
+ return this.merkleRootTracker.roots();
27328
+ }
27202
27329
  }
27203
27330
  // these value should be tested on other networks
27204
27331
  const FETCH_CHUNK = 5;
@@ -27251,78 +27378,6 @@ function ignoreErrors(promise, defaultValue) {
27251
27378
  });
27252
27379
  }
27253
27380
 
27254
- class RootPerBlock {
27255
- constructor(root, blockNumber) {
27256
- this.root = root;
27257
- this.blockNumber = blockNumber;
27258
- }
27259
- }
27260
- const maxBufferSize = 20;
27261
- class MerkleRootTracker {
27262
- constructor(acceptableRootWindowSize, initialRoot) {
27263
- this.acceptableRootWindowSize = acceptableRootWindowSize;
27264
- this.validMerkleRoots = new Array();
27265
- this.merkleRootBuffer = new Array();
27266
- this.pushRoot(0, initialRoot);
27267
- }
27268
- backFill(fromBlockNumber) {
27269
- if (this.validMerkleRoots.length == 0)
27270
- return;
27271
- let numBlocks = 0;
27272
- for (let i = this.validMerkleRoots.length - 1; i >= 0; i--) {
27273
- if (this.validMerkleRoots[i].blockNumber >= fromBlockNumber) {
27274
- numBlocks++;
27275
- }
27276
- }
27277
- if (numBlocks == 0)
27278
- return;
27279
- const olderBlock = fromBlockNumber < this.validMerkleRoots[0].blockNumber;
27280
- // Remove last roots
27281
- let rootsToPop = numBlocks;
27282
- if (this.validMerkleRoots.length < rootsToPop) {
27283
- rootsToPop = this.validMerkleRoots.length;
27284
- }
27285
- this.validMerkleRoots = this.validMerkleRoots.slice(0, this.validMerkleRoots.length - rootsToPop);
27286
- if (this.merkleRootBuffer.length == 0)
27287
- return;
27288
- if (olderBlock) {
27289
- const idx = this.merkleRootBuffer.findIndex((x) => x.blockNumber == fromBlockNumber);
27290
- if (idx > -1) {
27291
- this.merkleRootBuffer = this.merkleRootBuffer.slice(0, idx);
27292
- }
27293
- }
27294
- // Backfill the tree's acceptable roots
27295
- let rootsToRestore = this.acceptableRootWindowSize - this.validMerkleRoots.length;
27296
- if (this.merkleRootBuffer.length < rootsToRestore) {
27297
- rootsToRestore = this.merkleRootBuffer.length;
27298
- }
27299
- for (let i = 0; i < rootsToRestore; i++) {
27300
- const x = this.merkleRootBuffer.pop();
27301
- if (x)
27302
- this.validMerkleRoots.unshift(x);
27303
- }
27304
- }
27305
- pushRoot(blockNumber, root) {
27306
- this.validMerkleRoots.push(new RootPerBlock(root, blockNumber));
27307
- // Maintain valid merkle root window
27308
- if (this.validMerkleRoots.length > this.acceptableRootWindowSize) {
27309
- const x = this.validMerkleRoots.shift();
27310
- if (x)
27311
- this.merkleRootBuffer.push(x);
27312
- }
27313
- // Maintain merkle root buffer
27314
- if (this.merkleRootBuffer.length > maxBufferSize) {
27315
- this.merkleRootBuffer.shift();
27316
- }
27317
- }
27318
- roots() {
27319
- return this.validMerkleRoots.map((x) => x.root);
27320
- }
27321
- buffer() {
27322
- return this.merkleRootBuffer.map((x) => x.root);
27323
- }
27324
- }
27325
-
27326
27381
  // reexport the create function, dynamically imported from rln.ts
27327
27382
  async function create() {
27328
27383
  // A dependency graph that contains any wasm must all be imported
@@ -27332,4 +27387,4 @@ async function create() {
27332
27387
  return await rlnModule.create();
27333
27388
  }
27334
27389
 
27335
- export { GOERLI_CONTRACT, IdentityCredential, MerkleRootTracker, Proof, ProofMetadata, RLNContract, RLNDecoder, RLNEncoder, RLNInstance, RLN_ABI, create };
27390
+ export { IdentityCredential, MerkleRootTracker, Proof, ProofMetadata, RLNContract, RLNDecoder, RLNEncoder, RLNInstance, RLN_ABI, SEPOLIA_CONTRACT, create };