@waku/rln 0.0.2-8a6571f.0 → 0.0.2-a6c9380.0

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.
@@ -10,6 +10,7 @@ import { RATE_LIMIT_PARAMS, DEFAULT_RATE_LIMIT } from './constants.js';
10
10
  import { Contract } from '../../../../node_modules/@ethersproject/contracts/lib.esm/index.js';
11
11
  import { BigNumber } from '../../../../node_modules/@ethersproject/bignumber/lib.esm/bignumber.js';
12
12
 
13
+ /* eslint-disable no-console */
13
14
  const log = new Logger("waku:rln:contract");
14
15
  var MembershipState;
15
16
  (function (MembershipState) {
@@ -26,6 +27,7 @@ class RLNContract {
26
27
  _members = new Map();
27
28
  _membersFilter;
28
29
  _membersRemovedFilter;
30
+ _membersExpiredFilter;
29
31
  /**
30
32
  * Asynchronous initializer for RLNContract.
31
33
  * Allows injecting a mocked contract for testing purposes.
@@ -47,9 +49,10 @@ class RLNContract {
47
49
  // Use the injected contract if provided; otherwise, instantiate a new one.
48
50
  this.contract = contract || new Contract(address, RLN_ABI, signer);
49
51
  this.merkleRootTracker = new MerkleRootTracker(5, initialRoot);
50
- // Initialize event filters for MembershipRegistered and MembershipErased
52
+ // Initialize event filters
51
53
  this._membersFilter = this.contract.filters.MembershipRegistered();
52
54
  this._membersRemovedFilter = this.contract.filters.MembershipErased();
55
+ this._membersExpiredFilter = this.contract.filters.MembershipExpired();
53
56
  }
54
57
  /**
55
58
  * Gets the current rate limit for this contract instance
@@ -135,6 +138,12 @@ class RLNContract {
135
138
  }
136
139
  return this._membersRemovedFilter;
137
140
  }
141
+ get membersExpiredFilter() {
142
+ if (!this._membersExpiredFilter) {
143
+ throw Error("MembersExpired filter was not initialized.");
144
+ }
145
+ return this._membersExpiredFilter;
146
+ }
138
147
  async fetchMembers(rlnInstance, options = {}) {
139
148
  const registeredMemberEvents = await queryFilter(this.contract, {
140
149
  fromBlock: this.deployBlock,
@@ -146,7 +155,16 @@ class RLNContract {
146
155
  ...options,
147
156
  membersFilter: this.membersRemovedFilter
148
157
  });
149
- const events = [...registeredMemberEvents, ...removedMemberEvents];
158
+ const expiredMemberEvents = await queryFilter(this.contract, {
159
+ fromBlock: this.deployBlock,
160
+ ...options,
161
+ membersFilter: this.membersExpiredFilter
162
+ });
163
+ const events = [
164
+ ...registeredMemberEvents,
165
+ ...removedMemberEvents,
166
+ ...expiredMemberEvents
167
+ ];
150
168
  this.processEvents(rlnInstance, events);
151
169
  }
152
170
  processEvents(rlnInstance, events) {
@@ -156,8 +174,17 @@ class RLNContract {
156
174
  if (!evt.args) {
157
175
  return;
158
176
  }
159
- if (evt.event === "MembershipErased") {
160
- const index = evt.args.index;
177
+ if (evt.event === "MembershipErased" ||
178
+ evt.event === "MembershipExpired") {
179
+ // Both MembershipErased and MembershipExpired events should remove members
180
+ let index = evt.args.index;
181
+ if (!index) {
182
+ return;
183
+ }
184
+ // Convert index to ethers.BigNumber if it's not already
185
+ if (typeof index === "number" || typeof index === "string") {
186
+ index = BigNumber.from(index);
187
+ }
161
188
  const toRemoveVal = toRemoveTable.get(evt.blockNumber);
162
189
  if (toRemoveVal != undefined) {
163
190
  toRemoveVal.push(index.toNumber());
@@ -185,14 +212,21 @@ class RLNContract {
185
212
  if (!evt.args)
186
213
  return;
187
214
  const _idCommitment = evt.args.idCommitment;
188
- const index = evt.args.index;
215
+ let index = evt.args.index;
216
+ // Ensure index is an ethers.BigNumber
189
217
  if (!_idCommitment || !index) {
190
218
  return;
191
219
  }
220
+ // Convert index to ethers.BigNumber if it's not already
221
+ if (typeof index === "number" || typeof index === "string") {
222
+ index = BigNumber.from(index);
223
+ }
192
224
  const idCommitment = zeroPadLE(hexToBytes(_idCommitment), 32);
193
225
  rlnInstance.zerokit.insertMember(idCommitment);
194
- this._members.set(index.toNumber(), {
195
- index,
226
+ // Always store the numeric index as the key, but the BigNumber as the value
227
+ const numericIndex = index.toNumber();
228
+ this._members.set(numericIndex, {
229
+ index, // This is always a BigNumber
196
230
  idCommitment: _idCommitment
197
231
  });
198
232
  });
@@ -213,33 +247,45 @@ class RLNContract {
213
247
  });
214
248
  }
215
249
  subscribeToMembers(rlnInstance) {
216
- this.contract.on(this.membersFilter, (_idCommitment, _rateLimit, _index, event) => {
250
+ this.contract.on(this.membersFilter, (_idCommitment, _membershipRateLimit, _index, event) => {
251
+ this.processEvents(rlnInstance, [event]);
252
+ });
253
+ this.contract.on(this.membersRemovedFilter, (_idCommitment, _membershipRateLimit, _index, event) => {
217
254
  this.processEvents(rlnInstance, [event]);
218
255
  });
219
- this.contract.on(this.membersRemovedFilter, (_idCommitment, _rateLimit, _index, event) => {
256
+ this.contract.on(this.membersExpiredFilter, (_idCommitment, _membershipRateLimit, _index, event) => {
220
257
  this.processEvents(rlnInstance, [event]);
221
258
  });
222
259
  }
223
260
  async registerWithIdentity(identity) {
224
261
  try {
262
+ console.log("registering membership", identity);
225
263
  log.info(`Registering identity with rate limit: ${this.rateLimit} messages/epoch`);
226
264
  const txRegisterResponse = await this.contract.register(identity.IDCommitmentBigInt, this.rateLimit, [], { gasLimit: 300000 });
265
+ console.log("txRegisterResponse", txRegisterResponse);
227
266
  const txRegisterReceipt = await txRegisterResponse.wait();
267
+ console.log("txRegisterReceipt", txRegisterReceipt);
228
268
  const memberRegistered = txRegisterReceipt.events?.find((event) => event.event === "MembershipRegistered");
269
+ console.log("memberRegistered", memberRegistered);
229
270
  if (!memberRegistered || !memberRegistered.args) {
271
+ console.log("no memberRegistered");
230
272
  log.error("Failed to register membership: No MembershipRegistered event found");
231
273
  return undefined;
232
274
  }
233
275
  const decodedData = {
234
276
  idCommitment: memberRegistered.args.idCommitment,
235
- rateLimit: memberRegistered.args.rateLimit,
277
+ membershipRateLimit: memberRegistered.args.membershipRateLimit,
236
278
  index: memberRegistered.args.index
237
279
  };
280
+ console.log("decodedData", decodedData);
238
281
  log.info(`Successfully registered membership with index ${decodedData.index} ` +
239
- `and rate limit ${decodedData.rateLimit}`);
282
+ `and rate limit ${decodedData.membershipRateLimit}`);
240
283
  const network = await this.contract.provider.getNetwork();
284
+ console.log("network", network);
241
285
  const address = this.contract.address;
286
+ console.log("address", address);
242
287
  const membershipId = decodedData.index.toNumber();
288
+ console.log("membershipId", membershipId);
243
289
  return {
244
290
  identity,
245
291
  membership: {
@@ -287,11 +333,11 @@ class RLNContract {
287
333
  }
288
334
  const decodedData = {
289
335
  idCommitment: memberRegistered.args.idCommitment,
290
- rateLimit: memberRegistered.args.rateLimit,
336
+ membershipRateLimit: memberRegistered.args.membershipRateLimit,
291
337
  index: memberRegistered.args.index
292
338
  };
293
339
  log.info(`Successfully registered membership with permit. Index: ${decodedData.index}, ` +
294
- `Rate limit: ${decodedData.rateLimit}, Erased ${idCommitmentsToErase.length} commitments`);
340
+ `Rate limit: ${decodedData.membershipRateLimit}, Erased ${idCommitmentsToErase.length} commitments`);
295
341
  const network = await this.contract.provider.getNetwork();
296
342
  const address = this.contract.address;
297
343
  const membershipId = decodedData.index.toNumber();
@@ -352,17 +398,22 @@ class RLNContract {
352
398
  }
353
399
  }
354
400
  async extendMembership(idCommitment) {
355
- return this.contract.extendMemberships([idCommitment]);
401
+ const tx = await this.contract.extendMemberships([idCommitment]);
402
+ return await tx.wait();
356
403
  }
357
404
  async eraseMembership(idCommitment, eraseFromMembershipSet = true) {
358
- return this.contract.eraseMemberships([idCommitment], eraseFromMembershipSet);
405
+ const tx = await this.contract.eraseMemberships([idCommitment], eraseFromMembershipSet);
406
+ return await tx.wait();
359
407
  }
360
408
  async registerMembership(idCommitment, rateLimit = DEFAULT_RATE_LIMIT) {
361
409
  if (rateLimit < RATE_LIMIT_PARAMS.MIN_RATE ||
362
410
  rateLimit > RATE_LIMIT_PARAMS.MAX_RATE) {
363
411
  throw new Error(`Rate limit must be between ${RATE_LIMIT_PARAMS.MIN_RATE} and ${RATE_LIMIT_PARAMS.MAX_RATE}`);
364
412
  }
365
- return this.contract.register(idCommitment, rateLimit, []);
413
+ console.log("registering membership", idCommitment, rateLimit);
414
+ const txn = this.contract.register(idCommitment, rateLimit, []);
415
+ console.log("txn", txn);
416
+ return txn;
366
417
  }
367
418
  async getMemberIndex(idCommitment) {
368
419
  try {
@@ -100,8 +100,6 @@ class RLNInstance {
100
100
  return this._signer;
101
101
  }
102
102
  async start(options = {}) {
103
- // eslint-disable-next-line no-console
104
- console.log("starting", options);
105
103
  if (this.started || this.starting) {
106
104
  return;
107
105
  }
@@ -133,12 +131,6 @@ class RLNInstance {
133
131
  if (address === SEPOLIA_CONTRACT.address) {
134
132
  chainId = SEPOLIA_CONTRACT.chainId;
135
133
  }
136
- // eslint-disable-next-line no-console
137
- console.log({
138
- chainId,
139
- address,
140
- SEPOLIA_CONTRACT
141
- });
142
134
  const signer = options.signer || (await extractMetaMaskSigner());
143
135
  const currentChainId = await signer.getChainId();
144
136
  if (chainId && chainId !== currentChainId) {
@@ -174,6 +166,8 @@ class RLNInstance {
174
166
  if ("signature" in options) {
175
167
  identity = this.zerokit.generateSeededIdentityCredential(options.signature);
176
168
  }
169
+ // eslint-disable-next-line no-console
170
+ console.log("registering membership", identity);
177
171
  if (!identity) {
178
172
  throw Error("Missing signature or identity to register membership.");
179
173
  }