@waku/rln 0.1.1-b429b05 → 0.1.1-fa49e29

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 (43) hide show
  1. package/bundle/index.js +22902 -334
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/byte_utils.d.ts +6 -0
  4. package/dist/byte_utils.js +9 -0
  5. package/dist/byte_utils.js.map +1 -1
  6. package/dist/constants.d.ts +2 -2
  7. package/dist/constants.js +62 -9
  8. package/dist/constants.js.map +1 -1
  9. package/dist/index.d.ts +3 -2
  10. package/dist/index.js +3 -2
  11. package/dist/index.js.map +1 -1
  12. package/dist/keystore/cipher.d.ts +4 -0
  13. package/dist/keystore/cipher.js +28 -0
  14. package/dist/keystore/cipher.js.map +1 -0
  15. package/dist/keystore/credential_validation_generated.d.ts +8 -0
  16. package/dist/keystore/credential_validation_generated.js +121 -0
  17. package/dist/keystore/credential_validation_generated.js.map +1 -0
  18. package/dist/keystore/index.d.ts +2 -0
  19. package/dist/keystore/index.js +3 -0
  20. package/dist/keystore/index.js.map +1 -0
  21. package/dist/keystore/keystore.d.ts +50 -0
  22. package/dist/keystore/keystore.js +193 -0
  23. package/dist/keystore/keystore.js.map +1 -0
  24. package/dist/keystore/keystore_validation_generated.d.ts +8 -0
  25. package/dist/keystore/keystore_validation_generated.js +75 -0
  26. package/dist/keystore/keystore_validation_generated.js.map +1 -0
  27. package/dist/keystore/schema_validator.d.ts +2 -0
  28. package/dist/keystore/schema_validator.js +18 -0
  29. package/dist/keystore/schema_validator.js.map +1 -0
  30. package/dist/keystore/types.d.ts +9 -0
  31. package/dist/keystore/types.js +2 -0
  32. package/dist/keystore/types.js.map +1 -0
  33. package/dist/rln.js +3 -11
  34. package/dist/rln.js.map +1 -1
  35. package/dist/rln_contract.d.ts +21 -11
  36. package/dist/rln_contract.js +58 -23
  37. package/dist/rln_contract.js.map +1 -1
  38. package/package.json +22 -7
  39. package/src/byte_utils.ts +10 -0
  40. package/src/constants.ts +63 -9
  41. package/src/index.ts +9 -2
  42. package/src/rln.ts +3 -12
  43. package/src/rln_contract.ts +113 -35
@@ -1,19 +1,27 @@
1
1
  import { ethers } from "ethers";
2
2
 
3
- import { RLN_ABI } from "./constants.js";
3
+ import { RLN_REGISTRY_ABI, RLN_STORAGE_ABI } from "./constants.js";
4
4
  import { IdentityCredential, RLNInstance } from "./rln.js";
5
5
  import { MerkleRootTracker } from "./root_tracker.js";
6
6
 
7
7
  type Member = {
8
- pubkey: string;
9
- index: number;
8
+ idCommitment: string;
9
+ index: ethers.BigNumber;
10
10
  };
11
11
 
