@waku/rln 0.1.1-8928376 → 0.1.1-ac12f68

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