@waku/rln 0.1.5-6997987.0 → 0.1.5-731214b.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.
Files changed (38) hide show
  1. package/bundle/index.js +2 -1
  2. package/bundle/packages/rln/dist/contract/constants.js +1 -0
  3. package/bundle/packages/rln/dist/contract/rln_base_contract.js +61 -52
  4. package/bundle/packages/rln/dist/credentials_manager.js +12 -30
  5. package/bundle/packages/rln/dist/keystore/keystore.js +10 -6
  6. package/bundle/packages/rln/dist/zerokit.js +5 -5
  7. package/dist/.tsbuildinfo +1 -1
  8. package/dist/contract/index.d.ts +1 -0
  9. package/dist/contract/index.js +1 -0
  10. package/dist/contract/index.js.map +1 -1
  11. package/dist/contract/rln_base_contract.d.ts +2 -8
  12. package/dist/contract/rln_base_contract.js +61 -52
  13. package/dist/contract/rln_base_contract.js.map +1 -1
  14. package/dist/contract/types.d.ts +5 -0
  15. package/dist/contract/types.js.map +1 -1
  16. package/dist/credentials_manager.d.ts +3 -9
  17. package/dist/credentials_manager.js +12 -30
  18. package/dist/credentials_manager.js.map +1 -1
  19. package/dist/index.d.ts +2 -1
  20. package/dist/index.js +1 -0
  21. package/dist/index.js.map +1 -1
  22. package/dist/keystore/keystore.js +10 -6
  23. package/dist/keystore/keystore.js.map +1 -1
  24. package/dist/keystore/types.d.ts +3 -3
  25. package/dist/rln.js.map +1 -1
  26. package/dist/zerokit.d.ts +3 -3
  27. package/dist/zerokit.js +5 -5
  28. package/dist/zerokit.js.map +1 -1
  29. package/package.json +1 -1
  30. package/src/contract/index.ts +1 -0
  31. package/src/contract/rln_base_contract.ts +83 -74
  32. package/src/contract/types.ts +5 -0
  33. package/src/credentials_manager.ts +12 -36
  34. package/src/index.ts +3 -1
  35. package/src/keystore/keystore.ts +22 -12
  36. package/src/keystore/types.ts +3 -3
  37. package/src/rln.ts +1 -0
  38. package/src/zerokit.ts +3 -3
package/bundle/index.js CHANGED
@@ -1,7 +1,8 @@
1
1
  export { RLNDecoder, RLNEncoder } from './packages/rln/dist/codec.js';
2
2
  export { RLN_ABI } from './packages/rln/dist/contract/abi.js';
3
3
  export { RLNContract } from './packages/rln/dist/contract/rln_contract.js';
4
- export { LINEA_CONTRACT } from './packages/rln/dist/contract/constants.js';
4
+ export { DEFAULT_RATE_LIMIT, LINEA_CONTRACT, RATE_LIMIT_PARAMS, RATE_LIMIT_TIERS } from './packages/rln/dist/contract/constants.js';
5
+ export { MembershipState } from './packages/rln/dist/contract/types.js';
5
6
  export { RLNBaseContract } from './packages/rln/dist/contract/rln_base_contract.js';
6
7
  export { createRLN } from './packages/rln/dist/create.js';
7
8
  export { RLNCredentialsManager } from './packages/rln/dist/credentials_manager.js';