12
- type ContractOptions = {
13
- address: string;
14
- provider: ethers.Signer | ethers.providers.Provider;
12
+ type Provider = ethers.Signer | ethers.providers.Provider;
13
+
14
+ type RLNContractOptions = {
15
+ provider: Provider;
16
+ registryAddress: string;
17
+ };
18
+
19
+ type RLNStorageOptions = {
20
+ storageIndex?: number;
15
21
  };
16
22
 
23
+ type RLNContractInitOptions = RLNContractOptions & RLNStorageOptions;
24
+
17
25
  type FetchMembersOptions = {
18
26
  fromBlock?: number;
19
27
  fetchRange?: number;
@@ -21,18 +29,23 @@ type FetchMembersOptions = {
21
29
  };
22
30
 
23
31
  export class RLNContract {
24
- private _contract: ethers.Contract;
25
- private membersFilter: ethers.EventFilter;
32
+ private registryContract: ethers.Contract;
26
33
  private merkleRootTracker: MerkleRootTracker;
27
34
 
28
- private _members: Member[] = [];
35
+ private deployBlock: undefined | number;
36
+ private storageIndex: undefined | number;
37
+ private storageContract: undefined | ethers.Contract;
38
+ private _membersFilter: undefined | ethers.EventFilter;
39
+
40
+ private _members: Map<number, Member> = new Map();
29
41
 
30
42
  public static async init(
31
43
  rlnInstance: RLNInstance,
32
- options: ContractOptions
44
+ options: RLNContractInitOptions
33
45
  ): Promise<RLNContract> {
34
46
  const rlnContract = new RLNContract(rlnInstance, options);
35
47
 
48
+ await rlnContract.initStorageContract(options.provider);
36
49
  await rlnContract.fetchMembers(rlnInstance);
37
50
  rlnContract.subscribeToMembers(rlnInstance);
38
51
 
@@ -41,21 +54,61 @@ export class RLNContract {
41
54
 
42
55
  constructor(
43
56
  rlnInstance: RLNInstance,
44
- { address, provider }: ContractOptions
57
+ { registryAddress, provider }: RLNContractOptions
45
58
  ) {
46
59
  const initialRoot = rlnInstance.getMerkleRoot();
47
60
 
48
- this._contract = new ethers.Contract(address, RLN_ABI, provider);
61
+ this.registryContract = new ethers.Contract(
62
+ registryAddress,
63
+ RLN_REGISTRY_ABI,
64
+ provider
65
+ );
49
66
  this.merkleRootTracker = new MerkleRootTracker(5, initialRoot);
50
- this.membersFilter = this.contract.filters.MemberRegistered();
67
+ }
68
+
69
+ private async initStorageContract(
70
+ provider: Provider,
71
+ options: RLNStorageOptions = {}
72
+ ): Promise<void> {
73
+ const storageIndex = options?.storageIndex
74
+ ? options.storageIndex
75
+ : await this.registryContract.usingStorageIndex();
76
+ const storageAddress = await this.registryContract.storages(storageIndex);
77
+
78
+ if (!storageAddress || storageAddress === ethers.constants.AddressZero) {
79
+ throw Error("No RLN Storage initialized on registry contract.");
80
+ }
81
+
82
+ this.storageIndex = storageIndex;
83
+ this.storageContract = new ethers.Contract(
84
+ storageAddress,
85
+ RLN_STORAGE_ABI,
86
+ provider
87
+ );
88
+ this._membersFilter = this.storageContract.filters.MemberRegistered();
89
+
90
+ this.deployBlock = await this.storageContract.deployedBlockNumber();
51
91
  }
52
92
 
53
93
  public get contract(): ethers.Contract {
54
- return this._contract;
94
+ if (!this.storageContract) {
95
+ throw Error("Storage contract was not initialized");
96
+ }
97
+ return this.storageContract as ethers.Contract;
55
98
  }
56
99
 
57
100
  public get members(): Member[] {
58
- return this._members;
101
+ const sortedMembers = Array.from(this._members.values()).sort(
102
+ (left, right) => left.index.toNumber() - right.index.toNumber()
103
+ );
104
+ return sortedMembers;
105
+ }
106
+
107
+ private get membersFilter(): ethers.EventFilter {
108
+ if (!this._membersFilter) {
109
+ throw Error("Members filter was not initialized.");
110
+ }
111
+ return this._membersFilter as ethers.EventFilter;
59
112
  }
60
113
 
61
114
  public async fetchMembers(
@@ -63,6 +116,7 @@ export class RLNContract {
63
116
  options: FetchMembersOptions = {}
64
117
  ): Promise<void> {
65
118
  const registeredMemberEvents = await queryFilter(this.contract, {
119
+ fromBlock: this.deployBlock,
66
120
  ...options,
67
121
  membersFilter: this.membersFilter,
68
122
  });
@@ -79,13 +133,13 @@ export class RLNContract {
79
133
  }
80
134
 
81
135
  if (evt.removed) {
82
- const index: number = evt.args.index;
136
+ const index: ethers.BigNumber = evt.args.index;
83
137
  const toRemoveVal = toRemoveTable.get(evt.blockNumber);
84
138
  if (toRemoveVal != undefined) {
85
- toRemoveVal.push(index);
139
+ toRemoveVal.push(index.toNumber());
86
140
  toRemoveTable.set(evt.blockNumber, toRemoveVal);
87
141
  } else {
88
- toRemoveTable.set(evt.blockNumber, [index]);
142
+ toRemoveTable.set(evt.blockNumber, [index.toNumber()]);
89
143
  }
90
144
  } else {
91
145
  let eventsPerBlock = toInsertTable.get(evt.blockNumber);
@@ -108,18 +162,23 @@ export class RLNContract {
108
162
  ): void {
109
163
  toInsert.forEach((events: ethers.Event[], blockNumber: number) => {
110
164
  events.forEach((evt) => {
111
- if (!evt.args) {
165
+ const _idCommitment = evt?.args?.idCommitment;
166
+ const index: ethers.BigNumber = evt?.args?.index;
167
+
168
+ if (!_idCommitment || !index) {
112
169
  return;
113
170
  }
114
171
 
115
- const pubkey = evt.args.pubkey;
116
- const index = evt.args.index;
117
172
  const idCommitment = ethers.utils.zeroPad(
118
- ethers.utils.arrayify(pubkey),
173
+ ethers.utils.arrayify(_idCommitment),
119
174
  32
120
175
  );
121
176
  rlnInstance.insertMember(idCommitment);
122
- this.members.push({ index, pubkey });
177
+ this._members.set(index.toNumber(), {
178
+ index,
179
+ idCommitment:
180
+ _idCommitment?._hex || ethers.utils.hexlify(idCommitment),
181
+ });
123
182
  });
124
183
 
125
184
  const currentRoot = rlnInstance.getMerkleRoot();
@@ -134,9 +193,8 @@ export class RLNContract {
134
193
  const removeDescending = new Map([...toRemove].sort().reverse());
135
194
  removeDescending.forEach((indexes: number[], blockNumber: number) => {
136
195
  indexes.forEach((index) => {
137
- const idx = this.members.findIndex((m) => m.index === index);
138
- if (idx > -1) {
139
- this.members.splice(idx, 1);
196
+ if (this._members.has(index)) {
197
+ this._members.delete(index);
140
198
  }
141
199
  rlnInstance.deleteMember(index);
142
200
  });
@@ -147,14 +205,14 @@ export class RLNContract {
147
205
 
148
206
  public subscribeToMembers(rlnInstance: RLNInstance): void {
149
207
  this.contract.on(this.membersFilter, (_pubkey, _index, event) =>
150
- this.processEvents(rlnInstance, event)
208
+ this.processEvents(rlnInstance, [event])
151
209
  );
152
210
  }
153
211
 
154
212
  public async registerWithSignature(
155
213
  rlnInstance: RLNInstance,
156
214
  signature: string
157
- ): Promise<ethers.Event | undefined> {
215
+ ): Promise<Member | undefined> {
158
216
  const identityCredential =
159
217
  await rlnInstance.generateSeededIdentityCredential(signature);
160
218
 
@@ -163,16 +221,36 @@ export class RLNContract {
163
221
 
164
222
  public async registerWithKey(
165
223
  credential: IdentityCredential
166
- ): Promise<ethers.Event | undefined> {
167
- const depositValue = await this.contract.MEMBERSHIP_DEPOSIT();
168
-
224
+ ): Promise<Member | undefined> {
225
+ if (this.storageIndex === undefined) {
226
+ throw Error(
227
+ "Cannot register credential, no storage contract index found."
228
+ );
229
+ }
169
230
  const txRegisterResponse: ethers.ContractTransaction =
170
- await this.contract.register(credential.IDCommitmentBigInt, {
171
- value: depositValue,
172
- });
231
+ await this.registryContract["register(uint16,uint256)"](
232
+ this.storageIndex,
233
+ credential.IDCommitmentBigInt,
234
+ { gasLimit: 100000 }
235
+ );
173
236
  const txRegisterReceipt = await txRegisterResponse.wait();
174
237
 
175
- return txRegisterReceipt?.events?.[0];
238
+ // assumption: register(uint16,uint256) emits one event
239
+ const memberRegistered = txRegisterReceipt?.events?.[0];
240
+
241
+ if (!memberRegistered) {
242
+ return undefined;
243
+ }
244
+
245
+ const decodedData = this.contract.interface.decodeEventLog(
246
+ "MemberRegistered",
247
+ memberRegistered.data
248
+ );
249
+
250
+ return {
251
+ idCommitment: decodedData.idCommitment,
252
+ index: decodedData.index,
253
+ };
176
254
  }
177
255
 
178
256
  public roots(): Uint8Array[] {