@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
@@ -21,8 +21,8 @@ import { Logger } from '../../utils/dist/logger/index.js';
|
|
21
21
|
import '../../core/dist/lib/metadata/metadata.js';
|
22
22
|
import __wbg_init, { init_panic_hook, newRLN } from '../../../node_modules/@waku/zerokit-rln-wasm/rln_wasm.js';
|
23
23
|
import { createRLNEncoder, createRLNDecoder } from './codec.js';
|
24
|
+
import { DEFAULT_RATE_LIMIT, SEPOLIA_CONTRACT } from './contract/constants.js';
|
24
25
|
import { RLNContract } from './contract/rln_contract.js';
|
25
|
-
import { SEPOLIA_CONTRACT } from './contract/constants.js';
|
26
26
|
import { Keystore } from './keystore/keystore.js';
|
27
27
|
import verificationKey from './resources/verification_key.js';
|
28
28
|
import { builder } from './resources/witness_calculator.js';
|
@@ -32,19 +32,32 @@ import { Zerokit } from './zerokit.js';
|
|
32
32
|
|
33
33
|
const log = new Logger("waku:rln");
|
34
34
|
async function loadWitnessCalculator() {
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
try {
|
36
|
+
const url = new URL("./resources/rln.wasm", import.meta.url);
|
37
|
+
const response = await fetch(url);
|
38
|
+
if (!response.ok) {
|
39
|
+
throw new Error(`Failed to fetch witness calculator: ${response.status} ${response.statusText}`);
|
40
|
+
}
|
41
|
+
return await builder(new Uint8Array(await response.arrayBuffer()), false);
|
42
|
+
}
|
43
|
+
catch (error) {
|
44
|
+
log.error("Error loading witness calculator:", error);
|
45
|
+
throw new Error(`Failed to load witness calculator: ${error instanceof Error ? error.message : String(error)}`);
|
38
46
|
}
|
39
|
-
const witnessBuffer = await res.arrayBuffer();
|
40
|
-
return builder(new Uint8Array(witnessBuffer), false);
|
41
47
|
}
|
42
48
|
async function loadZkey() {
|
43
|
-
|
44
|
-
|
45
|
-
|
49
|
+
try {
|
50
|
+
const url = new URL("./resources/rln_final.zkey", import.meta.url);
|
51
|
+
const response = await fetch(url);
|
52
|
+
if (!response.ok) {
|
53
|
+
throw new Error(`Failed to fetch zkey: ${response.status} ${response.statusText}`);
|
54
|
+
}
|
55
|
+
return new Uint8Array(await response.arrayBuffer());
|
56
|
+
}
|
57
|
+
catch (error) {
|
58
|
+
log.error("Error loading zkey:", error);
|
59
|
+
throw new Error(`Failed to load zkey: ${error instanceof Error ? error.message : String(error)}`);
|
46
60
|
}
|
47
|
-
return new Uint8Array(await res.arrayBuffer());
|
48
61
|
}
|
49
62
|
/**
|
50
63
|
* Create an instance of RLN
|
@@ -61,7 +74,7 @@ async function create() {
|
|
61
74
|
const vkey = stringEncoder.encode(JSON.stringify(verificationKey));
|
62
75
|
const DEPTH = 20;
|
63
76
|
const zkRLN = newRLN(DEPTH, zkey, vkey);
|
64
|
-
const zerokit = new Zerokit(zkRLN, witnessCalculator);
|
77
|
+
const zerokit = new Zerokit(zkRLN, witnessCalculator, DEFAULT_RATE_LIMIT);
|
65
78
|
return new RLNInstance(zerokit);
|
66
79
|
}
|
67
80
|
catch (error) {
|
@@ -87,21 +100,24 @@ class RLNInstance {
|
|
87
100
|
return this._signer;
|
88
101
|
}
|
89
102
|
async start(options = {}) {
|
103
|
+
// eslint-disable-next-line no-console
|
104
|
+
console.log("starting", options);
|
90
105
|
if (this.started || this.starting) {
|
91
106
|
return;
|
92
107
|
}
|
93
108
|
this.starting = true;
|
94
109
|
try {
|
95
110
|
const { credentials, keystore } = await RLNInstance.decryptCredentialsIfNeeded(options.credentials);
|
96
|
-
const { signer,
|
111
|
+
const { signer, address } = await this.determineStartOptions(options, credentials);
|
97
112
|
if (keystore) {
|
98
113
|
this.keystore = keystore;
|
99
114
|
}
|
100
115
|
this._credentials = credentials;
|
101
116
|
this._signer = signer;
|
102
117
|
this._contract = await RLNContract.init(this, {
|
103
|
-
|
104
|
-
signer: signer
|
118
|
+
address: address,
|
119
|
+
signer: signer,
|
120
|
+
rateLimit: options.rateLimit ?? this.zerokit.getRateLimit
|
105
121
|
});
|
106
122
|
this.started = true;
|
107
123
|
}
|
@@ -111,12 +127,18 @@ class RLNInstance {
|
|
111
127
|
}
|
112
128
|
async determineStartOptions(options, credentials) {
|
113
129
|
let chainId = credentials?.membership.chainId;
|
114
|
-
const
|
115
|
-
options.
|
130
|
+
const address = credentials?.membership.address ||
|
131
|
+
options.address ||
|
116
132
|
SEPOLIA_CONTRACT.address;
|
117
|
-
if (
|
133
|
+
if (address === SEPOLIA_CONTRACT.address) {
|
118
134
|
chainId = SEPOLIA_CONTRACT.chainId;
|
119
135
|
}
|
136
|
+
// eslint-disable-next-line no-console
|
137
|
+
console.log({
|
138
|
+
chainId,
|
139
|
+
address,
|
140
|
+
SEPOLIA_CONTRACT
|
141
|
+
});
|
120
142
|
const signer = options.signer || (await extractMetaMaskSigner());
|
121
143
|
const currentChainId = await signer.getChainId();
|
122
144
|
if (chainId && chainId !== currentChainId) {
|
@@ -124,7 +146,7 @@ class RLNInstance {
|
|
124
146
|
}
|
125
147
|
return {
|
126
148
|
signer,
|
127
|
-
|
149
|
+
address
|
128
150
|
};
|
129
151
|
}
|
130
152
|
static async decryptCredentialsIfNeeded(credentials) {
|
@@ -184,12 +206,12 @@ class RLNInstance {
|
|
184
206
|
throw Error("Failed to verify chain coordinates: no contract initialized.");
|
185
207
|
}
|
186
208
|
const registryAddress = credentials.membership.address;
|
187
|
-
const currentRegistryAddress = this._contract.
|
209
|
+
const currentRegistryAddress = this._contract.address;
|
188
210
|
if (registryAddress !== currentRegistryAddress) {
|
189
211
|
throw Error(`Failed to verify chain coordinates: credentials contract address=${registryAddress} is not equal to registryContract address=${currentRegistryAddress}`);
|
190
212
|
}
|
191
213
|
const chainId = credentials.membership.chainId;
|
192
|
-
const network = await this._contract.
|
214
|
+
const network = await this._contract.provider.getNetwork();
|
193
215
|
const currentChainId = network.chainId;
|
194
216
|
if (chainId !== currentChainId) {
|
195
217
|
throw Error(`Failed to verify chain coordinates: credentials chainID=${chainId} is not equal to registryContract chainID=${currentChainId}`);
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { generateExtendedMembershipKey, generateSeededExtendedMembershipKey, insertMember, setLeavesFrom, deleteLeaf, getRoot, getSerializedRLNWitness, RLNWitnessToJson, generate_rln_proof_with_witness, verifyRLNProof, verifyWithRoots } from '../../../node_modules/@waku/zerokit-rln-wasm/rln_wasm.js';
|
2
|
+
import { DEFAULT_RATE_LIMIT, RATE_LIMIT_PARAMS } from './contract/constants.js';
|
2
3
|
import { IdentityCredential } from './identity.js';
|
3
4
|
import { Proof, proofToBytes } from './proof.js';
|
4
5
|
import { writeUIntLE, concatenate } from './utils/bytes.js';
|
@@ -7,9 +8,20 @@ import { epochIntToBytes, dateToEpoch } from './utils/epoch.js';
|
|
7
8
|
class Zerokit {
|
8
9
|
zkRLN;
|
9
10
|
witnessCalculator;
|
10
|
-
|
11
|
+
rateLimit;
|
12
|
+
constructor(zkRLN, witnessCalculator, rateLimit = DEFAULT_RATE_LIMIT) {
|
11
13
|
this.zkRLN = zkRLN;
|
12
14
|
this.witnessCalculator = witnessCalculator;
|
15
|
+
this.rateLimit = rateLimit;
|
16
|
+
}
|
17
|
+
get getZkRLN() {
|
18
|
+
return this.zkRLN;
|
19
|
+
}
|
20
|
+
get getWitnessCalculator() {
|
21
|
+
return this.witnessCalculator;
|
22
|
+
}
|
23
|
+
get getRateLimit() {
|
24
|
+
return this.rateLimit;
|
13
25
|
}
|
14
26
|
generateIdentityCredentials() {
|
15
27
|
const memKeys = generateExtendedMembershipKey(this.zkRLN); // TODO: rename this function in zerokit rln-wasm
|
@@ -38,35 +50,40 @@ class Zerokit {
|
|
38
50
|
getMerkleRoot() {
|
39
51
|
return getRoot(this.zkRLN);
|
40
52
|
}
|
41
|
-
serializeMessage(uint8Msg, memIndex, epoch, idKey) {
|
53
|
+
serializeMessage(uint8Msg, memIndex, epoch, idKey, rateLimit) {
|
42
54
|
// calculate message length
|
43
55
|
const msgLen = writeUIntLE(new Uint8Array(8), uint8Msg.length, 0, 8);
|
44
|
-
// Converting index to LE bytes
|
45
56
|
const memIndexBytes = writeUIntLE(new Uint8Array(8), memIndex, 0, 8);
|
46
|
-
|
47
|
-
|
57
|
+
const rateLimitBytes = writeUIntLE(new Uint8Array(8), rateLimit ?? this.rateLimit, 0, 8);
|
58
|
+
// [ id_key<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> | rate_limit<8> ]
|
59
|
+
return concatenate(idKey, memIndexBytes, epoch, msgLen, uint8Msg, rateLimitBytes);
|
48
60
|
}
|
49
|
-
async generateRLNProof(msg, index, epoch, idSecretHash) {
|
61
|
+
async generateRLNProof(msg, index, epoch, idSecretHash, rateLimit) {
|
50
62
|
if (epoch === undefined) {
|
51
63
|
epoch = epochIntToBytes(dateToEpoch(new Date()));
|
52
64
|
}
|
53
65
|
else if (epoch instanceof Date) {
|
54
66
|
epoch = epochIntToBytes(dateToEpoch(epoch));
|
55
67
|
}
|
68
|
+
const effectiveRateLimit = rateLimit ?? this.rateLimit;
|
56
69
|
if (epoch.length !== 32)
|
57
70
|
throw new Error("invalid epoch");
|
58
71
|
if (idSecretHash.length !== 32)
|
59
72
|
throw new Error("invalid id secret hash");
|
60
73
|
if (index < 0)
|
61
74
|
throw new Error("index must be >= 0");
|
62
|
-
|
75
|
+
if (effectiveRateLimit < RATE_LIMIT_PARAMS.MIN_RATE ||
|
76
|
+
effectiveRateLimit > RATE_LIMIT_PARAMS.MAX_RATE) {
|
77
|
+
throw new Error(`Rate limit must be between ${RATE_LIMIT_PARAMS.MIN_RATE} and ${RATE_LIMIT_PARAMS.MAX_RATE}`);
|
78
|
+
}
|
79
|
+
const serialized_msg = this.serializeMessage(msg, index, epoch, idSecretHash, effectiveRateLimit);
|
63
80
|
const rlnWitness = getSerializedRLNWitness(this.zkRLN, serialized_msg);
|
64
81
|
const inputs = RLNWitnessToJson(this.zkRLN, rlnWitness);
|
65
|
-
const calculatedWitness = await this.witnessCalculator.calculateWitness(inputs, false);
|
82
|
+
const calculatedWitness = await this.witnessCalculator.calculateWitness(inputs, false);
|
66
83
|
const proofBytes = generate_rln_proof_with_witness(this.zkRLN, calculatedWitness, rlnWitness);
|
67
84
|
return new Proof(proofBytes);
|
68
85
|
}
|
69
|
-
verifyRLNProof(proof, msg) {
|
86
|
+
verifyRLNProof(proof, msg, rateLimit) {
|
70
87
|
let pBytes;
|
71
88
|
if (proof instanceof Uint8Array) {
|
72
89
|
pBytes = proof;
|
@@ -76,9 +93,10 @@ class Zerokit {
|
|
76
93
|
}
|
77
94
|
// calculate message length
|
78
95
|
const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
79
|
-
|
96
|
+
const rateLimitBytes = writeUIntLE(new Uint8Array(8), rateLimit ?? this.rateLimit, 0, 8);
|
97
|
+
return verifyRLNProof(this.zkRLN, concatenate(pBytes, msgLen, msg, rateLimitBytes));
|
80
98
|
}
|
81
|
-
verifyWithRoots(proof, msg,
|
99
|
+
verifyWithRoots(proof, msg, roots, rateLimit) {
|
82
100
|
let pBytes;
|
83
101
|
if (proof instanceof Uint8Array) {
|
84
102
|
pBytes = proof;
|
@@ -88,10 +106,11 @@ class Zerokit {
|
|
88
106
|
}
|
89
107
|
// calculate message length
|
90
108
|
const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
109
|
+
const rateLimitBytes = writeUIntLE(new Uint8Array(8), rateLimit ?? this.rateLimit, 0, 8);
|
91
110
|
const rootsBytes = concatenate(...roots);
|
92
|
-
return verifyWithRoots(this.zkRLN, concatenate(pBytes, msgLen, msg), rootsBytes);
|
111
|
+
return verifyWithRoots(this.zkRLN, concatenate(pBytes, msgLen, msg, rateLimitBytes), rootsBytes);
|
93
112
|
}
|
94
|
-
verifyWithNoRoot(proof, msg) {
|
113
|
+
verifyWithNoRoot(proof, msg, rateLimit) {
|
95
114
|
let pBytes;
|
96
115
|
if (proof instanceof Uint8Array) {
|
97
116
|
pBytes = proof;
|
@@ -101,7 +120,8 @@ class Zerokit {
|
|
101
120
|
}
|
102
121
|
// calculate message length
|
103
122
|
const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
104
|
-
|
123
|
+
const rateLimitBytes = writeUIntLE(new Uint8Array(8), rateLimit ?? this.rateLimit, 0, 8);
|
124
|
+
return verifyWithRoots(this.zkRLN, concatenate(pBytes, msgLen, msg, rateLimitBytes), new Uint8Array());
|
105
125
|
}
|
106
126
|
}
|
107
127
|
|