@@ -12,6 +12,7 @@ const LINEA_CONTRACT = {
12
12
  */
13
13
  const RATE_LIMIT_TIERS = {
14
14
  LOW: 20, // Suggested minimum rate - 20 messages per epoch
15
+ MEDIUM: 200,
15
16
  HIGH: 600 // Suggested maximum rate - 600 messages per epoch
16
17
  };
17
18
  // Global rate limit parameters
@@ -19,6 +19,7 @@ import { MembershipState } from './types.js';
19
19
  import { Contract } from '../../../../node_modules/@ethersproject/contracts/lib.esm/index.js';
20
20
  import { BigNumber } from '../../../../node_modules/@ethersproject/bignumber/lib.esm/bignumber.js';
21
21
 
22
+ /* eslint-disable no-console */
22
23
  const log = new Logger("waku:rln:contract:base");
23
24
  class RLNBaseContract {
24
25
  contract;
@@ -33,6 +34,22 @@ class RLNBaseContract {
33
34
  * Allows injecting a mocked contract for testing purposes.
34
35
  */
35
36
  constructor(options) {
37
+ const { address, signer, rateLimit = DEFAULT_RATE_LIMIT, contract } = options;
38
+ log.info("Initializing RLNBaseContract", { address, rateLimit });
39
+ this.contract = contract || new Contract(address, RLN_ABI, signer);
40
+ this.rateLimit = rateLimit;
41
+ try {
42
+ log.info("Setting up event filters");
43
+ // Initialize event filters
44
+ this._membersFilter = this.contract.filters.MembershipRegistered();
45
+ this._membershipErasedFilter = this.contract.filters.MembershipErased();
46
+ this._membersExpiredFilter = this.contract.filters.MembershipExpired();
47
+ log.info("Event filters initialized successfully");
48
+ }
49
+ catch (error) {
50
+ log.error("Failed to initialize event filters", { error });
51
+ throw new Error("Failed to initialize event filters: " + error.message);
52
+ }
36
53
  // Initialize members and subscriptions
37
54
  this.fetchMembers()
38
55
  .then(() => {
@@ -41,14 +58,10 @@ class RLNBaseContract {
41
58
  .catch((error) => {
42
59
  log.error("Failed to initialize members", { error });
43
60
  });
44
- const { address, signer, rateLimit = DEFAULT_RATE_LIMIT, contract } = options;
45
- this.validateRateLimit(rateLimit);
46
- this.contract = contract || new Contract(address, RLN_ABI, signer);
47
- this.rateLimit = rateLimit;
48
- // Initialize event filters
49
- this._membersFilter = this.contract.filters.MembershipRegistered();
50
- this._membershipErasedFilter = this.contract.filters.MembershipErased();
51
- this._membersExpiredFilter = this.contract.filters.MembershipExpired();
61
+ // Validate rate limit asynchronously
62
+ this.validateRateLimit(rateLimit).catch((error) => {
63
+ log.error("Failed to validate initial rate limit", { error });
64
+ });
52
65
  }
53
66
  /**
54
67
  * Gets the current rate limit for this contract instance
@@ -116,7 +129,7 @@ class RLNBaseContract {
116
129
  * @param newRateLimit The new rate limit to use
117
130
  */
118
131
  async setRateLimit(newRateLimit) {
119
- this.validateRateLimit(newRateLimit);
132
+ await this.validateRateLimit(newRateLimit);
120
133
  this.rateLimit = newRateLimit;
121
134
  }
122
135
  get members() {
@@ -247,56 +260,47 @@ class RLNBaseContract {
247
260
  this.processEvents([event]);
248
261
  });
249
262
  }
250
- /**
251
- * Helper method to get remaining messages in current epoch
252
- * @param membershipId The ID of the membership to check
253
- * @returns number of remaining messages allowed in current epoch
254
- */
255
- async getRemainingMessages(membershipId) {
263
+ async getMembershipInfo(idCommitmentBigInt) {
256
264
  try {
257
- const [startTime, , rateLimit] = await this.contract.getMembershipInfo(membershipId);
258
- // Calculate current epoch
259
- const currentTime = Math.floor(Date.now() / 1000);
260
- const epochsPassed = Math.floor((currentTime - startTime) / RATE_LIMIT_PARAMS.EPOCH_LENGTH);
261
- const currentEpochStart = startTime + epochsPassed * RATE_LIMIT_PARAMS.EPOCH_LENGTH;
262
- // Get message count in current epoch using contract's function
263
- const messageCount = await this.contract.getMessageCount(membershipId, currentEpochStart);
264
- return Math.max(0, BigNumber.from(rateLimit)
265
- .sub(BigNumber.from(messageCount))
266
- .toNumber());
267
- }
268
- catch (error) {
269
- log.error(`Error getting remaining messages: ${error.message}`);
270
- return 0; // Fail safe: assume no messages remaining on error
271
- }
272
- }
273
- async getMembershipInfo(idCommitment) {
274
- try {
275
- const [startBlock, endBlock, rateLimit] = await this.contract.getMembershipInfo(idCommitment);
265
+ console.log("idCommitmentBigInt", idCommitmentBigInt);
266
+ const membershipData = await this.contract.memberships(idCommitmentBigInt);
276
267
  const currentBlock = await this.contract.provider.getBlockNumber();
268
+ console.log("membershipData", membershipData);
269
+ const [depositAmount, activeDuration, gracePeriodStartTimestamp, gracePeriodDuration, rateLimit, index, holder, token] = membershipData;
270
+ const gracePeriodEnd = gracePeriodStartTimestamp.add(gracePeriodDuration);
271
+ console.log("gracePeriodEnd", gracePeriodEnd);
277
272
  let state;
278
- if (currentBlock < startBlock) {
273
+ if (currentBlock < gracePeriodStartTimestamp.toNumber()) {
279
274
  state = MembershipState.Active;
280
275
  }
281
- else if (currentBlock < endBlock) {
276
+ else if (currentBlock < gracePeriodEnd.toNumber()) {
282
277
  state = MembershipState.GracePeriod;
283
278
  }
284
279
  else {
285
280
  state = MembershipState.Expired;
286
281
  }
287
- const index = await this.getMemberIndex(idCommitment);
288
- if (!index)
289
- return undefined;
282
+ console.log("state", state);
283
+ console.log("index", index);
284
+ console.log("idCommitment", idCommitmentBigInt.toString());
285
+ console.log("rateLimit", rateLimit);
286
+ console.log("gracePeriodStartTimestamp", gracePeriodStartTimestamp);
287
+ console.log("gracePeriodEnd", gracePeriodEnd);
290
288
  return {
291
289
  index,
292
- idCommitment,
293
- rateLimit: rateLimit.toNumber(),
294
- startBlock: startBlock.toNumber(),
295
- endBlock: endBlock.toNumber(),
296
- state
290
+ idCommitment: idCommitmentBigInt.toString(),
291
+ rateLimit: Number(rateLimit),
292
+ startBlock: gracePeriodStartTimestamp.toNumber(),
293
+ endBlock: gracePeriodEnd.toNumber(),
294
+ state,
295
+ depositAmount,
296
+ activeDuration,
297
+ gracePeriodDuration,
298
+ holder,
299
+ token
297
300
  };
298
301
  }
299
302
  catch (error) {
303
+ console.error("Error in getMembershipInfo:", error);
300
304
  return undefined;
301
305
  }
302
306
  }
@@ -313,9 +317,9 @@ class RLNBaseContract {
313
317
  }
314
318
  return this.contract.register(idCommitment, rateLimit, []);
315
319
  }
316
- async withdraw(token, holder) {
320
+ async withdraw(token, from) {
317
321
  try {
318
- const tx = await this.contract.withdraw(token, { from: holder });
322
+ const tx = await this.contract.withdraw(token, from);
319
323
  await tx.wait();
320
324
  }
321
325
  catch (error) {
@@ -362,7 +366,7 @@ class RLNBaseContract {
362
366
  membership: {
363
367
  address,
364
368
  treeIndex: membershipId,
365
- chainId: network.chainId,
369
+ chainId: network.chainId.toString(),
366
370
  rateLimit: decodedData.membershipRateLimit.toNumber()
367
371
  }
368
372
  };
@@ -421,7 +425,7 @@ class RLNBaseContract {
421
425
  membership: {
422
426
  address,
423
427
  treeIndex: membershipId,
424
- chainId: network.chainId,
428
+ chainId: network.chainId.toString(),
425
429
  rateLimit: decodedData.membershipRateLimit.toNumber()
426
430
  }
427
431
  };
@@ -435,10 +439,15 @@ class RLNBaseContract {
435
439
  * Validates that the rate limit is within the allowed range
436
440
  * @throws Error if the rate limit is outside the allowed range
437
441
  */
438
- validateRateLimit(rateLimit) {
439
- if (rateLimit < RATE_LIMIT_PARAMS.MIN_RATE ||
440
- rateLimit > RATE_LIMIT_PARAMS.MAX_RATE) {
441
- throw new Error(`Rate limit must be between ${RATE_LIMIT_PARAMS.MIN_RATE} and ${RATE_LIMIT_PARAMS.MAX_RATE} messages per epoch`);
442
+ async validateRateLimit(rateLimit) {
443
+ const [minRate, maxRate] = await Promise.all([
444
+ this.contract.minMembershipRateLimit(),
445
+ this.contract.maxMembershipRateLimit()
446
+ ]);
447
+ const minRateNum = BigNumber.from(minRate).toNumber();
448
+ const maxRateNum = BigNumber.from(maxRate).toNumber();
449
+ if (rateLimit < minRateNum || rateLimit > maxRateNum) {
450
+ throw new Error(`Rate limit must be between ${minRateNum} and ${maxRateNum} messages per epoch`);
442
451
  }
443
452
  }
444
453
  get membersFilter() {
@@ -32,33 +32,15 @@ const log = new Logger("waku:credentials");
32
32
  class RLNCredentialsManager {
33
33
  started = false;
34
34
  starting = false;
35
- _contract;
36
- _signer;
35
+ contract;
36
+ signer;
37
37
  keystore = Keystore.create();
38
- _credentials;
38
+ credentials;
39
39
  zerokit;
40
40
  constructor(zerokit) {
41
41
  log.info("RLNCredentialsManager initialized");
42
42
  this.zerokit = zerokit;
43
43
  }
44
- get contract() {
45
- return this._contract;
46
- }
47
- set contract(contract) {
48
- this._contract = contract;
49
- }
50
- get signer() {
51
- return this._signer;
52
- }
53
- set signer(signer) {
54
- this._signer = signer;
55
- }
56
- get credentials() {
57
- return this._credentials;
58
- }
59
- set credentials(credentials) {
60
- this._credentials = credentials;
61
- }
62
44
  get provider() {
63
45
  return this.contract?.provider;
64
46
  }
@@ -80,12 +62,12 @@ class RLNCredentialsManager {
80
62
  this.keystore = keystore;
81
63
  log.info("Using provided keystore");
82
64
  }
83
- this._credentials = credentials;
84
- this._signer = signer;
85
- this._contract = new RLNBaseContract({
65
+ this.credentials = credentials;
66
+ this.signer = signer;
67
+ this.contract = new RLNBaseContract({
86
68
  address: address,
87
69
  signer: signer,
88
- rateLimit: rateLimit ?? this.zerokit?.getRateLimit
70
+ rateLimit: rateLimit ?? this.zerokit?.rateLimit
89
71
  });
90
72
  log.info("RLNCredentialsManager successfully started");
91
73
  this.started = true;
@@ -130,8 +112,8 @@ class RLNCredentialsManager {
130
112
  */
131
113
  async useCredentials(id, password) {
132
114
  log.info(`Attempting to use credentials with ID: ${id}`);
133
- this._credentials = await this.keystore?.readCredential(id, password);
134
- if (this._credentials) {
115
+ this.credentials = await this.keystore?.readCredential(id, password);
116
+ if (this.credentials) {
135
117
  log.info("Successfully loaded credentials");
136
118
  }
137
119
  else {
@@ -144,13 +126,13 @@ class RLNCredentialsManager {
144
126
  options.address ||
145
127
  LINEA_CONTRACT.address;
146
128
  if (address === LINEA_CONTRACT.address) {
147
- chainId = LINEA_CONTRACT.chainId;
129
+ chainId = LINEA_CONTRACT.chainId.toString();
148
130
  log.info(`Using Linea contract with chainId: ${chainId}`);
149
131
  }
150
132
  const signer = options.signer || (await extractMetaMaskSigner());
151
133
  const currentChainId = await signer.getChainId();
152
134
  log.info(`Current chain ID: ${currentChainId}`);
153
- if (chainId && chainId !== currentChainId) {
135
+ if (chainId && chainId !== currentChainId.toString()) {
154
136
  log.error(`Chain ID mismatch: contract=${chainId}, current=${currentChainId}`);
155
137
  throw Error(`Failed to start RLN contract, chain ID of contract is different from current one: contract-${chainId}, current network-${currentChainId}`);
156
138
  }
@@ -199,7 +181,7 @@ class RLNCredentialsManager {
199
181
  const chainId = credentials.membership.chainId;
200
182
  const network = await this.contract.provider.getNetwork();
201
183
  const currentChainId = network.chainId;
202
- if (chainId !== currentChainId) {
184
+ if (chainId !== currentChainId.toString()) {
203
185
  throw Error(`Failed to verify chain coordinates: credentials chainID=${chainId} is not equal to registryContract chainID=${currentChainId}`);
204
186
  }
205
187
  }
@@ -177,7 +177,7 @@ class Keystore {
177
177
  treeIndex: _.get(obj, "treeIndex"),
178
178
  chainId: _.get(obj, "membershipContract.chainId"),
179
179
  address: _.get(obj, "membershipContract.address"),
180
- rateLimit: _.get(obj, "membershipContract.rateLimit")
180
+ rateLimit: _.get(obj, "userMessageLimit")
181
181
  }
182
182
  };
183
183
  }
@@ -187,6 +187,9 @@ class Keystore {
187
187
  }
188
188
  }
189
189
  static fromArraylikeToBytes(obj) {
190
+ if (Array.isArray(obj)) {
191
+ return new Uint8Array(obj);
192
+ }
190
193
  const bytes = [];
191
194
  let index = 0;
192
195
  let lastElement = obj[index];
@@ -208,15 +211,16 @@ class Keystore {
208
211
  return utf8ToBytes(JSON.stringify({
209
212
  treeIndex: options.membership.treeIndex,
210
213
  identityCredential: {
211
- idCommitment: options.identity.IDCommitment,
212
- idNullifier: options.identity.IDNullifier,
213
- idSecretHash: options.identity.IDSecretHash,
214
- idTrapdoor: options.identity.IDTrapdoor
214
+ idCommitment: Array.from(options.identity.IDCommitment),
215
+ idNullifier: Array.from(options.identity.IDNullifier),
216
+ idSecretHash: Array.from(options.identity.IDSecretHash),
217
+ idTrapdoor: Array.from(options.identity.IDTrapdoor)
215
218
  },
216
219
  membershipContract: {
217
220
  chainId: options.membership.chainId,
218
221
  address: options.membership.address
219
- }
222
+ },
223
+ userMessageLimit: options.membership.rateLimit
220
224
  }));
221
225
  }
222
226
  }
@@ -8,11 +8,11 @@ import { epochIntToBytes, dateToEpoch } from './utils/epoch.js';
8
8
  class Zerokit {
9
9
  zkRLN;
10
10
  witnessCalculator;
11
- rateLimit;
12
- constructor(zkRLN, witnessCalculator, rateLimit = DEFAULT_RATE_LIMIT) {
11
+ _rateLimit;
12
+ constructor(zkRLN, witnessCalculator, _rateLimit = DEFAULT_RATE_LIMIT) {
13
13
  this.zkRLN = zkRLN;
14
14
  this.witnessCalculator = witnessCalculator;
15
- this.rateLimit = rateLimit;
15
+ this._rateLimit = _rateLimit;
16
16
  }
17
17
  get getZkRLN() {
18
18
  return this.zkRLN;
@@ -20,8 +20,8 @@ class Zerokit {
20
20
  get getWitnessCalculator() {
21
21
  return this.witnessCalculator;
22
22
  }
23
- get getRateLimit() {
24
- return this.rateLimit;
23
+ get rateLimit() {
24
+ return this._rateLimit;
25
25
  }
26
26
  generateIdentityCredentials() {
27
27
  const memKeys = generateExtendedMembershipKey(this.zkRLN); // TODO: rename this function in zerokit rln-wasm