@waku/rln 0.0.2-950aefb.0 → 0.0.2-a3e7f15.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/packages/rln/dist/contract/rln_contract.js +34 -155
- package/bundle/packages/rln/dist/rln.js +0 -2
- package/dist/.tsbuildinfo +1 -1
- package/dist/contract/rln_contract.d.ts +4 -10
- package/dist/contract/rln_contract.js +34 -155
- package/dist/contract/rln_contract.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/rln.js +0 -2
- package/dist/rln.js.map +1 -1
- package/package.json +1 -1
- package/src/contract/rln_contract.ts +40 -223
- package/src/index.ts +11 -0
- package/src/rln.ts +0 -3
@@ -1,4 +1,3 @@
|
|
1
|
-
/* eslint-disable no-console */
|
2
1
|
import { Logger } from "@waku/utils";
|
3
2
|
import { hexToBytes } from "@waku/utils/bytes";
|
4
3
|
import { ethers } from "ethers";
|
@@ -66,7 +65,7 @@ export class RLNContract {
|
|
66
65
|
|
67
66
|
private _members: Map<number, Member> = new Map();
|
68
67
|
private _membersFilter: ethers.EventFilter;
|
69
|
-
private
|
68
|
+
private _membershipErasedFilter: ethers.EventFilter;
|
70
69
|
private _membersExpiredFilter: ethers.EventFilter;
|
71
70
|
|
72
71
|
/**
|
@@ -115,7 +114,7 @@ export class RLNContract {
|
|
115
114
|
|
116
115
|
// Initialize event filters
|
117
116
|
this._membersFilter = this.contract.filters.MembershipRegistered();
|
118
|
-
this.
|
117
|
+
this._membershipErasedFilter = this.contract.filters.MembershipErased();
|
119
118
|
this._membersExpiredFilter = this.contract.filters.MembershipExpired();
|
120
119
|
}
|
121
120
|
|
@@ -181,12 +180,11 @@ export class RLNContract {
|
|
181
180
|
* @returns Promise<number> The remaining rate limit that can be allocated
|
182
181
|
*/
|
183
182
|
public async getRemainingTotalRateLimit(): Promise<number> {
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
return 10_000;
|
183
|
+
const [maxTotal, currentTotal] = await Promise.all([
|
184
|
+
this.contract.maxTotalRateLimit(),
|
185
|
+
this.contract.currentTotalRateLimit()
|
186
|
+
]);
|
187
|
+
return Number(maxTotal) - Number(currentTotal);
|
190
188
|
}
|
191
189
|
|
192
190
|
/**
|
@@ -211,11 +209,11 @@ export class RLNContract {
|
|
211
209
|
return this._membersFilter;
|
212
210
|
}
|
213
211
|
|
214
|
-
private get
|
215
|
-
if (!this.
|
216
|
-
throw Error("
|
212
|
+
private get membershipErasedFilter(): ethers.EventFilter {
|
213
|
+
if (!this._membershipErasedFilter) {
|
214
|
+
throw Error("MembershipErased filter was not initialized.");
|
217
215
|
}
|
218
|
-
return this.
|
216
|
+
return this._membershipErasedFilter;
|
219
217
|
}
|
220
218
|
|
221
219
|
private get membersExpiredFilter(): ethers.EventFilter {
|
@@ -237,7 +235,7 @@ export class RLNContract {
|
|
237
235
|
const removedMemberEvents = await queryFilter(this.contract, {
|
238
236
|
fromBlock: this.deployBlock,
|
239
237
|
...options,
|
240
|
-
membersFilter: this.
|
238
|
+
membersFilter: this.membershipErasedFilter
|
241
239
|
});
|
242
240
|
const expiredMemberEvents = await queryFilter(this.contract, {
|
243
241
|
fromBlock: this.deployBlock,
|
@@ -266,14 +264,12 @@ export class RLNContract {
|
|
266
264
|
evt.event === "MembershipErased" ||
|
267
265
|
evt.event === "MembershipExpired"
|
268
266
|
) {
|
269
|
-
// Both MembershipErased and MembershipExpired events should remove members
|
270
267
|
let index = evt.args.index;
|
271
268
|
|
272
269
|
if (!index) {
|
273
270
|
return;
|
274
271
|
}
|
275
272
|
|
276
|
-
// Convert index to ethers.BigNumber if it's not already
|
277
273
|
if (typeof index === "number" || typeof index === "string") {
|
278
274
|
index = ethers.BigNumber.from(index);
|
279
275
|
}
|
@@ -311,12 +307,10 @@ export class RLNContract {
|
|
311
307
|
const _idCommitment = evt.args.idCommitment as string;
|
312
308
|
let index = evt.args.index;
|
313
309
|
|
314
|
-
// Ensure index is an ethers.BigNumber
|
315
310
|
if (!_idCommitment || !index) {
|
316
311
|
return;
|
317
312
|
}
|
318
313
|
|
319
|
-
// Convert index to ethers.BigNumber if it's not already
|
320
314
|
if (typeof index === "number" || typeof index === "string") {
|
321
315
|
index = ethers.BigNumber.from(index);
|
322
316
|
}
|
@@ -324,10 +318,9 @@ export class RLNContract {
|
|
324
318
|
const idCommitment = zeroPadLE(hexToBytes(_idCommitment), 32);
|
325
319
|
rlnInstance.zerokit.insertMember(idCommitment);
|
326
320
|
|
327
|
-
// Always store the numeric index as the key, but the BigNumber as the value
|
328
321
|
const numericIndex = index.toNumber();
|
329
322
|
this._members.set(numericIndex, {
|
330
|
-
index,
|
323
|
+
index,
|
331
324
|
idCommitment: _idCommitment
|
332
325
|
});
|
333
326
|
});
|
@@ -368,7 +361,7 @@ export class RLNContract {
|
|
368
361
|
);
|
369
362
|
|
370
363
|
this.contract.on(
|
371
|
-
this.
|
364
|
+
this.membershipErasedFilter,
|
372
365
|
(
|
373
366
|
_idCommitment: string,
|
374
367
|
_membershipRateLimit: ethers.BigNumber,
|
@@ -396,14 +389,6 @@ export class RLNContract {
|
|
396
389
|
identity: IdentityCredential
|
397
390
|
): Promise<DecryptedCredentials | undefined> {
|
398
391
|
try {
|
399
|
-
console.log("registerWithIdentity - starting registration process");
|
400
|
-
console.log("registerWithIdentity - identity:", identity);
|
401
|
-
console.log(
|
402
|
-
"registerWithIdentity - IDCommitmentBigInt:",
|
403
|
-
identity.IDCommitmentBigInt.toString()
|
404
|
-
);
|
405
|
-
console.log("registerWithIdentity - rate limit:", this.rateLimit);
|
406
|
-
|
407
392
|
log.info(
|
408
393
|
`Registering identity with rate limit: ${this.rateLimit} messages/epoch`
|
409
394
|
);
|
@@ -413,9 +398,6 @@ export class RLNContract {
|
|
413
398
|
identity.IDCommitmentBigInt.toString()
|
414
399
|
);
|
415
400
|
if (existingIndex) {
|
416
|
-
console.error(
|
417
|
-
`ID commitment is already registered with index ${existingIndex}`
|
418
|
-
);
|
419
401
|
throw new Error(
|
420
402
|
`ID commitment is already registered with index ${existingIndex}`
|
421
403
|
);
|
@@ -424,16 +406,11 @@ export class RLNContract {
|
|
424
406
|
// Check if there's enough remaining rate limit
|
425
407
|
const remainingRateLimit = await this.getRemainingTotalRateLimit();
|
426
408
|
if (remainingRateLimit < this.rateLimit) {
|
427
|
-
console.error(
|
428
|
-
`Not enough remaining rate limit. Requested: ${this.rateLimit}, Available: ${remainingRateLimit}`
|
429
|
-
);
|
430
409
|
throw new Error(
|
431
410
|
`Not enough remaining rate limit. Requested: ${this.rateLimit}, Available: ${remainingRateLimit}`
|
432
411
|
);
|
433
412
|
}
|
434
413
|
|
435
|
-
console.log("registerWithIdentity - calling contract.register");
|
436
|
-
// Estimate gas for the transaction
|
437
414
|
const estimatedGas = await this.contract.estimateGas.register(
|
438
415
|
identity.IDCommitmentBigInt,
|
439
416
|
this.rateLimit,
|
@@ -448,97 +425,40 @@ export class RLNContract {
|
|
448
425
|
[],
|
449
426
|
{ gasLimit }
|
450
427
|
);
|
451
|
-
console.log(
|
452
|
-
"registerWithIdentity - txRegisterResponse:",
|
453
|
-
txRegisterResponse
|
454
|
-
);
|
455
|
-
console.log("registerWithIdentity - hash:", txRegisterResponse.hash);
|
456
|
-
console.log(
|
457
|
-
"registerWithIdentity - waiting for transaction confirmation..."
|
458
|
-
);
|
459
428
|
|
460
429
|
const txRegisterReceipt = await txRegisterResponse.wait();
|
461
|
-
console.log(
|
462
|
-
"registerWithIdentity - txRegisterReceipt:",
|
463
|
-
txRegisterReceipt
|
464
|
-
);
|
465
|
-
console.log(
|
466
|
-
"registerWithIdentity - transaction status:",
|
467
|
-
txRegisterReceipt.status
|
468
|
-
);
|
469
|
-
console.log(
|
470
|
-
"registerWithIdentity - block number:",
|
471
|
-
txRegisterReceipt.blockNumber
|
472
|
-
);
|
473
|
-
console.log(
|
474
|
-
"registerWithIdentity - gas used:",
|
475
|
-
txRegisterReceipt.gasUsed.toString()
|
476
|
-
);
|
477
430
|
|
478
|
-
// Check transaction status
|
479
431
|
if (txRegisterReceipt.status === 0) {
|
480
|
-
console.error("Transaction failed on-chain");
|
481
432
|
throw new Error("Transaction failed on-chain");
|
482
433
|
}
|
483
434
|
|
484
435
|
const memberRegistered = txRegisterReceipt.events?.find(
|
485
436
|
(event) => event.event === "MembershipRegistered"
|
486
437
|
);
|
487
|
-
console.log(
|
488
|
-
"registerWithIdentity - memberRegistered event:",
|
489
|
-
memberRegistered
|
490
|
-
);
|
491
438
|
|
492
439
|
if (!memberRegistered || !memberRegistered.args) {
|
493
|
-
|
494
|
-
"registerWithIdentity - ERROR: no memberRegistered event found"
|
495
|
-
);
|
496
|
-
console.log(
|
497
|
-
"registerWithIdentity - all events:",
|
498
|
-
txRegisterReceipt.events
|
499
|
-
);
|
500
|
-
console.error(
|
440
|
+
log.error(
|
501
441
|
"Failed to register membership: No MembershipRegistered event found"
|
502
442
|
);
|
503
443
|
return undefined;
|
504
444
|
}
|
505
445
|
|
506
|
-
console.log(
|
507
|
-
"registerWithIdentity - memberRegistered args:",
|
508
|
-
memberRegistered.args
|
509
|
-
);
|
510
446
|
const decodedData: MembershipRegisteredEvent = {
|
511
447
|
idCommitment: memberRegistered.args.idCommitment,
|
512
448
|
membershipRateLimit: memberRegistered.args.membershipRateLimit,
|
513
449
|
index: memberRegistered.args.index
|
514
450
|
};
|
515
|
-
console.log("registerWithIdentity - decodedData:", decodedData);
|
516
|
-
console.log(
|
517
|
-
"registerWithIdentity - index:",
|
518
|
-
decodedData.index.toString()
|
519
|
-
);
|
520
|
-
console.log(
|
521
|
-
"registerWithIdentity - membershipRateLimit:",
|
522
|
-
decodedData.membershipRateLimit.toString()
|
523
|
-
);
|
524
451
|
|
525
452
|
log.info(
|
526
453
|
`Successfully registered membership with index ${decodedData.index} ` +
|
527
454
|
`and rate limit ${decodedData.membershipRateLimit}`
|
528
455
|
);
|
529
456
|
|
530
|
-
console.log("registerWithIdentity - getting network information");
|
531
457
|
const network = await this.contract.provider.getNetwork();
|
532
|
-
console.log("registerWithIdentity - network:", network);
|
533
|
-
console.log("registerWithIdentity - chainId:", network.chainId);
|
534
|
-
|
535
458
|
const address = this.contract.address;
|
536
|
-
|
537
|
-
|
538
|
-
const membershipId = decodedData.index.toNumber();
|
539
|
-
console.log("registerWithIdentity - membershipId:", membershipId);
|
459
|
+
const membershipId = Number(decodedData.index);
|
540
460
|
|
541
|
-
|
461
|
+
return {
|
542
462
|
identity,
|
543
463
|
membership: {
|
544
464
|
address,
|
@@ -546,41 +466,33 @@ export class RLNContract {
|
|
546
466
|
chainId: network.chainId
|
547
467
|
}
|
548
468
|
};
|
549
|
-
console.log("registerWithIdentity - returning result:", result);
|
550
|
-
|
551
|
-
return result;
|
552
469
|
} catch (error) {
|
553
|
-
console.log("registerWithIdentity - ERROR:", error);
|
554
|
-
|
555
|
-
// Improved error handling to decode contract errors
|
556
470
|
if (error instanceof Error) {
|
557
471
|
const errorMessage = error.message;
|
558
|
-
|
559
|
-
|
472
|
+
log.error("registerWithIdentity - error message:", errorMessage);
|
473
|
+
log.error("registerWithIdentity - error stack:", error.stack);
|
560
474
|
|
561
475
|
// Try to extract more specific error information
|
562
476
|
if (errorMessage.includes("CannotExceedMaxTotalRateLimit")) {
|
563
|
-
|
477
|
+
throw new Error(
|
564
478
|
"Registration failed: Cannot exceed maximum total rate limit"
|
565
479
|
);
|
566
480
|
} else if (errorMessage.includes("InvalidIdCommitment")) {
|
567
|
-
|
481
|
+
throw new Error("Registration failed: Invalid ID commitment");
|
568
482
|
} else if (errorMessage.includes("InvalidMembershipRateLimit")) {
|
569
|
-
|
483
|
+
throw new Error("Registration failed: Invalid membership rate limit");
|
570
484
|
} else if (errorMessage.includes("execution reverted")) {
|
571
|
-
|
572
|
-
console.error(
|
485
|
+
throw new Error(
|
573
486
|
"Contract execution reverted. Check contract requirements."
|
574
487
|
);
|
575
488
|
} else {
|
576
|
-
|
489
|
+
throw new Error(`Error in registerWithIdentity: ${errorMessage}`);
|
577
490
|
}
|
578
491
|
} else {
|
579
|
-
|
492
|
+
throw new Error("Unknown error in registerWithIdentity", {
|
493
|
+
cause: error
|
494
|
+
});
|
580
495
|
}
|
581
|
-
|
582
|
-
// Re-throw the error to allow callers to handle it
|
583
|
-
throw error;
|
584
496
|
}
|
585
497
|
}
|
586
498
|
|
@@ -669,7 +581,7 @@ export class RLNContract {
|
|
669
581
|
|
670
582
|
const network = await this.contract.provider.getNetwork();
|
671
583
|
const address = this.contract.address;
|
672
|
-
const membershipId = decodedData.index
|
584
|
+
const membershipId = Number(decodedData.index);
|
673
585
|
|
674
586
|
return {
|
675
587
|
identity,
|
@@ -735,47 +647,33 @@ export class RLNContract {
|
|
735
647
|
|
736
648
|
public async extendMembership(
|
737
649
|
idCommitment: string
|
738
|
-
): Promise<ethers.
|
739
|
-
|
740
|
-
return await tx.wait();
|
650
|
+
): Promise<ethers.ContractTransaction> {
|
651
|
+
return this.contract.extendMemberships([idCommitment]);
|
741
652
|
}
|
742
653
|
|
743
654
|
public async eraseMembership(
|
744
655
|
idCommitment: string,
|
745
656
|
eraseFromMembershipSet: boolean = true
|
746
|
-
): Promise<ethers.
|
747
|
-
|
657
|
+
): Promise<ethers.ContractTransaction> {
|
658
|
+
return this.contract.eraseMemberships(
|
748
659
|
[idCommitment],
|
749
660
|
eraseFromMembershipSet
|
750
661
|
);
|
751
|
-
return await tx.wait();
|
752
662
|
}
|
753
663
|
|
754
664
|
public async registerMembership(
|
755
665
|
idCommitment: string,
|
756
666
|
rateLimit: number = DEFAULT_RATE_LIMIT
|
757
667
|
): Promise<ethers.ContractTransaction> {
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
);
|
766
|
-
}
|
767
|
-
|
768
|
-
// Try to register
|
769
|
-
return this.contract.register(idCommitment, rateLimit, []);
|
770
|
-
} catch (error) {
|
771
|
-
console.error("Error in registerMembership:", error);
|
772
|
-
|
773
|
-
// Run debug to help diagnose the issue
|
774
|
-
await this.debugRegistration(idCommitment, rateLimit);
|
775
|
-
|
776
|
-
// Re-throw the error
|
777
|
-
throw error;
|
668
|
+
if (
|
669
|
+
rateLimit < RATE_LIMIT_PARAMS.MIN_RATE ||
|
670
|
+
rateLimit > RATE_LIMIT_PARAMS.MAX_RATE
|
671
|
+
) {
|
672
|
+
throw new Error(
|
673
|
+
`Rate limit must be between ${RATE_LIMIT_PARAMS.MIN_RATE} and ${RATE_LIMIT_PARAMS.MAX_RATE}`
|
674
|
+
);
|
778
675
|
}
|
676
|
+
return this.contract.register(idCommitment, rateLimit, []);
|
779
677
|
}
|
780
678
|
|
781
679
|
private async getMemberIndex(
|
@@ -794,87 +692,6 @@ export class RLNContract {
|
|
794
692
|
return undefined;
|
795
693
|
}
|
796
694
|
}
|
797
|
-
|
798
|
-
/**
|
799
|
-
* Debug function to check why a registration might fail
|
800
|
-
* @param idCommitment The ID commitment to check
|
801
|
-
* @param rateLimit The rate limit to check
|
802
|
-
*/
|
803
|
-
public async debugRegistration(
|
804
|
-
idCommitment: string,
|
805
|
-
rateLimit: number
|
806
|
-
): Promise<void> {
|
807
|
-
console.log("=== DEBUG REGISTRATION ===");
|
808
|
-
console.log(`ID Commitment: ${idCommitment}`);
|
809
|
-
console.log(`Rate Limit: ${rateLimit}`);
|
810
|
-
|
811
|
-
// Check if ID commitment is already registered
|
812
|
-
try {
|
813
|
-
const existingIndex = await this.getMemberIndex(idCommitment);
|
814
|
-
if (existingIndex) {
|
815
|
-
console.error(
|
816
|
-
`ERROR: ID commitment is already registered with index ${existingIndex}`
|
817
|
-
);
|
818
|
-
} else {
|
819
|
-
console.log("ID commitment is not yet registered ✓");
|
820
|
-
}
|
821
|
-
} catch (error) {
|
822
|
-
console.error("Error checking if ID commitment is registered:", error);
|
823
|
-
}
|
824
|
-
|
825
|
-
// Check rate limit constraints
|
826
|
-
try {
|
827
|
-
const minRateLimit = await this.getMinRateLimit();
|
828
|
-
const maxRateLimit = await this.getMaxRateLimit();
|
829
|
-
const maxTotalRateLimit = await this.getMaxTotalRateLimit();
|
830
|
-
const currentTotalRateLimit = await this.getCurrentTotalRateLimit();
|
831
|
-
const remainingRateLimit = await this.getRemainingTotalRateLimit();
|
832
|
-
|
833
|
-
console.log(`Min Rate Limit: ${minRateLimit}`);
|
834
|
-
console.log(`Max Rate Limit: ${maxRateLimit}`);
|
835
|
-
console.log(`Max Total Rate Limit: ${maxTotalRateLimit}`);
|
836
|
-
console.log(`Current Total Rate Limit: ${currentTotalRateLimit}`);
|
837
|
-
console.log(`Remaining Rate Limit: ${remainingRateLimit}`);
|
838
|
-
|
839
|
-
if (rateLimit < minRateLimit) {
|
840
|
-
console.error(
|
841
|
-
`ERROR: Rate limit ${rateLimit} is below minimum ${minRateLimit}`
|
842
|
-
);
|
843
|
-
}
|
844
|
-
if (rateLimit > maxRateLimit) {
|
845
|
-
console.error(
|
846
|
-
`ERROR: Rate limit ${rateLimit} exceeds maximum ${maxRateLimit}`
|
847
|
-
);
|
848
|
-
}
|
849
|
-
if (rateLimit > remainingRateLimit) {
|
850
|
-
console.error(
|
851
|
-
`ERROR: Rate limit ${rateLimit} exceeds remaining capacity ${remainingRateLimit}`
|
852
|
-
);
|
853
|
-
}
|
854
|
-
} catch (error) {
|
855
|
-
console.error("Error checking rate limit constraints:", error);
|
856
|
-
}
|
857
|
-
|
858
|
-
// Try to estimate gas for the transaction to see if it would revert
|
859
|
-
try {
|
860
|
-
await this.contract.estimateGas.register(idCommitment, rateLimit, []);
|
861
|
-
console.log("Transaction gas estimation succeeded ✓");
|
862
|
-
} catch (error) {
|
863
|
-
console.error("Transaction would revert with error:", error);
|
864
|
-
|
865
|
-
// Try to extract more specific error information
|
866
|
-
const errorMessage = (error as Error).message;
|
867
|
-
if (errorMessage.includes("CannotExceedMaxTotalRateLimit")) {
|
868
|
-
console.error("Cannot exceed maximum total rate limit");
|
869
|
-
} else if (errorMessage.includes("InvalidIdCommitment")) {
|
870
|
-
console.error("Invalid ID commitment format");
|
871
|
-
} else if (errorMessage.includes("InvalidMembershipRateLimit")) {
|
872
|
-
console.error("Invalid membership rate limit");
|
873
|
-
}
|
874
|
-
}
|
875
|
-
|
876
|
-
console.log("=== END DEBUG ===");
|
877
|
-
}
|
878
695
|
}
|
879
696
|
|
880
697
|
interface CustomQueryOptions extends FetchMembersOptions {
|
package/src/index.ts
CHANGED
@@ -23,3 +23,14 @@ export {
|
|
23
23
|
extractMetaMaskSigner,
|
24
24
|
RLN_ABI
|
25
25
|
};
|
26
|
+
|
27
|
+
export type {
|
28
|
+
DecryptedCredentials,
|
29
|
+
EncryptedCredentials,
|
30
|
+
Keccak256Hash,
|
31
|
+
KeystoreEntity,
|
32
|
+
MembershipHash,
|
33
|
+
MembershipInfo,
|
34
|
+
Password,
|
35
|
+
Sha256Hash
|
36
|
+
} from "./keystore/types.js";
|
package/src/rln.ts
CHANGED