@waku/rln 0.1.0-e52107d → 0.1.1-5b9414a
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 +22885 -288
- 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 +3 -3
- package/dist/constants.js +64 -11
- 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 +49 -0
- package/dist/keystore/keystore.js +182 -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/message.d.ts +2 -1
- package/dist/message.js +5 -2
- package/dist/message.js.map +1 -1
- package/dist/rln.js +3 -11
- package/dist/rln.js.map +1 -1
- package/dist/rln_contract.d.ts +15 -5
- package/dist/rln_contract.js +96 -23
- package/dist/rln_contract.js.map +1 -1
- package/package.json +23 -8
- package/src/byte_utils.ts +10 -0
- package/src/constants.ts +65 -11
- package/src/index.ts +10 -3
- package/src/message.ts +7 -2
- package/src/rln.ts +3 -12
- package/src/rln_contract.ts +142 -34
package/src/rln_contract.ts
CHANGED
@@ -1,16 +1,19 @@
|
|
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
|
+
import { MerkleRootTracker } from "./root_tracker.js";
|
5
6
|
|
6
7
|
type Member = {
|
7
8
|
pubkey: string;
|
8
9
|
index: number;
|
9
10
|
};
|
10
11
|
|
12
|
+
type Provider = ethers.Signer | ethers.providers.Provider;
|
13
|
+
|
11
14
|
type ContractOptions = {
|
12
15
|
address: string;
|
13
|
-
provider:
|
16
|
+
provider: Provider;
|
14
17
|
};
|
15
18
|
|
16
19
|
type FetchMembersOptions = {
|
@@ -20,8 +23,13 @@ type FetchMembersOptions = {
|
|
20
23
|
};
|
21
24
|
|
22
25
|
export class RLNContract {
|
23
|
-
private
|
24
|
-
private
|
26
|
+
private registryContract: ethers.Contract;
|
27
|
+
private merkleRootTracker: MerkleRootTracker;
|
28
|
+
|
29
|
+
private deployBlock: undefined | number;
|
30
|
+
private storageIndex: undefined | number;
|
31
|
+
private storageContract: undefined | ethers.Contract;
|
32
|
+
private _membersFilter: undefined | ethers.EventFilter;
|
25
33
|
|
26
34
|
private _members: Member[] = [];
|
27
35
|
|
@@ -29,65 +37,154 @@ export class RLNContract {
|
|
29
37
|
rlnInstance: RLNInstance,
|
30
38
|
options: ContractOptions
|
31
39
|
): Promise<RLNContract> {
|
32
|
-
const rlnContract = new RLNContract(options);
|
40
|
+
const rlnContract = new RLNContract(rlnInstance, options);
|
33
41
|
|
42
|
+
await rlnContract.initStorageContract(options.provider);
|
34
43
|
await rlnContract.fetchMembers(rlnInstance);
|
35
44
|
rlnContract.subscribeToMembers(rlnInstance);
|
36
45
|
|
37
46
|
return rlnContract;
|
38
47
|
}
|
39
48
|
|
40
|
-
constructor(
|
41
|
-
|
42
|
-
|
49
|
+
constructor(
|
50
|
+
rlnInstance: RLNInstance,
|
51
|
+
{ address, provider }: ContractOptions
|
52
|
+
) {
|
53
|
+
const initialRoot = rlnInstance.getMerkleRoot();
|
54
|
+
|
55
|
+
this.registryContract = new ethers.Contract(
|
56
|
+
address,
|
57
|
+
RLN_REGISTRY_ABI,
|
58
|
+
provider
|
59
|
+
);
|
60
|
+
this.merkleRootTracker = new MerkleRootTracker(5, initialRoot);
|
61
|
+
}
|
62
|
+
|
63
|
+
private async initStorageContract(provider: Provider): Promise<void> {
|
64
|
+
const index = await this.registryContract.usingStorageIndex();
|
65
|
+
const address = await this.registryContract.storages(index);
|
66
|
+
|
67
|
+
this.storageIndex = index;
|
68
|
+
this.storageContract = new ethers.Contract(
|
69
|
+
address,
|
70
|
+
RLN_STORAGE_ABI,
|
71
|
+
provider
|
72
|
+
);
|
73
|
+
this._membersFilter = this.storageContract.filters.MemberRegistered();
|
74
|
+
|
75
|
+
this.deployBlock = await this.storageContract.deployedBlockNumber();
|
43
76
|
}
|
44
77
|
|
45
78
|
public get contract(): ethers.Contract {
|
46
|
-
|
79
|
+
if (!this.storageContract) {
|
80
|
+
throw Error("Storage contract was not initialized.");
|
81
|
+
}
|
82
|
+
return this.storageContract as ethers.Contract;
|
47
83
|
}
|
48
84
|
|
49
85
|
public get members(): Member[] {
|
50
86
|
return this._members;
|
51
87
|
}
|
52
88
|
|
89
|
+
private get membersFilter(): ethers.EventFilter {
|
90
|
+
if (!this._membersFilter) {
|
91
|
+
throw Error("Members filter was not initialized.");
|
92
|
+
}
|
93
|
+
return this._membersFilter as ethers.EventFilter;
|
94
|
+
}
|
95
|
+
|
53
96
|
public async fetchMembers(
|
54
97
|
rlnInstance: RLNInstance,
|
55
98
|
options: FetchMembersOptions = {}
|
56
99
|
): Promise<void> {
|
57
100
|
const registeredMemberEvents = await queryFilter(this.contract, {
|
101
|
+
fromBlock: this.deployBlock,
|
58
102
|
...options,
|
59
103
|
membersFilter: this.membersFilter,
|
60
104
|
});
|
61
|
-
|
62
|
-
for (const event of registeredMemberEvents) {
|
63
|
-
this.addMemberFromEvent(rlnInstance, event);
|
64
|
-
}
|
105
|
+
this.processEvents(rlnInstance, registeredMemberEvents);
|
65
106
|
}
|
66
107
|
|
67
|
-
public
|
68
|
-
|
69
|
-
|
70
|
-
|
108
|
+
public processEvents(rlnInstance: RLNInstance, events: ethers.Event[]): void {
|
109
|
+
const toRemoveTable = new Map<number, number[]>();
|
110
|
+
const toInsertTable = new Map<number, ethers.Event[]>();
|
111
|
+
|
112
|
+
events.forEach((evt) => {
|
113
|
+
if (!evt.args) {
|
114
|
+
return;
|
115
|
+
}
|
116
|
+
|
117
|
+
if (evt.removed) {
|
118
|
+
const index: number = evt.args.index;
|
119
|
+
const toRemoveVal = toRemoveTable.get(evt.blockNumber);
|
120
|
+
if (toRemoveVal != undefined) {
|
121
|
+
toRemoveVal.push(index);
|
122
|
+
toRemoveTable.set(evt.blockNumber, toRemoveVal);
|
123
|
+
} else {
|
124
|
+
toRemoveTable.set(evt.blockNumber, [index]);
|
125
|
+
}
|
126
|
+
} else {
|
127
|
+
let eventsPerBlock = toInsertTable.get(evt.blockNumber);
|
128
|
+
if (eventsPerBlock == undefined) {
|
129
|
+
eventsPerBlock = [];
|
130
|
+
}
|
131
|
+
|
132
|
+
eventsPerBlock.push(evt);
|
133
|
+
toInsertTable.set(evt.blockNumber, eventsPerBlock);
|
134
|
+
}
|
135
|
+
|
136
|
+
this.removeMembers(rlnInstance, toRemoveTable);
|
137
|
+
this.insertMembers(rlnInstance, toInsertTable);
|
138
|
+
});
|
71
139
|
}
|
72
140
|
|
73
|
-
private
|
141
|
+
private insertMembers(
|
74
142
|
rlnInstance: RLNInstance,
|
75
|
-
|
143
|
+
toInsert: Map<number, ethers.Event[]>
|
76
144
|
): void {
|
77
|
-
|
78
|
-
|
79
|
-
|
145
|
+
toInsert.forEach((events: ethers.Event[], blockNumber: number) => {
|
146
|
+
events.forEach((evt) => {
|
147
|
+
if (!evt.args) {
|
148
|
+
return;
|
149
|
+
}
|
150
|
+
|
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
|
+
);
|
157
|
+
rlnInstance.insertMember(idCommitment);
|
158
|
+
this.members.push({ index, pubkey });
|
159
|
+
});
|
80
160
|
|
81
|
-
|
82
|
-
|
161
|
+
const currentRoot = rlnInstance.getMerkleRoot();
|
162
|
+
this.merkleRootTracker.pushRoot(blockNumber, currentRoot);
|
163
|
+
});
|
164
|
+
}
|
165
|
+
|
166
|
+
private removeMembers(
|
167
|
+
rlnInstance: RLNInstance,
|
168
|
+
toRemove: Map<number, number[]>
|
169
|
+
): void {
|
170
|
+
const removeDescending = new Map([...toRemove].sort().reverse());
|
171
|
+
removeDescending.forEach((indexes: number[], blockNumber: number) => {
|
172
|
+
indexes.forEach((index) => {
|
173
|
+
const idx = this.members.findIndex((m) => m.index === index);
|
174
|
+
if (idx > -1) {
|
175
|
+
this.members.splice(idx, 1);
|
176
|
+
}
|
177
|
+
rlnInstance.deleteMember(index);
|
178
|
+
});
|
83
179
|
|
84
|
-
|
180
|
+
this.merkleRootTracker.backFill(blockNumber);
|
181
|
+
});
|
182
|
+
}
|
85
183
|
|
86
|
-
|
87
|
-
|
88
|
-
|
184
|
+
public subscribeToMembers(rlnInstance: RLNInstance): void {
|
185
|
+
this.contract.on(this.membersFilter, (_pubkey, _index, event) =>
|
186
|
+
this.processEvents(rlnInstance, event)
|
89
187
|
);
|
90
|
-
rlnInstance.insertMember(idCommitment);
|
91
188
|
}
|
92
189
|
|
93
190
|
public async registerWithSignature(
|
@@ -103,16 +200,27 @@ export class RLNContract {
|
|
103
200
|
public async registerWithKey(
|
104
201
|
credential: IdentityCredential
|
105
202
|
): Promise<ethers.Event | undefined> {
|
106
|
-
|
107
|
-
|
203
|
+
if (!this.storageIndex) {
|
204
|
+
throw Error(
|
205
|
+
"Cannot register credential, no storage contract index found."
|
206
|
+
);
|
207
|
+
}
|
108
208
|
const txRegisterResponse: ethers.ContractTransaction =
|
109
|
-
await this.
|
110
|
-
|
111
|
-
|
209
|
+
await this.registryContract.register(
|
210
|
+
this.storageIndex,
|
211
|
+
credential.IDCommitmentBigInt,
|
212
|
+
{
|
213
|
+
gasLimit: 100000,
|
214
|
+
}
|
215
|
+
);
|
112
216
|
const txRegisterReceipt = await txRegisterResponse.wait();
|
113
217
|
|
114
218
|
return txRegisterReceipt?.events?.[0];
|
115
219
|
}
|
220
|
+
|
221
|
+
public roots(): Uint8Array[] {
|
222
|
+
return this.merkleRootTracker.roots();
|
223
|
+
}
|
116
224
|
}
|
117
225
|
|
118
226
|
type CustomQueryOptions = FetchMembersOptions & {
|