@waku/rln 0.0.2-09108d9.0 → 0.0.2-8a6571f.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/index.js +2 -1
- package/bundle/packages/rln/dist/contract/abi.js +648 -0
- package/bundle/packages/rln/dist/contract/constants.js +25 -65
- package/bundle/packages/rln/dist/contract/rln_contract.js +291 -71
- package/bundle/packages/rln/dist/message.js +1 -1
- package/bundle/packages/rln/dist/rln.js +42 -20
- package/bundle/packages/rln/dist/zerokit.js +34 -14
- package/dist/.tsbuildinfo +1 -1
- package/dist/contract/abi.d.ts +46 -0
- package/dist/contract/abi.js +647 -0
- package/dist/contract/abi.js.map +1 -0
- package/dist/contract/constants.d.ts +63 -3
- package/dist/contract/constants.js +23 -64
- package/dist/contract/constants.js.map +1 -1
- package/dist/contract/rln_contract.d.ts +98 -17
- package/dist/contract/rln_contract.js +290 -69
- package/dist/contract/rln_contract.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/message.js +1 -1
- package/dist/message.js.map +1 -1
- package/dist/rln.d.ts +5 -1
- package/dist/rln.js +42 -19
- package/dist/rln.js.map +1 -1
- package/dist/zerokit.d.ts +10 -6
- package/dist/zerokit.js +34 -14
- package/dist/zerokit.js.map +1 -1
- package/package.json +1 -1
- package/src/contract/abi.ts +646 -0
- package/src/contract/constants.ts +26 -65
- package/src/contract/rln_contract.ts +439 -105
- package/src/index.ts +4 -9
- package/src/message.ts +1 -1
- package/src/rln.ts +63 -21
- package/src/zerokit.ts +74 -15
package/src/index.ts
CHANGED
@@ -1,10 +1,6 @@
|
|
1
1
|
import { RLNDecoder, RLNEncoder } from "./codec.js";
|
2
|
-
import {
|
3
|
-
|
4
|
-
RLN_STORAGE_ABI,
|
5
|
-
SEPOLIA_CONTRACT
|
6
|
-
} from "./contract/index.js";
|
7
|
-
import { RLNContract } from "./contract/index.js";
|
2
|
+
import { RLN_ABI } from "./contract/abi.js";
|
3
|
+
import { RLNContract, SEPOLIA_CONTRACT } from "./contract/index.js";
|
8
4
|
import { createRLN } from "./create.js";
|
9
5
|
import { IdentityCredential } from "./identity.js";
|
10
6
|
import { Keystore } from "./keystore/index.js";
|
@@ -23,8 +19,7 @@ export {
|
|
23
19
|
RLNDecoder,
|
24
20
|
MerkleRootTracker,
|
25
21
|
RLNContract,
|
26
|
-
RLN_STORAGE_ABI,
|
27
|
-
RLN_REGISTRY_ABI,
|
28
22
|
SEPOLIA_CONTRACT,
|
29
|
-
extractMetaMaskSigner
|
23
|
+
extractMetaMaskSigner,
|
24
|
+
RLN_ABI
|
30
25
|
};
|
package/src/message.ts
CHANGED
@@ -27,7 +27,7 @@ export class RlnMessage<T extends IDecodedMessage> implements IDecodedMessage {
|
|
27
27
|
? this.rlnInstance.zerokit.verifyWithRoots(
|
28
28
|
this.rateLimitProof,
|
29
29
|
toRLNSignal(this.msg.contentTopic, this.msg),
|
30
|
-
|
30
|
+
roots
|
31
31
|
) // this.rlnInstance.verifyRLNProof once issue status-im/nwaku#1248 is fixed
|
32
32
|
: undefined;
|
33
33
|
}
|
package/src/rln.ts
CHANGED
@@ -15,6 +15,7 @@ import {
|
|
15
15
|
type RLNDecoder,
|
16
16
|
type RLNEncoder
|
17
17
|
} from "./codec.js";
|
18
|
+
import { DEFAULT_RATE_LIMIT } from "./contract/constants.js";
|
18
19
|
import { RLNContract, SEPOLIA_CONTRACT } from "./contract/index.js";
|
19
20
|
import { IdentityCredential } from "./identity.js";
|
20
21
|
import { Keystore } from "./keystore/index.js";
|
@@ -25,26 +26,53 @@ import type {
|
|
25
26
|
import { KeystoreEntity, Password } from "./keystore/types.js";
|
26
27
|
import verificationKey from "./resources/verification_key";
|
27
28
|
import * as wc from "./resources/witness_calculator";
|
29
|
+
import { WitnessCalculator } from "./resources/witness_calculator";
|
28
30
|
import { extractMetaMaskSigner } from "./utils/index.js";
|
29
31
|
import { Zerokit } from "./zerokit.js";
|
30
32
|
|
31
33
|
const log = new Logger("waku:rln");
|
32
34
|
|
33
|
-
async function loadWitnessCalculator(): Promise<
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
async function loadWitnessCalculator(): Promise<WitnessCalculator> {
|
36
|
+
try {
|
37
|
+
const url = new URL("./resources/rln.wasm", import.meta.url);
|
38
|
+
const response = await fetch(url);
|
39
|
+
|
40
|
+
if (!response.ok) {
|
41
|
+
throw new Error(
|
42
|
+
`Failed to fetch witness calculator: ${response.status} ${response.statusText}`
|
43
|
+
);
|
44
|
+
}
|
45
|
+
|
46
|
+
return await wc.builder(
|
47
|
+
new Uint8Array(await response.arrayBuffer()),
|
48
|
+
false
|
49
|
+
);
|
50
|
+
} catch (error) {
|
51
|
+
log.error("Error loading witness calculator:", error);
|
52
|
+
throw new Error(
|
53
|
+
`Failed to load witness calculator: ${error instanceof Error ? error.message : String(error)}`
|
54
|
+
);
|
37
55
|
}
|
38
|
-
const witnessBuffer = await res.arrayBuffer();
|
39
|
-
return wc.builder(new Uint8Array(witnessBuffer), false);
|
40
56
|
}
|
41
57
|
|
42
58
|
async function loadZkey(): Promise<Uint8Array> {
|
43
|
-
|
44
|
-
|
45
|
-
|
59
|
+
try {
|
60
|
+
const url = new URL("./resources/rln_final.zkey", import.meta.url);
|
61
|
+
const response = await fetch(url);
|
62
|
+
|
63
|
+
if (!response.ok) {
|
64
|
+
throw new Error(
|
65
|
+
`Failed to fetch zkey: ${response.status} ${response.statusText}`
|
66
|
+
);
|
67
|
+
}
|
68
|
+
|
69
|
+
return new Uint8Array(await response.arrayBuffer());
|
70
|
+
} catch (error) {
|
71
|
+
log.error("Error loading zkey:", error);
|
72
|
+
throw new Error(
|
73
|
+
`Failed to load zkey: ${error instanceof Error ? error.message : String(error)}`
|
74
|
+
);
|
46
75
|
}
|
47
|
-
return new Uint8Array(await res.arrayBuffer());
|
48
76
|
}
|
49
77
|
|
50
78
|
/**
|
@@ -65,7 +93,7 @@ export async function create(): Promise<RLNInstance> {
|
|
65
93
|
|
66
94
|
const DEPTH = 20;
|
67
95
|
const zkRLN = zerokitRLN.newRLN(DEPTH, zkey, vkey);
|
68
|
-
const zerokit = new Zerokit(zkRLN, witnessCalculator);
|
96
|
+
const zerokit = new Zerokit(zkRLN, witnessCalculator, DEFAULT_RATE_LIMIT);
|
69
97
|
|
70
98
|
return new RLNInstance(zerokit);
|
71
99
|
} catch (error) {
|
@@ -82,12 +110,16 @@ type StartRLNOptions = {
|
|
82
110
|
/**
|
83
111
|
* If not set - will use default SEPOLIA_CONTRACT address.
|
84
112
|
*/
|
85
|
-
|
113
|
+
address?: string;
|
86
114
|
/**
|
87
115
|
* Credentials to use for generating proofs and connecting to the contract and network.
|
88
116
|
* If provided used for validating the network chainId and connecting to registry contract.
|
89
117
|
*/
|
90
118
|
credentials?: EncryptedCredentials | DecryptedCredentials;
|
119
|
+
/**
|
120
|
+
* Rate limit for the member.
|
121
|
+
*/
|
122
|
+
rateLimit?: number;
|
91
123
|
};
|
92
124
|
|
93
125
|
type RegisterMembershipOptions =
|
@@ -119,6 +151,8 @@ export class RLNInstance {
|
|
119
151
|
}
|
120
152
|
|
121
153
|
public async start(options: StartRLNOptions = {}): Promise<void> {
|
154
|
+
// eslint-disable-next-line no-console
|
155
|
+
console.log("starting", options);
|
122
156
|
if (this.started || this.starting) {
|
123
157
|
return;
|
124
158
|
}
|
@@ -128,7 +162,7 @@ export class RLNInstance {
|
|
128
162
|
try {
|
129
163
|
const { credentials, keystore } =
|
130
164
|
await RLNInstance.decryptCredentialsIfNeeded(options.credentials);
|
131
|
-
const { signer,
|
165
|
+
const { signer, address } = await this.determineStartOptions(
|
132
166
|
options,
|
133
167
|
credentials
|
134
168
|
);
|
@@ -140,8 +174,9 @@ export class RLNInstance {
|
|
140
174
|
this._credentials = credentials;
|
141
175
|
this._signer = signer!;
|
142
176
|
this._contract = await RLNContract.init(this, {
|
143
|
-
|
144
|
-
signer: signer
|
177
|
+
address: address!,
|
178
|
+
signer: signer!,
|
179
|
+
rateLimit: options.rateLimit ?? this.zerokit.getRateLimit
|
145
180
|
});
|
146
181
|
this.started = true;
|
147
182
|
} finally {
|
@@ -154,15 +189,22 @@ export class RLNInstance {
|
|
154
189
|
credentials: KeystoreEntity | undefined
|
155
190
|
): Promise<StartRLNOptions> {
|
156
191
|
let chainId = credentials?.membership.chainId;
|
157
|
-
const
|
192
|
+
const address =
|
158
193
|
credentials?.membership.address ||
|
159
|
-
options.
|
194
|
+
options.address ||
|
160
195
|
SEPOLIA_CONTRACT.address;
|
161
196
|
|
162
|
-
if (
|
197
|
+
if (address === SEPOLIA_CONTRACT.address) {
|
163
198
|
chainId = SEPOLIA_CONTRACT.chainId;
|
164
199
|
}
|
165
200
|
|
201
|
+
// eslint-disable-next-line no-console
|
202
|
+
console.log({
|
203
|
+
chainId,
|
204
|
+
address,
|
205
|
+
SEPOLIA_CONTRACT
|
206
|
+
});
|
207
|
+
|
166
208
|
const signer = options.signer || (await extractMetaMaskSigner());
|
167
209
|
const currentChainId = await signer.getChainId();
|
168
210
|
|
@@ -174,7 +216,7 @@ export class RLNInstance {
|
|
174
216
|
|
175
217
|
return {
|
176
218
|
signer,
|
177
|
-
|
219
|
+
address
|
178
220
|
};
|
179
221
|
}
|
180
222
|
|
@@ -270,7 +312,7 @@ export class RLNInstance {
|
|
270
312
|
}
|
271
313
|
|
272
314
|
const registryAddress = credentials.membership.address;
|
273
|
-
const currentRegistryAddress = this._contract.
|
315
|
+
const currentRegistryAddress = this._contract.address;
|
274
316
|
if (registryAddress !== currentRegistryAddress) {
|
275
317
|
throw Error(
|
276
318
|
`Failed to verify chain coordinates: credentials contract address=${registryAddress} is not equal to registryContract address=${currentRegistryAddress}`
|
@@ -278,7 +320,7 @@ export class RLNInstance {
|
|
278
320
|
}
|
279
321
|
|
280
322
|
const chainId = credentials.membership.chainId;
|
281
|
-
const network = await this._contract.
|
323
|
+
const network = await this._contract.provider.getNetwork();
|
282
324
|
const currentChainId = network.chainId;
|
283
325
|
if (chainId !== currentChainId) {
|
284
326
|
throw Error(
|
package/src/zerokit.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import type { IRateLimitProof } from "@waku/interfaces";
|
2
2
|
import * as zerokitRLN from "@waku/zerokit-rln-wasm";
|
3
3
|
|
4
|
+
import { DEFAULT_RATE_LIMIT, RATE_LIMIT_PARAMS } from "./contract/constants.js";
|
4
5
|
import { IdentityCredential } from "./identity.js";
|
5
6
|
import { Proof, proofToBytes } from "./proof.js";
|
6
7
|
import { WitnessCalculator } from "./resources/witness_calculator";
|
@@ -14,9 +15,22 @@ import {
|
|
14
15
|
export class Zerokit {
|
15
16
|
public constructor(
|
16
17
|
private readonly zkRLN: number,
|
17
|
-
private readonly witnessCalculator: WitnessCalculator
|
18
|
+
private readonly witnessCalculator: WitnessCalculator,
|
19
|
+
private readonly rateLimit: number = DEFAULT_RATE_LIMIT
|
18
20
|
) {}
|
19
21
|
|
22
|
+
public get getZkRLN(): number {
|
23
|
+
return this.zkRLN;
|
24
|
+
}
|
25
|
+
|
26
|
+
public get getWitnessCalculator(): WitnessCalculator {
|
27
|
+
return this.witnessCalculator;
|
28
|
+
}
|
29
|
+
|
30
|
+
public get getRateLimit(): number {
|
31
|
+
return this.rateLimit;
|
32
|
+
}
|
33
|
+
|
20
34
|
public generateIdentityCredentials(): IdentityCredential {
|
21
35
|
const memKeys = zerokitRLN.generateExtendedMembershipKey(this.zkRLN); // TODO: rename this function in zerokit rln-wasm
|
22
36
|
return IdentityCredential.fromBytes(memKeys);
|
@@ -65,23 +79,36 @@ export class Zerokit {
|
|
65
79
|
uint8Msg: Uint8Array,
|
66
80
|
memIndex: number,
|
67
81
|
epoch: Uint8Array,
|
68
|
-
idKey: Uint8Array
|
82
|
+
idKey: Uint8Array,
|
83
|
+
rateLimit?: number
|
69
84
|
): Uint8Array {
|
70
85
|
// calculate message length
|
71
86
|
const msgLen = writeUIntLE(new Uint8Array(8), uint8Msg.length, 0, 8);
|
72
|
-
|
73
|
-
// Converting index to LE bytes
|
74
87
|
const memIndexBytes = writeUIntLE(new Uint8Array(8), memIndex, 0, 8);
|
88
|
+
const rateLimitBytes = writeUIntLE(
|
89
|
+
new Uint8Array(8),
|
90
|
+
rateLimit ?? this.rateLimit,
|
91
|
+
0,
|
92
|
+
8
|
93
|
+
);
|
75
94
|
|
76
|
-
// [ id_key<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> ]
|
77
|
-
return concatenate(
|
95
|
+
// [ id_key<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> | rate_limit<8> ]
|
96
|
+
return concatenate(
|
97
|
+
idKey,
|
98
|
+
memIndexBytes,
|
99
|
+
epoch,
|
100
|
+
msgLen,
|
101
|
+
uint8Msg,
|
102
|
+
rateLimitBytes
|
103
|
+
);
|
78
104
|
}
|
79
105
|
|
80
106
|
public async generateRLNProof(
|
81
107
|
msg: Uint8Array,
|
82
108
|
index: number,
|
83
109
|
epoch: Uint8Array | Date | undefined,
|
84
|
-
idSecretHash: Uint8Array
|
110
|
+
idSecretHash: Uint8Array,
|
111
|
+
rateLimit?: number
|
85
112
|
): Promise<IRateLimitProof> {
|
86
113
|
if (epoch === undefined) {
|
87
114
|
epoch = epochIntToBytes(dateToEpoch(new Date()));
|
@@ -89,15 +116,26 @@ export class Zerokit {
|
|
89
116
|
epoch = epochIntToBytes(dateToEpoch(epoch));
|
90
117
|
}
|
91
118
|
|
119
|
+
const effectiveRateLimit = rateLimit ?? this.rateLimit;
|
120
|
+
|
92
121
|
if (epoch.length !== 32) throw new Error("invalid epoch");
|
93
122
|
if (idSecretHash.length !== 32) throw new Error("invalid id secret hash");
|
94
123
|
if (index < 0) throw new Error("index must be >= 0");
|
124
|
+
if (
|
125
|
+
effectiveRateLimit < RATE_LIMIT_PARAMS.MIN_RATE ||
|
126
|
+
effectiveRateLimit > RATE_LIMIT_PARAMS.MAX_RATE
|
127
|
+
) {
|
128
|
+
throw new Error(
|
129
|
+
`Rate limit must be between ${RATE_LIMIT_PARAMS.MIN_RATE} and ${RATE_LIMIT_PARAMS.MAX_RATE}`
|
130
|
+
);
|
131
|
+
}
|
95
132
|
|
96
133
|
const serialized_msg = this.serializeMessage(
|
97
134
|
msg,
|
98
135
|
index,
|
99
136
|
epoch,
|
100
|
-
idSecretHash
|
137
|
+
idSecretHash,
|
138
|
+
effectiveRateLimit
|
101
139
|
);
|
102
140
|
const rlnWitness = zerokitRLN.getSerializedRLNWitness(
|
103
141
|
this.zkRLN,
|
@@ -107,7 +145,7 @@ export class Zerokit {
|
|
107
145
|
const calculatedWitness = await this.witnessCalculator.calculateWitness(
|
108
146
|
inputs,
|
109
147
|
false
|
110
|
-
);
|
148
|
+
);
|
111
149
|
|
112
150
|
const proofBytes = zerokitRLN.generate_rln_proof_with_witness(
|
113
151
|
this.zkRLN,
|
@@ -120,7 +158,8 @@ export class Zerokit {
|
|
120
158
|
|
121
159
|
public verifyRLNProof(
|
122
160
|
proof: IRateLimitProof | Uint8Array,
|
123
|
-
msg: Uint8Array
|
161
|
+
msg: Uint8Array,
|
162
|
+
rateLimit?: number
|
124
163
|
): boolean {
|
125
164
|
let pBytes: Uint8Array;
|
126
165
|
if (proof instanceof Uint8Array) {
|
@@ -131,17 +170,24 @@ export class Zerokit {
|
|
131
170
|
|
132
171
|
// calculate message length
|
133
172
|
const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
173
|
+
const rateLimitBytes = writeUIntLE(
|
174
|
+
new Uint8Array(8),
|
175
|
+
rateLimit ?? this.rateLimit,
|
176
|
+
0,
|
177
|
+
8
|
178
|
+
);
|
134
179
|
|
135
180
|
return zerokitRLN.verifyRLNProof(
|
136
181
|
this.zkRLN,
|
137
|
-
concatenate(pBytes, msgLen, msg)
|
182
|
+
concatenate(pBytes, msgLen, msg, rateLimitBytes)
|
138
183
|
);
|
139
184
|
}
|
140
185
|
|
141
186
|
public verifyWithRoots(
|
142
187
|
proof: IRateLimitProof | Uint8Array,
|
143
188
|
msg: Uint8Array,
|
144
|
-
|
189
|
+
roots: Array<Uint8Array>,
|
190
|
+
rateLimit?: number
|
145
191
|
): boolean {
|
146
192
|
let pBytes: Uint8Array;
|
147
193
|
if (proof instanceof Uint8Array) {
|
@@ -151,19 +197,26 @@ export class Zerokit {
|
|
151
197
|
}
|
152
198
|
// calculate message length
|
153
199
|
const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
200
|
+
const rateLimitBytes = writeUIntLE(
|
201
|
+
new Uint8Array(8),
|
202
|
+
rateLimit ?? this.rateLimit,
|
203
|
+
0,
|
204
|
+
8
|
205
|
+
);
|
154
206
|
|
155
207
|
const rootsBytes = concatenate(...roots);
|
156
208
|
|
157
209
|
return zerokitRLN.verifyWithRoots(
|
158
210
|
this.zkRLN,
|
159
|
-
concatenate(pBytes, msgLen, msg),
|
211
|
+
concatenate(pBytes, msgLen, msg, rateLimitBytes),
|
160
212
|
rootsBytes
|
161
213
|
);
|
162
214
|
}
|
163
215
|
|
164
216
|
public verifyWithNoRoot(
|
165
217
|
proof: IRateLimitProof | Uint8Array,
|
166
|
-
msg: Uint8Array
|
218
|
+
msg: Uint8Array,
|
219
|
+
rateLimit?: number
|
167
220
|
): boolean {
|
168
221
|
let pBytes: Uint8Array;
|
169
222
|
if (proof instanceof Uint8Array) {
|
@@ -174,10 +227,16 @@ export class Zerokit {
|
|
174
227
|
|
175
228
|
// calculate message length
|
176
229
|
const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
230
|
+
const rateLimitBytes = writeUIntLE(
|
231
|
+
new Uint8Array(8),
|
232
|
+
rateLimit ?? this.rateLimit,
|
233
|
+
0,
|
234
|
+
8
|
235
|
+
);
|
177
236
|
|
178
237
|
return zerokitRLN.verifyWithRoots(
|
179
238
|
this.zkRLN,
|
180
|
-
concatenate(pBytes, msgLen, msg),
|
239
|
+
concatenate(pBytes, msgLen, msg, rateLimitBytes),
|
181
240
|
new Uint8Array()
|
182
241
|
);
|
183
242
|
}
|