@waku/rln 0.0.2-2eccb11.0 → 0.0.2-3ab8023.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 +162 -13
- package/bundle/packages/rln/dist/rln.js +2 -8
- package/dist/.tsbuildinfo +1 -1
- package/dist/contract/rln_contract.d.ts +7 -1
- package/dist/contract/rln_contract.js +162 -13
- package/dist/contract/rln_contract.js.map +1 -1
- package/dist/rln.js +2 -8
- package/dist/rln.js.map +1 -1
- package/package.json +1 -1
- package/src/contract/rln_contract.ts +244 -18
- package/src/rln.ts +3 -9
@@ -1,3 +1,4 @@
|
|
1
|
+
/* eslint-disable no-console */
|
1
2
|
import { Logger } from "@waku/utils";
|
2
3
|
import { hexToBytes } from "@waku/utils/bytes";
|
3
4
|
import { ethers } from "ethers";
|
@@ -112,7 +113,7 @@ export class RLNContract {
|
|
112
113
|
this.contract = contract || new ethers.Contract(address, RLN_ABI, signer);
|
113
114
|
this.merkleRootTracker = new MerkleRootTracker(5, initialRoot);
|
114
115
|
|
115
|
-
// Initialize event filters
|
116
|
+
// Initialize event filters
|
116
117
|
this._membersFilter = this.contract.filters.MembershipRegistered();
|
117
118
|
this._membersRemovedFilter = this.contract.filters.MembershipErased();
|
118
119
|
this._membersExpiredFilter = this.contract.filters.MembershipExpired();
|
@@ -267,7 +268,6 @@ export class RLNContract {
|
|
267
268
|
// Both MembershipErased and MembershipExpired events should remove members
|
268
269
|
let index = evt.args.index;
|
269
270
|
|
270
|
-
// Ensure index is an ethers.BigNumber
|
271
271
|
if (!index) {
|
272
272
|
return;
|
273
273
|
}
|
@@ -293,7 +293,6 @@ export class RLNContract {
|
|
293
293
|
eventsPerBlock.push(evt);
|
294
294
|
toInsertTable.set(evt.blockNumber, eventsPerBlock);
|
295
295
|
}
|
296
|
-
// MembershipExtended events don't change the membership set, so we don't need to handle them here
|
297
296
|
});
|
298
297
|
|
299
298
|
this.removeMembers(rlnInstance, toRemoveTable);
|
@@ -396,46 +395,149 @@ export class RLNContract {
|
|
396
395
|
identity: IdentityCredential
|
397
396
|
): Promise<DecryptedCredentials | undefined> {
|
398
397
|
try {
|
398
|
+
console.log("registerWithIdentity - starting registration process");
|
399
|
+
console.log("registerWithIdentity - identity:", identity);
|
400
|
+
console.log(
|
401
|
+
"registerWithIdentity - IDCommitmentBigInt:",
|
402
|
+
identity.IDCommitmentBigInt.toString()
|
403
|
+
);
|
404
|
+
console.log("registerWithIdentity - rate limit:", this.rateLimit);
|
405
|
+
|
399
406
|
log.info(
|
400
407
|
`Registering identity with rate limit: ${this.rateLimit} messages/epoch`
|
401
408
|
);
|
402
409
|
|
410
|
+
// Check if the ID commitment is already registered
|
411
|
+
const existingIndex = await this.getMemberIndex(
|
412
|
+
identity.IDCommitmentBigInt.toString()
|
413
|
+
);
|
414
|
+
if (existingIndex) {
|
415
|
+
console.error(
|
416
|
+
`ID commitment is already registered with index ${existingIndex}`
|
417
|
+
);
|
418
|
+
throw new Error(
|
419
|
+
`ID commitment is already registered with index ${existingIndex}`
|
420
|
+
);
|
421
|
+
}
|
422
|
+
|
423
|
+
// Check if there's enough remaining rate limit
|
424
|
+
const remainingRateLimit = await this.getRemainingTotalRateLimit();
|
425
|
+
if (remainingRateLimit < this.rateLimit) {
|
426
|
+
console.error(
|
427
|
+
`Not enough remaining rate limit. Requested: ${this.rateLimit}, Available: ${remainingRateLimit}`
|
428
|
+
);
|
429
|
+
throw new Error(
|
430
|
+
`Not enough remaining rate limit. Requested: ${this.rateLimit}, Available: ${remainingRateLimit}`
|
431
|
+
);
|
432
|
+
}
|
433
|
+
|
434
|
+
console.log("registerWithIdentity - calling contract.register");
|
435
|
+
// Estimate gas for the transaction
|
436
|
+
const estimatedGas = await this.contract.estimateGas.register(
|
437
|
+
identity.IDCommitmentBigInt,
|
438
|
+
this.rateLimit,
|
439
|
+
[]
|
440
|
+
);
|
441
|
+
const gasLimit = estimatedGas.add(10000);
|
442
|
+
|
403
443
|
const txRegisterResponse: ethers.ContractTransaction =
|
404
444
|
await this.contract.register(
|
405
445
|
identity.IDCommitmentBigInt,
|
406
446
|
this.rateLimit,
|
407
447
|
[],
|
408
|
-
{ gasLimit
|
448
|
+
{ gasLimit }
|
409
449
|
);
|
450
|
+
console.log(
|
451
|
+
"registerWithIdentity - txRegisterResponse:",
|
452
|
+
txRegisterResponse
|
453
|
+
);
|
454
|
+
console.log("registerWithIdentity - hash:", txRegisterResponse.hash);
|
455
|
+
console.log(
|
456
|
+
"registerWithIdentity - waiting for transaction confirmation..."
|
457
|
+
);
|
458
|
+
|
410
459
|
const txRegisterReceipt = await txRegisterResponse.wait();
|
460
|
+
console.log(
|
461
|
+
"registerWithIdentity - txRegisterReceipt:",
|
462
|
+
txRegisterReceipt
|
463
|
+
);
|
464
|
+
console.log(
|
465
|
+
"registerWithIdentity - transaction status:",
|
466
|
+
txRegisterReceipt.status
|
467
|
+
);
|
468
|
+
console.log(
|
469
|
+
"registerWithIdentity - block number:",
|
470
|
+
txRegisterReceipt.blockNumber
|
471
|
+
);
|
472
|
+
console.log(
|
473
|
+
"registerWithIdentity - gas used:",
|
474
|
+
txRegisterReceipt.gasUsed.toString()
|
475
|
+
);
|
476
|
+
|
477
|
+
// Check transaction status
|
478
|
+
if (txRegisterReceipt.status === 0) {
|
479
|
+
console.error("Transaction failed on-chain");
|
480
|
+
throw new Error("Transaction failed on-chain");
|
481
|
+
}
|
411
482
|
|
412
483
|
const memberRegistered = txRegisterReceipt.events?.find(
|
413
484
|
(event) => event.event === "MembershipRegistered"
|
414
485
|
);
|
486
|
+
console.log(
|
487
|
+
"registerWithIdentity - memberRegistered event:",
|
488
|
+
memberRegistered
|
489
|
+
);
|
415
490
|
|
416
491
|
if (!memberRegistered || !memberRegistered.args) {
|
417
|
-
log
|
492
|
+
console.log(
|
493
|
+
"registerWithIdentity - ERROR: no memberRegistered event found"
|
494
|
+
);
|
495
|
+
console.log(
|
496
|
+
"registerWithIdentity - all events:",
|
497
|
+
txRegisterReceipt.events
|
498
|
+
);
|
499
|
+
console.error(
|
418
500
|
"Failed to register membership: No MembershipRegistered event found"
|
419
501
|
);
|
420
502
|
return undefined;
|
421
503
|
}
|
422
504
|
|
505
|
+
console.log(
|
506
|
+
"registerWithIdentity - memberRegistered args:",
|
507
|
+
memberRegistered.args
|
508
|
+
);
|
423
509
|
const decodedData: MembershipRegisteredEvent = {
|
424
510
|
idCommitment: memberRegistered.args.idCommitment,
|
425
511
|
membershipRateLimit: memberRegistered.args.membershipRateLimit,
|
426
512
|
index: memberRegistered.args.index
|
427
513
|
};
|
514
|
+
console.log("registerWithIdentity - decodedData:", decodedData);
|
515
|
+
console.log(
|
516
|
+
"registerWithIdentity - index:",
|
517
|
+
decodedData.index.toString()
|
518
|
+
);
|
519
|
+
console.log(
|
520
|
+
"registerWithIdentity - membershipRateLimit:",
|
521
|
+
decodedData.membershipRateLimit.toString()
|
522
|
+
);
|
428
523
|
|
429
524
|
log.info(
|
430
525
|
`Successfully registered membership with index ${decodedData.index} ` +
|
431
526
|
`and rate limit ${decodedData.membershipRateLimit}`
|
432
527
|
);
|
433
528
|
|
529
|
+
console.log("registerWithIdentity - getting network information");
|
434
530
|
const network = await this.contract.provider.getNetwork();
|
531
|
+
console.log("registerWithIdentity - network:", network);
|
532
|
+
console.log("registerWithIdentity - chainId:", network.chainId);
|
533
|
+
|
435
534
|
const address = this.contract.address;
|
535
|
+
console.log("registerWithIdentity - contract address:", address);
|
536
|
+
|
436
537
|
const membershipId = decodedData.index.toNumber();
|
538
|
+
console.log("registerWithIdentity - membershipId:", membershipId);
|
437
539
|
|
438
|
-
|
540
|
+
const result = {
|
439
541
|
identity,
|
440
542
|
membership: {
|
441
543
|
address,
|
@@ -443,9 +545,41 @@ export class RLNContract {
|
|
443
545
|
chainId: network.chainId
|
444
546
|
}
|
445
547
|
};
|
548
|
+
console.log("registerWithIdentity - returning result:", result);
|
549
|
+
|
550
|
+
return result;
|
446
551
|
} catch (error) {
|
447
|
-
log
|
448
|
-
|
552
|
+
console.log("registerWithIdentity - ERROR:", error);
|
553
|
+
|
554
|
+
// Improved error handling to decode contract errors
|
555
|
+
if (error instanceof Error) {
|
556
|
+
const errorMessage = error.message;
|
557
|
+
console.log("registerWithIdentity - error message:", errorMessage);
|
558
|
+
console.log("registerWithIdentity - error stack:", error.stack);
|
559
|
+
|
560
|
+
// Try to extract more specific error information
|
561
|
+
if (errorMessage.includes("CannotExceedMaxTotalRateLimit")) {
|
562
|
+
console.error(
|
563
|
+
"Registration failed: Cannot exceed maximum total rate limit"
|
564
|
+
);
|
565
|
+
} else if (errorMessage.includes("InvalidIdCommitment")) {
|
566
|
+
console.error("Registration failed: Invalid ID commitment");
|
567
|
+
} else if (errorMessage.includes("InvalidMembershipRateLimit")) {
|
568
|
+
console.error("Registration failed: Invalid membership rate limit");
|
569
|
+
} else if (errorMessage.includes("execution reverted")) {
|
570
|
+
// Generic revert
|
571
|
+
console.error(
|
572
|
+
"Contract execution reverted. Check contract requirements."
|
573
|
+
);
|
574
|
+
} else {
|
575
|
+
console.error(`Error in registerWithIdentity: ${errorMessage}`);
|
576
|
+
}
|
577
|
+
} else {
|
578
|
+
console.error("Unknown error in registerWithIdentity");
|
579
|
+
}
|
580
|
+
|
581
|
+
// Re-throw the error to allow callers to handle it
|
582
|
+
throw error;
|
449
583
|
}
|
450
584
|
}
|
451
585
|
|
@@ -619,17 +753,28 @@ export class RLNContract {
|
|
619
753
|
public async registerMembership(
|
620
754
|
idCommitment: string,
|
621
755
|
rateLimit: number = DEFAULT_RATE_LIMIT
|
622
|
-
): Promise<ethers.
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
756
|
+
): Promise<ethers.ContractTransaction> {
|
757
|
+
try {
|
758
|
+
if (
|
759
|
+
rateLimit < RATE_LIMIT_PARAMS.MIN_RATE ||
|
760
|
+
rateLimit > RATE_LIMIT_PARAMS.MAX_RATE
|
761
|
+
) {
|
762
|
+
throw new Error(
|
763
|
+
`Rate limit must be between ${RATE_LIMIT_PARAMS.MIN_RATE} and ${RATE_LIMIT_PARAMS.MAX_RATE}`
|
764
|
+
);
|
765
|
+
}
|
766
|
+
|
767
|
+
// Try to register
|
768
|
+
return this.contract.register(idCommitment, rateLimit, []);
|
769
|
+
} catch (error) {
|
770
|
+
console.error("Error in registerMembership:", error);
|
771
|
+
|
772
|
+
// Run debug to help diagnose the issue
|
773
|
+
await this.debugRegistration(idCommitment, rateLimit);
|
774
|
+
|
775
|
+
// Re-throw the error
|
776
|
+
throw error;
|
630
777
|
}
|
631
|
-
const tx = await this.contract.register(idCommitment, rateLimit, []);
|
632
|
-
return await tx.wait();
|
633
778
|
}
|
634
779
|
|
635
780
|
private async getMemberIndex(
|
@@ -648,6 +793,87 @@ export class RLNContract {
|
|
648
793
|
return undefined;
|
649
794
|
}
|
650
795
|
}
|
796
|
+
|
797
|
+
/**
|
798
|
+
* Debug function to check why a registration might fail
|
799
|
+
* @param idCommitment The ID commitment to check
|
800
|
+
* @param rateLimit The rate limit to check
|
801
|
+
*/
|
802
|
+
public async debugRegistration(
|
803
|
+
idCommitment: string,
|
804
|
+
rateLimit: number
|
805
|
+
): Promise<void> {
|
806
|
+
console.log("=== DEBUG REGISTRATION ===");
|
807
|
+
console.log(`ID Commitment: ${idCommitment}`);
|
808
|
+
console.log(`Rate Limit: ${rateLimit}`);
|
809
|
+
|
810
|
+
// Check if ID commitment is already registered
|
811
|
+
try {
|
812
|
+
const existingIndex = await this.getMemberIndex(idCommitment);
|
813
|
+
if (existingIndex) {
|
814
|
+
console.error(
|
815
|
+
`ERROR: ID commitment is already registered with index ${existingIndex}`
|
816
|
+
);
|
817
|
+
} else {
|
818
|
+
console.log("ID commitment is not yet registered ✓");
|
819
|
+
}
|
820
|
+
} catch (error) {
|
821
|
+
console.error("Error checking if ID commitment is registered:", error);
|
822
|
+
}
|
823
|
+
|
824
|
+
// Check rate limit constraints
|
825
|
+
try {
|
826
|
+
const minRateLimit = await this.getMinRateLimit();
|
827
|
+
const maxRateLimit = await this.getMaxRateLimit();
|
828
|
+
const maxTotalRateLimit = await this.getMaxTotalRateLimit();
|
829
|
+
const currentTotalRateLimit = await this.getCurrentTotalRateLimit();
|
830
|
+
const remainingRateLimit = await this.getRemainingTotalRateLimit();
|
831
|
+
|
832
|
+
console.log(`Min Rate Limit: ${minRateLimit}`);
|
833
|
+
console.log(`Max Rate Limit: ${maxRateLimit}`);
|
834
|
+
console.log(`Max Total Rate Limit: ${maxTotalRateLimit}`);
|
835
|
+
console.log(`Current Total Rate Limit: ${currentTotalRateLimit}`);
|
836
|
+
console.log(`Remaining Rate Limit: ${remainingRateLimit}`);
|
837
|
+
|
838
|
+
if (rateLimit < minRateLimit) {
|
839
|
+
console.error(
|
840
|
+
`ERROR: Rate limit ${rateLimit} is below minimum ${minRateLimit}`
|
841
|
+
);
|
842
|
+
}
|
843
|
+
if (rateLimit > maxRateLimit) {
|
844
|
+
console.error(
|
845
|
+
`ERROR: Rate limit ${rateLimit} exceeds maximum ${maxRateLimit}`
|
846
|
+
);
|
847
|
+
}
|
848
|
+
if (rateLimit > remainingRateLimit) {
|
849
|
+
console.error(
|
850
|
+
`ERROR: Rate limit ${rateLimit} exceeds remaining capacity ${remainingRateLimit}`
|
851
|
+
);
|
852
|
+
}
|
853
|
+
} catch (error) {
|
854
|
+
console.error("Error checking rate limit constraints:", error);
|
855
|
+
}
|
856
|
+
|
857
|
+
// Try to estimate gas for the transaction to see if it would revert
|
858
|
+
try {
|
859
|
+
await this.contract.estimateGas.register(idCommitment, rateLimit, []);
|
860
|
+
console.log("Transaction gas estimation succeeded ✓");
|
861
|
+
} catch (error) {
|
862
|
+
console.error("Transaction would revert with error:", error);
|
863
|
+
|
864
|
+
// Try to extract more specific error information
|
865
|
+
const errorMessage = (error as Error).message;
|
866
|
+
if (errorMessage.includes("CannotExceedMaxTotalRateLimit")) {
|
867
|
+
console.error("Cannot exceed maximum total rate limit");
|
868
|
+
} else if (errorMessage.includes("InvalidIdCommitment")) {
|
869
|
+
console.error("Invalid ID commitment format");
|
870
|
+
} else if (errorMessage.includes("InvalidMembershipRateLimit")) {
|
871
|
+
console.error("Invalid membership rate limit");
|
872
|
+
}
|
873
|
+
}
|
874
|
+
|
875
|
+
console.log("=== END DEBUG ===");
|
876
|
+
}
|
651
877
|
}
|
652
878
|
|
653
879
|
interface CustomQueryOptions extends FetchMembersOptions {
|
package/src/rln.ts
CHANGED
@@ -151,8 +151,6 @@ export class RLNInstance {
|
|
151
151
|
}
|
152
152
|
|
153
153
|
public async start(options: StartRLNOptions = {}): Promise<void> {
|
154
|
-
// eslint-disable-next-line no-console
|
155
|
-
console.log("starting", options);
|
156
154
|
if (this.started || this.starting) {
|
157
155
|
return;
|
158
156
|
}
|
@@ -198,13 +196,6 @@ export class RLNInstance {
|
|
198
196
|
chainId = SEPOLIA_CONTRACT.chainId;
|
199
197
|
}
|
200
198
|
|
201
|
-
// eslint-disable-next-line no-console
|
202
|
-
console.log({
|
203
|
-
chainId,
|
204
|
-
address,
|
205
|
-
SEPOLIA_CONTRACT
|
206
|
-
});
|
207
|
-
|
208
199
|
const signer = options.signer || (await extractMetaMaskSigner());
|
209
200
|
const currentChainId = await signer.getChainId();
|
210
201
|
|
@@ -263,6 +254,9 @@ export class RLNInstance {
|
|
263
254
|
);
|
264
255
|
}
|
265
256
|
|
257
|
+
// eslint-disable-next-line no-console
|
258
|
+
console.log("registering membership", identity);
|
259
|
+
|
266
260
|
if (!identity) {
|
267
261
|
throw Error("Missing signature or identity to register membership.");
|
268
262
|
}
|