@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.
- package/bundle/index.js +22902 -334
- package/dist/.tsbuildinfo +1 -1
- package/dist/byte_utils.d.ts +6 -0
- package/dist/byte_utils.js +9 -0
- package/dist/byte_utils.js.map +1 -1
- package/dist/constants.d.ts +2 -2
- package/dist/constants.js +62 -9
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/keystore/cipher.d.ts +4 -0
- package/dist/keystore/cipher.js +28 -0
- package/dist/keystore/cipher.js.map +1 -0
- package/dist/keystore/credential_validation_generated.d.ts +8 -0
- package/dist/keystore/credential_validation_generated.js +121 -0
- package/dist/keystore/credential_validation_generated.js.map +1 -0
- package/dist/keystore/index.d.ts +2 -0
- package/dist/keystore/index.js +3 -0
- package/dist/keystore/index.js.map +1 -0
- package/dist/keystore/keystore.d.ts +50 -0
- package/dist/keystore/keystore.js +193 -0
- package/dist/keystore/keystore.js.map +1 -0
- package/dist/keystore/keystore_validation_generated.d.ts +8 -0
- package/dist/keystore/keystore_validation_generated.js +75 -0
- package/dist/keystore/keystore_validation_generated.js.map +1 -0
- package/dist/keystore/schema_validator.d.ts +2 -0
- package/dist/keystore/schema_validator.js +18 -0
- package/dist/keystore/schema_validator.js.map +1 -0
- package/dist/keystore/types.d.ts +9 -0
- package/dist/keystore/types.js +2 -0
- package/dist/keystore/types.js.map +1 -0
- package/dist/rln.js +3 -11
- package/dist/rln.js.map +1 -1
- package/dist/rln_contract.d.ts +21 -11
- package/dist/rln_contract.js +58 -23
- package/dist/rln_contract.js.map +1 -1
- package/package.json +22 -7
- package/src/byte_utils.ts +10 -0
- package/src/constants.ts +63 -9
- package/src/index.ts +9 -2
- package/src/rln.ts +3 -12
- package/src/rln_contract.ts +113 -35
package/src/rln_contract.ts
CHANGED
@@ -1,19 +1,27 @@
|
|
1
1
|
import { ethers } from "ethers";
|
2
2
|
|
3
|
-
import {
|
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
|
-
|
9
|
-
index:
|
8
|
+
idCommitment: string;
|
9
|
+
index: ethers.BigNumber;
|
10
10
|
};
|
11
11
|
|
12
|
-
type
|
13
|
-
|
14
|
-
|
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
|
25
|
-
private membersFilter: ethers.EventFilter;
|
32
|
+
private registryContract: ethers.Contract;
|
26
33
|
private merkleRootTracker: MerkleRootTracker;
|
27
34
|
|
28
|
-
private
|
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:
|
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
|
-
{
|
57
|
+
{ registryAddress, provider }: RLNContractOptions
|
45
58
|
) {
|
46
59
|
const initialRoot = rlnInstance.getMerkleRoot();
|
47
60
|
|
48
|
-
this.
|
61
|
+
this.registryContract = new ethers.Contract(
|
62
|
+
registryAddress,
|
63
|
+
RLN_REGISTRY_ABI,
|
64
|
+
provider
|
65
|
+
);
|
49
66
|
this.merkleRootTracker = new MerkleRootTracker(5, initialRoot);
|
50
|
-
|
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
|
-
|
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
|
-
|
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:
|
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
|
-
|
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(
|
173
|
+
ethers.utils.arrayify(_idCommitment),
|
119
174
|
32
|
120
175
|
);
|
121
176
|
rlnInstance.insertMember(idCommitment);
|
122
|
-
this.
|
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
|
-
|
138
|
-
|
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<
|
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<
|
167
|
-
|
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.
|
171
|
-
|
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
|
-
|
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[] {
|