@waku/rln 0.1.5-1d384f2.0 → 0.1.5-35b50c3.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.
- package/bundle/index.js +2 -1
- package/bundle/packages/rln/dist/contract/constants.js +1 -0
- package/bundle/packages/rln/dist/contract/rln_base_contract.js +69 -64
- package/dist/.tsbuildinfo +1 -1
- package/dist/contract/index.d.ts +1 -0
- package/dist/contract/index.js +1 -0
- package/dist/contract/index.js.map +1 -1
- package/dist/contract/rln_base_contract.d.ts +5 -11
- package/dist/contract/rln_base_contract.js +69 -64
- package/dist/contract/rln_base_contract.js.map +1 -1
- package/dist/contract/types.d.ts +5 -0
- package/dist/contract/types.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/keystore/keystore.js.map +1 -1
- package/dist/keystore/types.d.ts +2 -2
- package/package.json +1 -1
- package/src/contract/index.ts +1 -0
- package/src/contract/rln_base_contract.ts +97 -93
- package/src/contract/types.ts +5 -0
- package/src/index.ts +3 -1
- package/src/keystore/keystore.ts +4 -2
- package/src/keystore/types.ts +2 -2
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';
|
@@ -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
|
-
|
45
|
-
this.validateRateLimit(rateLimit)
|
46
|
-
|
47
|
-
|
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,86 +260,73 @@ 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) {
|
256
|
-
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) {
|
263
|
+
async getMembershipInfo(idCommitmentBigInt) {
|
274
264
|
try {
|
275
|
-
const
|
265
|
+
const membershipData = await this.contract.memberships(idCommitmentBigInt);
|
276
266
|
const currentBlock = await this.contract.provider.getBlockNumber();
|
267
|
+
console.log("membershipData", membershipData);
|
268
|
+
const [depositAmount, activeDuration, gracePeriodStartTimestamp, gracePeriodDuration, rateLimit, index, holder, token] = membershipData;
|
269
|
+
const gracePeriodEnd = gracePeriodStartTimestamp.add(gracePeriodDuration);
|
277
270
|
let state;
|
278
|
-
if (currentBlock <
|
271
|
+
if (currentBlock < gracePeriodStartTimestamp.toNumber()) {
|
279
272
|
state = MembershipState.Active;
|
280
273
|
}
|
281
|
-
else if (currentBlock <
|
274
|
+
else if (currentBlock < gracePeriodEnd.toNumber()) {
|
282
275
|
state = MembershipState.GracePeriod;
|
283
276
|
}
|
284
277
|
else {
|
285
278
|
state = MembershipState.Expired;
|
286
279
|
}
|
287
|
-
const index = await this.getMemberIndex(idCommitment);
|
288
|
-
if (!index)
|
289
|
-
return undefined;
|
290
280
|
return {
|
291
281
|
index,
|
292
|
-
idCommitment,
|
293
|
-
rateLimit: rateLimit
|
294
|
-
startBlock:
|
295
|
-
endBlock:
|
296
|
-
state
|
282
|
+
idCommitment: idCommitmentBigInt.toString(),
|
283
|
+
rateLimit: Number(rateLimit),
|
284
|
+
startBlock: gracePeriodStartTimestamp.toNumber(),
|
285
|
+
endBlock: gracePeriodEnd.toNumber(),
|
286
|
+
state,
|
287
|
+
depositAmount,
|
288
|
+
activeDuration,
|
289
|
+
gracePeriodDuration,
|
290
|
+
holder,
|
291
|
+
token
|
297
292
|
};
|
298
293
|
}
|
299
294
|
catch (error) {
|
295
|
+
console.error("Error in getMembershipInfo:", error);
|
300
296
|
return undefined;
|
301
297
|
}
|
302
298
|
}
|
303
|
-
async extendMembership(
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
return this.contract.eraseMemberships([idCommitment], eraseFromMembershipSet);
|
299
|
+
async extendMembership(idCommitmentBigInt) {
|
300
|
+
const tx = await this.contract.extendMemberships([idCommitmentBigInt]);
|
301
|
+
await tx.wait();
|
302
|
+
return tx;
|
308
303
|
}
|
309
|
-
async
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
}
|
314
|
-
return this.contract.register(idCommitment, rateLimit, []);
|
304
|
+
async eraseMembership(idCommitmentBigInt, eraseFromMembershipSet = true) {
|
305
|
+
const tx = await this.contract.eraseMemberships([idCommitmentBigInt], eraseFromMembershipSet);
|
306
|
+
await tx.wait();
|
307
|
+
return tx;
|
315
308
|
}
|
316
|
-
async withdraw(token,
|
309
|
+
async withdraw(token, from) {
|
317
310
|
try {
|
318
|
-
const tx = await this.contract.withdraw(token,
|
311
|
+
const tx = await this.contract.withdraw(token, from);
|
319
312
|
await tx.wait();
|
320
313
|
}
|
321
314
|
catch (error) {
|
322
315
|
log.error(`Error in withdraw: ${error.message}`);
|
323
316
|
}
|
324
317
|
}
|
318
|
+
async registerMembership(idCommitmentBigInt, rateLimit = DEFAULT_RATE_LIMIT) {
|
319
|
+
if (rateLimit < RATE_LIMIT_PARAMS.MIN_RATE ||
|
320
|
+
rateLimit > RATE_LIMIT_PARAMS.MAX_RATE) {
|
321
|
+
throw new Error(`Rate limit must be between ${RATE_LIMIT_PARAMS.MIN_RATE} and ${RATE_LIMIT_PARAMS.MAX_RATE}`);
|
322
|
+
}
|
323
|
+
return this.contract.register(idCommitmentBigInt, rateLimit, []);
|
324
|
+
}
|
325
325
|
async registerWithIdentity(identity) {
|
326
326
|
try {
|
327
327
|
log.info(`Registering identity with rate limit: ${this.rateLimit} messages/epoch`);
|
328
328
|
// Check if the ID commitment is already registered
|
329
|
-
const existingIndex = await this.getMemberIndex(identity.IDCommitmentBigInt
|
329
|
+
const existingIndex = await this.getMemberIndex(identity.IDCommitmentBigInt);
|
330
330
|
if (existingIndex) {
|
331
331
|
throw new Error(`ID commitment is already registered with index ${existingIndex}`);
|
332
332
|
}
|
@@ -435,10 +435,15 @@ class RLNBaseContract {
|
|
435
435
|
* Validates that the rate limit is within the allowed range
|
436
436
|
* @throws Error if the rate limit is outside the allowed range
|
437
437
|
*/
|
438
|
-
validateRateLimit(rateLimit) {
|
439
|
-
|
440
|
-
|
441
|
-
|
438
|
+
async validateRateLimit(rateLimit) {
|
439
|
+
const [minRate, maxRate] = await Promise.all([
|
440
|
+
this.contract.minMembershipRateLimit(),
|
441
|
+
this.contract.maxMembershipRateLimit()
|
442
|
+
]);
|
443
|
+
const minRateNum = BigNumber.from(minRate).toNumber();
|
444
|
+
const maxRateNum = BigNumber.from(maxRate).toNumber();
|
445
|
+
if (rateLimit < minRateNum || rateLimit > maxRateNum) {
|
446
|
+
throw new Error(`Rate limit must be between ${minRateNum} and ${maxRateNum} messages per epoch`);
|
442
447
|
}
|
443
448
|
}
|
444
449
|
get membersFilter() {
|
@@ -459,9 +464,9 @@ class RLNBaseContract {
|
|
459
464
|
}
|
460
465
|
return this._membersExpiredFilter;
|
461
466
|
}
|
462
|
-
async getMemberIndex(
|
467
|
+
async getMemberIndex(idCommitmentBigInt) {
|
463
468
|
try {
|
464
|
-
const events = await this.contract.queryFilter(this.contract.filters.MembershipRegistered(
|
469
|
+
const events = await this.contract.queryFilter(this.contract.filters.MembershipRegistered(idCommitmentBigInt));
|
465
470
|
if (events.length === 0)
|
466
471
|
return undefined;
|
467
472
|
// Get the most recent registration event
|