@waku/rln 0.1.5-fdaf129.0 → 0.1.5
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/CHANGELOG.md +22 -0
- package/bundle/_virtual/utils.js +2 -2
- package/bundle/_virtual/utils2.js +2 -2
- package/bundle/index.js +1 -2
- package/bundle/node_modules/@ethersproject/abi/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/abstract-provider/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/abstract-signer/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/address/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/bignumber/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/contracts/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/contracts/lib.esm/index.js +1 -1
- package/bundle/node_modules/@ethersproject/hash/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/networks/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/networks/lib.esm/index.js +19 -1
- package/bundle/node_modules/@ethersproject/properties/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/providers/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/signing-key/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/signing-key/lib.esm/elliptic.js +58 -10
- package/bundle/node_modules/@ethersproject/strings/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/transactions/lib.esm/_version.js +1 -1
- package/bundle/node_modules/@ethersproject/web/lib.esm/_version.js +1 -1
- package/bundle/packages/proto/dist/generated/sds_message.js +59 -3
- package/bundle/packages/rln/dist/contract/constants.js +0 -1
- package/bundle/packages/rln/dist/contract/rln_base_contract.js +59 -60
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/ethereum-cryptography/random.js +1 -1
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/ethereum-cryptography/utils.js +2 -2
- package/bundle/packages/rln/node_modules/@noble/hashes/_sha2.js +1 -1
- package/bundle/packages/rln/node_modules/@noble/hashes/hmac.js +1 -1
- package/bundle/packages/rln/node_modules/@noble/hashes/pbkdf2.js +1 -1
- package/bundle/packages/rln/node_modules/@noble/hashes/scrypt.js +1 -1
- package/bundle/packages/rln/node_modules/@noble/hashes/sha256.js +1 -1
- package/bundle/packages/rln/node_modules/@noble/hashes/sha512.js +1 -1
- package/bundle/packages/rln/node_modules/@noble/hashes/utils.js +1 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/contract/index.d.ts +0 -1
- package/dist/contract/index.js +0 -1
- package/dist/contract/index.js.map +1 -1
- package/dist/contract/rln_base_contract.d.ts +11 -5
- package/dist/contract/rln_base_contract.js +59 -60
- package/dist/contract/rln_base_contract.js.map +1 -1
- package/dist/contract/types.d.ts +0 -5
- package/dist/contract/types.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js +0 -1
- 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 +92 -1
- package/src/contract/index.ts +0 -1
- package/src/contract/rln_base_contract.ts +85 -85
- package/src/contract/types.ts +0 -5
- package/src/index.ts +1 -3
- package/src/keystore/keystore.ts +2 -4
- package/src/keystore/types.ts +2 -2
@@ -1,4 +1,3 @@
|
|
1
|
-
/* eslint-disable no-console */
|
2
1
|
import { Logger } from "@waku/utils";
|
3
2
|
import { ethers } from "ethers";
|
4
3
|
|
@@ -34,6 +33,15 @@ export class RLNBaseContract {
|
|
34
33
|
* Allows injecting a mocked contract for testing purposes.
|
35
34
|
*/
|
36
35
|
public constructor(options: RLNContractInitOptions) {
|
36
|
+
// Initialize members and subscriptions
|
37
|
+
this.fetchMembers()
|
38
|
+
.then(() => {
|
39
|
+
this.subscribeToMembers();
|
40
|
+
})
|
41
|
+
.catch((error) => {
|
42
|
+
log.error("Failed to initialize members", { error });
|
43
|
+
});
|
44
|
+
|
37
45
|
const {
|
38
46
|
address,
|
39
47
|
signer,
|
@@ -41,38 +49,15 @@ export class RLNBaseContract {
|
|
41
49
|
contract
|
42
50
|
} = options;
|
43
51
|
|
44
|
-
|
52
|
+
this.validateRateLimit(rateLimit);
|
45
53
|
|
46
54
|
this.contract = contract || new ethers.Contract(address, RLN_ABI, signer);
|
47
55
|
this.rateLimit = rateLimit;
|
48
56
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
this._membershipErasedFilter = this.contract.filters.MembershipErased();
|
54
|
-
this._membersExpiredFilter = this.contract.filters.MembershipExpired();
|
55
|
-
log.info("Event filters initialized successfully");
|
56
|
-
} catch (error) {
|
57
|
-
log.error("Failed to initialize event filters", { error });
|
58
|
-
throw new Error(
|
59
|
-
"Failed to initialize event filters: " + (error as Error).message
|
60
|
-
);
|
61
|
-
}
|
62
|
-
|
63
|
-
// Initialize members and subscriptions
|
64
|
-
this.fetchMembers()
|
65
|
-
.then(() => {
|
66
|
-
this.subscribeToMembers();
|
67
|
-
})
|
68
|
-
.catch((error) => {
|
69
|
-
log.error("Failed to initialize members", { error });
|
70
|
-
});
|
71
|
-
|
72
|
-
// Validate rate limit asynchronously
|
73
|
-
this.validateRateLimit(rateLimit).catch((error) => {
|
74
|
-
log.error("Failed to validate initial rate limit", { error });
|
75
|
-
});
|
57
|
+
// Initialize event filters
|
58
|
+
this._membersFilter = this.contract.filters.MembershipRegistered();
|
59
|
+
this._membershipErasedFilter = this.contract.filters.MembershipErased();
|
60
|
+
this._membersExpiredFilter = this.contract.filters.MembershipExpired();
|
76
61
|
}
|
77
62
|
|
78
63
|
/**
|
@@ -149,7 +134,7 @@ export class RLNBaseContract {
|
|
149
134
|
* @param newRateLimit The new rate limit to use
|
150
135
|
*/
|
151
136
|
public async setRateLimit(newRateLimit: number): Promise<void> {
|
152
|
-
|
137
|
+
this.validateRateLimit(newRateLimit);
|
153
138
|
this.rateLimit = newRateLimit;
|
154
139
|
}
|
155
140
|
|
@@ -339,7 +324,7 @@ export class RLNBaseContract {
|
|
339
324
|
this.contract.on(
|
340
325
|
this.membersFilter,
|
341
326
|
(
|
342
|
-
_idCommitment:
|
327
|
+
_idCommitment: string,
|
343
328
|
_membershipRateLimit: ethers.BigNumber,
|
344
329
|
_index: ethers.BigNumber,
|
345
330
|
event: ethers.Event
|
@@ -351,7 +336,7 @@ export class RLNBaseContract {
|
|
351
336
|
this.contract.on(
|
352
337
|
this.membershipErasedFilter,
|
353
338
|
(
|
354
|
-
_idCommitment:
|
339
|
+
_idCommitment: string,
|
355
340
|
_membershipRateLimit: ethers.BigNumber,
|
356
341
|
_index: ethers.BigNumber,
|
357
342
|
event: ethers.Event
|
@@ -363,7 +348,7 @@ export class RLNBaseContract {
|
|
363
348
|
this.contract.on(
|
364
349
|
this.membersExpiredFilter,
|
365
350
|
(
|
366
|
-
_idCommitment:
|
351
|
+
_idCommitment: string,
|
367
352
|
_membershipRateLimit: ethers.BigNumber,
|
368
353
|
_index: ethers.BigNumber,
|
369
354
|
event: ethers.Event
|
@@ -373,74 +358,94 @@ export class RLNBaseContract {
|
|
373
358
|
);
|
374
359
|
}
|
375
360
|
|
361
|
+
/**
|
362
|
+
* Helper method to get remaining messages in current epoch
|
363
|
+
* @param membershipId The ID of the membership to check
|
364
|
+
* @returns number of remaining messages allowed in current epoch
|
365
|
+
*/
|
366
|
+
public async getRemainingMessages(membershipId: number): Promise<number> {
|
367
|
+
try {
|
368
|
+
const [startTime, , rateLimit] =
|
369
|
+
await this.contract.getMembershipInfo(membershipId);
|
370
|
+
|
371
|
+
// Calculate current epoch
|
372
|
+
const currentTime = Math.floor(Date.now() / 1000);
|
373
|
+
const epochsPassed = Math.floor(
|
374
|
+
(currentTime - startTime) / RATE_LIMIT_PARAMS.EPOCH_LENGTH
|
375
|
+
);
|
376
|
+
const currentEpochStart =
|
377
|
+
startTime + epochsPassed * RATE_LIMIT_PARAMS.EPOCH_LENGTH;
|
378
|
+
|
379
|
+
// Get message count in current epoch using contract's function
|
380
|
+
const messageCount = await this.contract.getMessageCount(
|
381
|
+
membershipId,
|
382
|
+
currentEpochStart
|
383
|
+
);
|
384
|
+
return Math.max(
|
385
|
+
0,
|
386
|
+
ethers.BigNumber.from(rateLimit)
|
387
|
+
.sub(ethers.BigNumber.from(messageCount))
|
388
|
+
.toNumber()
|
389
|
+
);
|
390
|
+
} catch (error) {
|
391
|
+
log.error(
|
392
|
+
`Error getting remaining messages: ${(error as Error).message}`
|
393
|
+
);
|
394
|
+
return 0; // Fail safe: assume no messages remaining on error
|
395
|
+
}
|
396
|
+
}
|
397
|
+
|
376
398
|
public async getMembershipInfo(
|
377
|
-
|
399
|
+
idCommitment: string
|
378
400
|
): Promise<MembershipInfo | undefined> {
|
379
401
|
try {
|
380
|
-
const
|
381
|
-
await this.contract.
|
402
|
+
const [startBlock, endBlock, rateLimit] =
|
403
|
+
await this.contract.getMembershipInfo(idCommitment);
|
382
404
|
const currentBlock = await this.contract.provider.getBlockNumber();
|
383
|
-
console.log("membershipData", membershipData);
|
384
|
-
|
385
|
-
const [
|
386
|
-
depositAmount,
|
387
|
-
activeDuration,
|
388
|
-
gracePeriodStartTimestamp,
|
389
|
-
gracePeriodDuration,
|
390
|
-
rateLimit,
|
391
|
-
index,
|
392
|
-
holder,
|
393
|
-
token
|
394
|
-
] = membershipData;
|
395
|
-
|
396
|
-
const gracePeriodEnd = gracePeriodStartTimestamp.add(gracePeriodDuration);
|
397
405
|
|
398
406
|
let state: MembershipState;
|
399
|
-
if (currentBlock <
|
407
|
+
if (currentBlock < startBlock) {
|
400
408
|
state = MembershipState.Active;
|
401
|
-
} else if (currentBlock <
|
409
|
+
} else if (currentBlock < endBlock) {
|
402
410
|
state = MembershipState.GracePeriod;
|
403
411
|
} else {
|
404
412
|
state = MembershipState.Expired;
|
405
413
|
}
|
406
414
|
|
415
|
+
const index = await this.getMemberIndex(idCommitment);
|
416
|
+
if (!index) return undefined;
|
417
|
+
|
407
418
|
return {
|
408
419
|
index,
|
409
|
-
idCommitment
|
410
|
-
rateLimit:
|
411
|
-
startBlock:
|
412
|
-
endBlock:
|
413
|
-
state
|
414
|
-
depositAmount,
|
415
|
-
activeDuration,
|
416
|
-
gracePeriodDuration,
|
417
|
-
holder,
|
418
|
-
token
|
420
|
+
idCommitment,
|
421
|
+
rateLimit: rateLimit.toNumber(),
|
422
|
+
startBlock: startBlock.toNumber(),
|
423
|
+
endBlock: endBlock.toNumber(),
|
424
|
+
state
|
419
425
|
};
|
420
426
|
} catch (error) {
|
421
|
-
console.error("Error in getMembershipInfo:", error);
|
422
427
|
return undefined;
|
423
428
|
}
|
424
429
|
}
|
425
430
|
|
426
431
|
public async extendMembership(
|
427
|
-
|
432
|
+
idCommitment: string
|
428
433
|
): Promise<ethers.ContractTransaction> {
|
429
|
-
return this.contract.extendMemberships([
|
434
|
+
return this.contract.extendMemberships([idCommitment]);
|
430
435
|
}
|
431
436
|
|
432
437
|
public async eraseMembership(
|
433
|
-
|
438
|
+
idCommitment: string,
|
434
439
|
eraseFromMembershipSet: boolean = true
|
435
440
|
): Promise<ethers.ContractTransaction> {
|
436
441
|
return this.contract.eraseMemberships(
|
437
|
-
[
|
442
|
+
[idCommitment],
|
438
443
|
eraseFromMembershipSet
|
439
444
|
);
|
440
445
|
}
|
441
446
|
|
442
447
|
public async registerMembership(
|
443
|
-
|
448
|
+
idCommitment: string,
|
444
449
|
rateLimit: number = DEFAULT_RATE_LIMIT
|
445
450
|
): Promise<ethers.ContractTransaction> {
|
446
451
|
if (
|
@@ -451,12 +456,12 @@ export class RLNBaseContract {
|
|
451
456
|
`Rate limit must be between ${RATE_LIMIT_PARAMS.MIN_RATE} and ${RATE_LIMIT_PARAMS.MAX_RATE}`
|
452
457
|
);
|
453
458
|
}
|
454
|
-
return this.contract.register(
|
459
|
+
return this.contract.register(idCommitment, rateLimit, []);
|
455
460
|
}
|
456
461
|
|
457
|
-
public async withdraw(token: string,
|
462
|
+
public async withdraw(token: string, holder: string): Promise<void> {
|
458
463
|
try {
|
459
|
-
const tx = await this.contract.withdraw(token, from);
|
464
|
+
const tx = await this.contract.withdraw(token, { from: holder });
|
460
465
|
await tx.wait();
|
461
466
|
} catch (error) {
|
462
467
|
log.error(`Error in withdraw: ${(error as Error).message}`);
|
@@ -473,7 +478,7 @@ export class RLNBaseContract {
|
|
473
478
|
|
474
479
|
// Check if the ID commitment is already registered
|
475
480
|
const existingIndex = await this.getMemberIndex(
|
476
|
-
identity.IDCommitmentBigInt
|
481
|
+
identity.IDCommitmentBigInt.toString()
|
477
482
|
);
|
478
483
|
if (existingIndex) {
|
479
484
|
throw new Error(
|
@@ -651,18 +656,13 @@ export class RLNBaseContract {
|
|
651
656
|
* Validates that the rate limit is within the allowed range
|
652
657
|
* @throws Error if the rate limit is outside the allowed range
|
653
658
|
*/
|
654
|
-
private
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
const minRateNum = ethers.BigNumber.from(minRate).toNumber();
|
661
|
-
const maxRateNum = ethers.BigNumber.from(maxRate).toNumber();
|
662
|
-
|
663
|
-
if (rateLimit < minRateNum || rateLimit > maxRateNum) {
|
659
|
+
private validateRateLimit(rateLimit: number): void {
|
660
|
+
if (
|
661
|
+
rateLimit < RATE_LIMIT_PARAMS.MIN_RATE ||
|
662
|
+
rateLimit > RATE_LIMIT_PARAMS.MAX_RATE
|
663
|
+
) {
|
664
664
|
throw new Error(
|
665
|
-
`Rate limit must be between ${
|
665
|
+
`Rate limit must be between ${RATE_LIMIT_PARAMS.MIN_RATE} and ${RATE_LIMIT_PARAMS.MAX_RATE} messages per epoch`
|
666
666
|
);
|
667
667
|
}
|
668
668
|
}
|
@@ -689,11 +689,11 @@ export class RLNBaseContract {
|
|
689
689
|
}
|
690
690
|
|
691
691
|
private async getMemberIndex(
|
692
|
-
|
692
|
+
idCommitment: string
|
693
693
|
): Promise<ethers.BigNumber | undefined> {
|
694
694
|
try {
|
695
695
|
const events = await this.contract.queryFilter(
|
696
|
-
this.contract.filters.MembershipRegistered(
|
696
|
+
this.contract.filters.MembershipRegistered(idCommitment)
|
697
697
|
);
|
698
698
|
if (events.length === 0) return undefined;
|
699
699
|
|
package/src/contract/types.ts
CHANGED
@@ -38,11 +38,6 @@ export interface MembershipInfo {
|
|
38
38
|
startBlock: number;
|
39
39
|
endBlock: number;
|
40
40
|
state: MembershipState;
|
41
|
-
depositAmount: ethers.BigNumber;
|
42
|
-
activeDuration: number;
|
43
|
-
gracePeriodDuration: number;
|
44
|
-
holder: string;
|
45
|
-
token: string;
|
46
41
|
}
|
47
42
|
|
48
43
|
export enum MembershipState {
|
package/src/index.ts
CHANGED
package/src/keystore/keystore.ts
CHANGED
@@ -21,8 +21,8 @@ import { isCredentialValid, isKeystoreValid } from "./schema_validator.js";
|
|
21
21
|
import type {
|
22
22
|
Keccak256Hash,
|
23
23
|
KeystoreEntity,
|
24
|
-
KeystoreMembershipInfo,
|
25
24
|
MembershipHash,
|
25
|
+
MembershipInfo,
|
26
26
|
Password,
|
27
27
|
Sha256Hash
|
28
28
|
} from "./types.js";
|
@@ -310,9 +310,7 @@ export class Keystore {
|
|
310
310
|
|
311
311
|
// follows nwaku implementation
|
312
312
|
// https://github.com/waku-org/nwaku/blob/f05528d4be3d3c876a8b07f9bb7dfaae8aa8ec6e/waku/waku_keystore/protocol_types.nim#L111
|
313
|
-
private static computeMembershipHash(
|
314
|
-
info: KeystoreMembershipInfo
|
315
|
-
): MembershipHash {
|
313
|
+
private static computeMembershipHash(info: MembershipInfo): MembershipHash {
|
316
314
|
return bytesToHex(
|
317
315
|
sha256(utf8ToBytes(`${info.chainId}${info.address}${info.treeIndex}`))
|
318
316
|
).toUpperCase();
|
package/src/keystore/types.ts
CHANGED
@@ -7,7 +7,7 @@ export type Password = string | Uint8Array;
|
|
7
7
|
|
8
8
|
// see reference
|
9
9
|
// https://github.com/waku-org/nwaku/blob/f05528d4be3d3c876a8b07f9bb7dfaae8aa8ec6e/waku/waku_keystore/protocol_types.nim#L111
|
10
|
-
export type
|
10
|
+
export type MembershipInfo = {
|
11
11
|
chainId: string;
|
12
12
|
address: string;
|
13
13
|
treeIndex: number;
|
@@ -16,7 +16,7 @@ export type KeystoreMembershipInfo = {
|
|
16
16
|
|
17
17
|
export type KeystoreEntity = {
|
18
18
|
identity: IdentityCredential;
|
19
|
-
membership:
|
19
|
+
membership: MembershipInfo;
|
20
20
|
};
|
21
21
|
|
22
22
|
export type DecryptedCredentials = KeystoreEntity;
|